compile scope expressions

This commit is contained in:
tali 2023-11-30 13:52:05 -05:00
parent c089d893c6
commit fd3b356699
2 changed files with 29 additions and 18 deletions

View File

@ -5,7 +5,7 @@ let () =
Logs.set_level (Some Logs.Debug); Logs.set_level (Some Logs.Debug);
try 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 prog = compile ast in
let ret = run prog in let ret = run prog in
Fmt.pr "{\"program\":%a,\"output\":%a}" Code.pp_program prog Value.pp ret Fmt.pr "{\"program\":%a,\"output\":%a}" Code.pp_program prog Value.pp ret

View File

@ -72,8 +72,9 @@ let compile modl =
bb := jp; bb := jp;
Reg tmp Reg tmp
| Ast.Obj body -> compile_obj env body | Ast.Obj body -> compile_obj env body
| Ast.Scope body -> compile_scope env body
| _ -> failwith "Bcc.compile_exp: TODO" | _ -> failwith "Bcc.compile_exp: TODO"
and compile_obj env items = and compile_block env items =
let self = !sp in let self = !sp in
(* construct new env and vtable *) (* construct new env and vtable *)
@ -92,7 +93,7 @@ let compile modl =
in in
let vtable = Value.{ elems; n_slots } 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)); emit (CON (self, vtable));
let emit_set name rhs = let emit_set name rhs =
let slot = (Env.find name env).slot in 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_mov (self + 1) (Code.cst_of_int slot);
emit (SET (self, self + 1)) emit (SET (self, self + 1))
in in
List.iter let final_exp =
(function List.fold_left
(fun _ -> function
| Ast.Item_fun (_, _, _) -> failwith "Bcc: unsupported: methods" | Ast.Item_fun (_, _, _) -> failwith "Bcc: unsupported: methods"
| Ast.Item_exp e -> | Ast.Item_exp e ->
sp := self + 1; sp := self + 1;
ignore (compile_exp env e) Some (compile_exp env e)
| Ast.Item_obj (name, body) -> | Ast.Item_obj (name, body) ->
sp := self + 2; sp := self + 2;
emit_set name (compile_obj env body) emit_set name (compile_obj env body);
None
| Ast.Item_val (name, rhs) -> | Ast.Item_val (name, rhs) ->
sp := self + 2; sp := self + 2;
emit_set name (compile_exp env rhs)) emit_set name (compile_exp env rhs);
items; None)
None
(* reset sp and return self *) items
in
self, final_exp
and compile_obj env items =
let self, _ = compile_block env items in
sp := self + 1; sp := self + 1;
Code.Reg self 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 in
let env = Env.empty in let env = Env.empty in