diff --git a/lib/compiler/emit.ml b/lib/compiler/emit.ml index e417dbc..07102f7 100644 --- a/lib/compiler/emit.ml +++ b/lib/compiler/emit.ml @@ -108,6 +108,13 @@ let backpatch p = if Queue.is_empty p.backpatch then Ok () else backpatch_one p (Queue.pop p.backpatch) + +let smooth_one = function + | Instr i -> i + | _ -> failwith "backpatching process was not complete!" +let smooth_instrs p = + Dynarray.to_array (Dynarray.map smooth_one p.instrs) + let compile (exprs : expression list) (tbl : int SymbolTable.t) = let program = { instrs=Dynarray.create (); @@ -116,4 +123,6 @@ let compile (exprs : expression list) (tbl : int SymbolTable.t) = backpatch=Queue.create (); } in let* _ = compile_all program exprs in - backpatch program + let* _ = backpatch program in + let final_instrs = smooth_instrs program in + Ok (Vm.Types.make_vm final_instrs (Dynarray.to_array program.constants) (SymbolTable.cardinal tbl)) diff --git a/lib/vm/types.ml b/lib/vm/types.ml index 4ec6db1..3c30e87 100644 --- a/lib/vm/types.ml +++ b/lib/vm/types.ml @@ -36,4 +36,15 @@ type vm_state = { mutable stack : value list } + +let make_vm instrs constants global_count = + { + i = 0; + instrs = instrs; + globals = Array.make global_count Nil; + constants = constants; + env = []; + stack = []; + } + (* TODO: add facilities to print the VM state in case of errors. *)