Skip to content

Commit 7595b97

Browse files
committed
compiler: forbit let rec bindings within function body
Close #13
1 parent 2345e78 commit 7595b97

File tree

5 files changed

+48
-34
lines changed

5 files changed

+48
-34
lines changed

src/compiler/ocaml_to_erlang/error.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ let ppf = Format.err_formatter
1111
let file_a_bug =
1212
{| If you think this is a bug, please file an issue here: https://github.com/AbstractMachinesLab/caramel/issues/new |}
1313

14+
let unsupported_let_rec_inside_of_function_body () =
15+
Format.fprintf ppf
16+
{|We have found a let rec binding within a function.
17+
18+
This is currently not supported.
19+
\n
20+
|};
21+
exit 1
22+
1423
let unsupported_let_shadowing name =
1524
Format.fprintf ppf
1625
{|We have found that the variable name %s is being shadowed.

src/compiler/ocaml_to_erlang/fun.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,9 @@ and mk_expression exp ~var_names ~modules ~functions ~module_name =
327327
in
328328
let branches = if_true :: if_false in
329329
Erlang.Ast.Expr_case (expr, branches)
330-
| Texp_let (_, vbs, expr) ->
330+
| Texp_let (Recursive, _, _) ->
331+
Error.unsupported_let_rec_inside_of_function_body ()
332+
| Texp_let (Nonrecursive, vbs, expr) ->
331333
(* NOTE: consider flattening let-ins ?
332334
let rec flatten e acc =
333335
match e with

tests/compiler/expressions.t/let_bindings.ml

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,3 @@ let let_nested f g h =
2626
in
2727
f a
2828

29-
(* FIXME: Erlang does not support let rec bindings, and we're forced to use a
30-
combinator instead.
31-
32-
Right now it believes that the name is supposed to be a module level
33-
function, which compiles fine but crashes at runtime.
34-
35-
So this:
36-
let rec f x = f (x + 1) in
37-
f 0
38-
39-
could look like:
40-
41-
let_rec() ->
42-
RecF = fun(G) -> fun (X) -> (G(G))(X+1) end end,
43-
F = RecF(RecF),
44-
F(0).
45-
46-
alternatively we coudl wrap this in a support library too
47-
48-
F = caramel:letrec1(fun (F, X) -> F(X + 1) end)
49-
50-
*)
51-
let let_rec () =
52-
let rec f x = f (x + 1) in
53-
f 0
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(* FIXME: Erlang does not support let rec bindings, and we're forced to use a
2+
combinator instead.
3+
4+
Right now it believes that the name is supposed to be a module level
5+
function, which compiles fine but crashes at runtime.
6+
7+
So this:
8+
let rec f x = f (x + 1) in
9+
f 0
10+
11+
could look like:
12+
13+
let_rec() ->
14+
RecF = fun(G) -> fun (X) -> (G(G))(X+1) end end,
15+
F = RecF(RecF),
16+
F(0).
17+
18+
alternatively we coudl wrap this in a support library too
19+
20+
F = caramel:letrec1(fun (F, X) -> F(X + 1) end)
21+
22+
*)
23+
let let_rec () =
24+
let rec f x = f (x + 1) in
25+
f 0

tests/compiler/expressions.t/run.t

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
binding_on_match.ml
44
funref.ml
55
let_bindings.ml
6+
let_rec.ml
67
let_shadowing.ml
78
list.ml
89
literals.ml
@@ -175,7 +176,6 @@
175176
-export([let_many/0]).
176177
-export([let_nested/3]).
177178
-export([let_one/0]).
178-
-export([let_rec/0]).
179179

180180
-spec let_one() -> integer().
181181
let_one() ->
@@ -210,13 +210,6 @@
210210
end(),
211211
F(A).
212212

213-
-spec let_rec() -> any().
214-
let_rec() ->
215-
F = fun
216-
(X) -> f(erlang:'+'(X, 1))
217-
end,
218-
F(0).
219-
220213

221214
$ caramelc compile list.ml
222215
File "list.ml", line 7, characters 9-21:
@@ -568,6 +561,7 @@
568561
$ cat let_shadowing.erl
569562
cat: let_shadowing.erl: No such file or directory
570563
[1]
564+
571565
$ caramelc compile names_primes.ml
572566
Compiling names_primes.erl OK
573567
$ cat names_primes.erl
@@ -584,3 +578,12 @@
584578
X_prime_prime.
585579

586580

581+
$ caramelc compile let_rec.ml
582+
We have found a let rec binding within a function.
583+
584+
This is currently not supported.
585+
\n
586+
[1]
587+
$ cat let_rec.erl
588+
cat: let_rec.erl: No such file or directory
589+
[1]

0 commit comments

Comments
 (0)