compile scope expressions
This commit is contained in:
parent
c089d893c6
commit
fd3b356699
|
@ -5,7 +5,7 @@ let () =
|
|||
Logs.set_level (Some Logs.Debug);
|
||||
|
||||
try
|
||||
let ast = parse "val x = 3 val y = 5 val output = 2 * (if(9 < 8) x else 1 + y)" in
|
||||
let ast = parse "val z = 5 val output = 1 + (({ val x = 3 val y = 4 x * y }) + z)" in
|
||||
let prog = compile ast in
|
||||
let ret = run prog in
|
||||
Fmt.pr "{\"program\":%a,\"output\":%a}" Code.pp_program prog Value.pp ret
|
||||
|
|
|
@ -72,8 +72,9 @@ let compile modl =
|
|||
bb := jp;
|
||||
Reg tmp
|
||||
| Ast.Obj body -> compile_obj env body
|
||||
| Ast.Scope body -> compile_scope env body
|
||||
| _ -> failwith "Bcc.compile_exp: TODO"
|
||||
and compile_obj env items =
|
||||
and compile_block env items =
|
||||
let self = !sp in
|
||||
|
||||
(* construct new env and vtable *)
|
||||
|
@ -92,7 +93,7 @@ let compile modl =
|
|||
in
|
||||
let vtable = Value.{ elems; n_slots } in
|
||||
|
||||
(* emit constructor / field inits *)
|
||||
(* emit constructor, compile val fields, and get result of final expression *)
|
||||
emit (CON (self, vtable));
|
||||
let emit_set name rhs =
|
||||
let slot = (Env.find name env).slot in
|
||||
|
@ -100,23 +101,33 @@ let compile modl =
|
|||
emit_mov (self + 1) (Code.cst_of_int slot);
|
||||
emit (SET (self, self + 1))
|
||||
in
|
||||
List.iter
|
||||
(function
|
||||
| Ast.Item_fun (_, _, _) -> failwith "Bcc: unsupported: methods"
|
||||
| Ast.Item_exp e ->
|
||||
sp := self + 1;
|
||||
ignore (compile_exp env e)
|
||||
| Ast.Item_obj (name, body) ->
|
||||
sp := self + 2;
|
||||
emit_set name (compile_obj env body)
|
||||
| Ast.Item_val (name, rhs) ->
|
||||
sp := self + 2;
|
||||
emit_set name (compile_exp env rhs))
|
||||
items;
|
||||
|
||||
(* reset sp and return self *)
|
||||
let final_exp =
|
||||
List.fold_left
|
||||
(fun _ -> function
|
||||
| Ast.Item_fun (_, _, _) -> failwith "Bcc: unsupported: methods"
|
||||
| Ast.Item_exp e ->
|
||||
sp := self + 1;
|
||||
Some (compile_exp env e)
|
||||
| Ast.Item_obj (name, body) ->
|
||||
sp := self + 2;
|
||||
emit_set name (compile_obj env body);
|
||||
None
|
||||
| Ast.Item_val (name, rhs) ->
|
||||
sp := self + 2;
|
||||
emit_set name (compile_exp env rhs);
|
||||
None)
|
||||
None
|
||||
items
|
||||
in
|
||||
self, final_exp
|
||||
and compile_obj env items =
|
||||
let self, _ = compile_block env items in
|
||||
sp := self + 1;
|
||||
Code.Reg self
|
||||
and compile_scope env items =
|
||||
match compile_block env items with
|
||||
| _, None -> failwith "block must end with an expression"
|
||||
| _, Some ret -> ret
|
||||
in
|
||||
|
||||
let env = Env.empty in
|
||||
|
|
Loading…
Reference in New Issue