Skip to content

Commit c2a0c5b

Browse files
authored
fix(compiler): Correctly handle and backpatch mutually recursive closure scope functions (#1808)
1 parent 114d17b commit c2a0c5b

File tree

2 files changed

+61
-13
lines changed

2 files changed

+61
-13
lines changed

compiler/src/codegen/transl_anf.re

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -618,19 +618,37 @@ and compile_anf_expr = (env, a) =>
618618
};
619619
let (new_env, locations) = get_locs(env, binds);
620620
let instrs =
621-
List.fold_right2(
622-
(loc, (id, rhs), acc) =>
623-
[
624-
{
625-
instr_desc: MStore([(loc, compile_comp(~id, env, rhs))]),
626-
instr_loc: rhs.comp_loc,
627-
},
628-
...acc,
629-
],
630-
locations,
631-
binds,
632-
[],
633-
);
621+
switch (recflag) {
622+
| Nonrecursive =>
623+
List.fold_right2(
624+
(loc, (id, rhs), acc) =>
625+
[
626+
{
627+
instr_desc: MStore([(loc, compile_comp(~id, env, rhs))]),
628+
instr_loc: rhs.comp_loc,
629+
},
630+
...acc,
631+
],
632+
locations,
633+
binds,
634+
[],
635+
)
636+
| Recursive => [
637+
{
638+
instr_desc:
639+
MStore(
640+
List.fold_right2(
641+
(loc, (id, rhs), acc) =>
642+
[(loc, compile_comp(~id, new_env, rhs)), ...acc],
643+
locations,
644+
binds,
645+
[],
646+
),
647+
),
648+
instr_loc: a.anf_loc,
649+
},
650+
]
651+
};
634652
instrs @ compile_anf_expr(new_env, body);
635653
| AEComp(c) => [compile_comp(env, c)]
636654
};

compiler/test/suites/functions.re

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,36 @@ provide let truc = () => {
182182
}
183183
truc()|},
184184
);
185+
186+
assertRun(
187+
"func_mutually_recursive_closure",
188+
{|
189+
let main = () => {
190+
let closureScope = "closureScope"
191+
let rec isEven = n => {
192+
print(closureScope)
193+
if (n <= 1) {
194+
n == 0
195+
} else {
196+
isOdd(n - 1)
197+
}
198+
},
199+
isOdd = n => {
200+
if (n <= 1) {
201+
n == 1
202+
} else {
203+
isEven(n - 1)
204+
}
205+
}
206+
207+
print(isOdd(3))
208+
}
209+
210+
main()
211+
|},
212+
"closureScope\ntrue\n",
213+
);
214+
185215
assertCompileError(
186216
"newline_before_arrow",
187217
{|

0 commit comments

Comments
 (0)