rhysd / gocaml

:camel: Statically typed functional programming language implementation with Go and LLVM

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mutual recursion does not work

rhysd opened this issue · comments

Repro:

let rec odd x = if x = 1 then true else even (x-1) in
let rec even x = if x = 0 then true else odd (x-1) in
print_bool (odd 131)

GCIL:

odd$t1 = fun x$t2 ; type=int -> bool
  BEGIN: body (odd$t1)
  $k2 = int 1 ; type=int
  $k3 = binary = x$t2 $k2 ; type=bool
  $k10 = if $k3 ; type=bool
    BEGIN: then
    $k4 = bool true ; type=bool
    END: then
    BEGIN: else
    $k7 = int 1 ; type=int
    $k8 = binary - x$t2 $k7 ; type=int
    $k9 = appx even $k8 ; type=bool
    END: else
  END: body (odd$t1)

even$t3 = fun x$t4 ; type=int -> bool
  BEGIN: body (even$t3)
  $k12 = int 0 ; type=int
  $k13 = binary = x$t4 $k12 ; type=bool
  $k20 = if $k13 ; type=bool
    BEGIN: then
    $k14 = bool true ; type=bool
    END: then
    BEGIN: else
    $k17 = int 1 ; type=int
    $k18 = binary - x$t4 $k17 ; type=int
    $k19 = app odd$t1 $k18 ; type=bool
    END: else
  END: body (even$t3)

BEGIN: program
$k23 = int 131 ; type=int
$k24 = app odd$t1 $k23 ; type=bool
$k25 = appx print_bool $k24 ; type=()
END: program

In odd, even is not defined yet so cannot be resolved. It results in falling back into external symbol and causes linker error.

let rec odd x =
    let rec even x = if x = 0 then true else odd (x-1) in
    if x = 1 then true else even (x-1) in
print_bool (odd 131);
print_bool (odd 130)

This works.