compile scope expressions
This commit is contained in:
parent
c089d893c6
commit
fd3b356699
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue