Skip to content

Commit 9c72b70

Browse files
committed
letrec
1 parent cf59e6d commit 9c72b70

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

lib_src/gcc_compiler.ml

+16
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ let rec compile_expr expr state =
8383
| Cdr expr ->
8484
let (tuple_expr, f) = compile_expr expr state in
8585
(tuple_expr @ [CDR]), f
86+
| Letrec (bindings, body) ->
87+
let n = List.length bindings in
88+
let names = List.map ~f:fst bindings in
89+
let rec_env = push_vars state.env names in
90+
let rec_state = {functions = state.functions; env = rec_env} in
91+
let (vals_code, s1) = List.fold_left bindings
92+
~init: ([], rec_state)
93+
~f:(fun (code, state) (_name, e) ->
94+
let (c, s1) = compile_expr e state in
95+
(code @ c, s1))
96+
in
97+
let id = Address.create () in
98+
let s2 = compile_func id names body s1 in
99+
DUM n :: vals_code @ [LDF id] @ [RAP n], s2
86100

87101
and compile_func id formals expr {functions; env} =
88102
let e_env = push_vars env formals in
@@ -131,6 +145,8 @@ let assemble instructions =
131145
| SEL (addr1, addr2) -> sprintf "SEL %d %d" (resolve addr1) (resolve addr2)
132146
| LDF addr -> sprintf "LDF %d" (resolve addr)
133147
| AP n -> sprintf "AP %d" n
148+
| DUM n -> sprintf "DUM %d" n
149+
| RAP n -> sprintf "RAP %d" n
134150
| _ ->
135151
let sexp = Sexp.to_string (sexp_of_instruction instruction) in
136152
failwithf "unsupported instruction %s" sexp ()

lib_src/gcc_types.ml

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type expr =
4747
| Cons of expr * expr
4848
| Fn of var list * expr
4949
| Call of expr * expr list
50+
| Letrec of (var * expr) list * expr
5051
| If of expr * expr * expr
5152
| Eq of expr * expr
5253
| Gt of expr * expr

0 commit comments

Comments
 (0)