add back CALl instruction
This commit is contained in:
parent
c51b482607
commit
44406a233e
|
@ -23,6 +23,7 @@ type ins =
|
||||||
| SET of reg * reg * reg
|
| SET of reg * reg * reg
|
||||||
| LOC of reg * reg * string
|
| LOC of reg * reg * string
|
||||||
| CON of reg * vtable
|
| CON of reg * vtable
|
||||||
|
| CAL of reg * reg * reg * reg list
|
||||||
(* control flow *)
|
(* control flow *)
|
||||||
| RET
|
| RET
|
||||||
| JMP of block
|
| JMP of block
|
||||||
|
@ -44,13 +45,8 @@ let instructions t =
|
||||||
type prog =
|
type prog =
|
||||||
{ entry : block }
|
{ entry : block }
|
||||||
|
|
||||||
(* like [Seq.flat_map] but may change the ordering *)
|
type Value.mthd +=
|
||||||
let flat_map_u f lst =
|
| Method of { n_args : int; body : prog }
|
||||||
let rec go acc = function
|
|
||||||
| [] -> []
|
|
||||||
| x :: xs -> go (List.rev_append (f x) acc) xs
|
|
||||||
in
|
|
||||||
go [] lst
|
|
||||||
|
|
||||||
let frame_size t =
|
let frame_size t =
|
||||||
let queue = ref [ t.entry ] in
|
let queue = ref [ t.entry ] in
|
||||||
|
@ -79,6 +75,8 @@ let frame_size t =
|
||||||
| GET (r1, r2, r3)
|
| GET (r1, r2, r3)
|
||||||
| SET (r1, r2, r3)
|
| SET (r1, r2, r3)
|
||||||
-> meas r1 (meas r2 (meas r3 fs))
|
-> meas r1 (meas r2 (meas r3 fs))
|
||||||
|
| CAL (r1, r2, r3, rs) ->
|
||||||
|
List.fold_right meas (r1::r2::r3::rs) fs
|
||||||
| JMP b ->
|
| JMP b ->
|
||||||
enqueue b;
|
enqueue b;
|
||||||
fs
|
fs
|
||||||
|
@ -126,6 +124,10 @@ let pp_ins ~label ppf = function
|
||||||
| SET (a, b, c) -> Fmt.pf ppf "mov %a[%a], %a" pp_reg b pp_reg c pp_reg a
|
| SET (a, b, c) -> Fmt.pf ppf "mov %a[%a], %a" pp_reg b pp_reg c pp_reg a
|
||||||
| LOC (a, b, el) -> Fmt.pf ppf "mov %a, &%a.%s" pp_reg a pp_reg b el
|
| LOC (a, b, el) -> Fmt.pf ppf "mov %a, &%a.%s" pp_reg a pp_reg b el
|
||||||
| CON (a, vt) -> Fmt.pf ppf "con %a, %a" pp_reg a pp_vtable vt
|
| CON (a, vt) -> Fmt.pf ppf "con %a, %a" pp_reg a pp_vtable vt
|
||||||
|
| CAL (a, b, c, ds) ->
|
||||||
|
Fmt.pf ppf "cal %a, %a[%a](" pp_reg a pp_reg b pp_reg c;
|
||||||
|
List.iteri (fun i d -> if i > 0 then Fmt.pf ppf ","; pp_reg ppf d) ds;
|
||||||
|
Fmt.pf ppf ")"
|
||||||
| RET -> Fmt.pf ppf "ret"
|
| RET -> Fmt.pf ppf "ret"
|
||||||
| JMP b -> Fmt.pf ppf "jmp %s" (label b)
|
| JMP b -> Fmt.pf ppf "jmp %s" (label b)
|
||||||
| CBR (a, b1, b2) ->
|
| CBR (a, b1, b2) ->
|
||||||
|
|
|
@ -64,7 +64,7 @@ type frame = {
|
||||||
|
|
||||||
let jmp fr b = fr.pc <- Code.instructions b
|
let jmp fr b = fr.pc <- Code.instructions b
|
||||||
|
|
||||||
let exec ({ r; _ } as fr) = function
|
let rec exec ({ r; _ } as fr) = function
|
||||||
| Code.LDI (R a, v) -> r.(a) <- v
|
| Code.LDI (R a, v) -> r.(a) <- v
|
||||||
| Code.LDR (R a, R b) -> r.(a) <- r.(b)
|
| Code.LDR (R a, R b) -> r.(a) <- r.(b)
|
||||||
| Code.ADD (R a, R b, R c) -> r.(a) <- Prim.add r.(b) r.(c)
|
| Code.ADD (R a, R b, R c) -> r.(a) <- Prim.add r.(b) r.(c)
|
||||||
|
@ -78,13 +78,27 @@ let exec ({ r; _ } as fr) = function
|
||||||
| Code.SET (R a, R b, R c) -> Prim.set r.(b) r.(c) r.(a)
|
| Code.SET (R a, R b, R c) -> Prim.set r.(b) r.(c) r.(a)
|
||||||
| Code.LOC (R a, R b, el) -> r.(a) <- Prim.loc r.(b) el
|
| Code.LOC (R a, R b, el) -> r.(a) <- Prim.loc r.(b) el
|
||||||
| Code.CON (R a, vtbl) -> r.(a) <- Value.make_obj vtbl
|
| Code.CON (R a, vtbl) -> r.(a) <- Value.make_obj vtbl
|
||||||
|
| Code.CAL (R a, R b, R c, args) ->
|
||||||
|
let obj, mthd = Prim.mthd r.(b) r.(c) in
|
||||||
|
let args = List.map (fun (Code.R i) -> r.(i)) args in
|
||||||
|
r.(a) <- call mthd obj args
|
||||||
| Code.JMP b -> jmp fr b
|
| Code.JMP b -> jmp fr b
|
||||||
| Code.CBR (R a, b1, b2) ->
|
| Code.CBR (R a, b1, b2) ->
|
||||||
jmp fr (if Value.truthy r.(a) then b1 else b2)
|
jmp fr (if Value.truthy r.(a) then b1 else b2)
|
||||||
| Code.RET ->
|
| Code.RET ->
|
||||||
fr.pc <- []
|
fr.pc <- []
|
||||||
|
|
||||||
let rec step fr =
|
and call mthd self args =
|
||||||
|
match mthd with
|
||||||
|
| Code.Method { n_args; body } ->
|
||||||
|
if List.length args <> n_args then
|
||||||
|
runtime_error "wrong number of arguments, expected %d" n_args;
|
||||||
|
run body self (* args *)
|
||||||
|
|
||||||
|
| _ ->
|
||||||
|
Value.call mthd self args
|
||||||
|
|
||||||
|
and step fr =
|
||||||
match fr.pc with
|
match fr.pc with
|
||||||
| [] -> ()
|
| [] -> ()
|
||||||
| i :: rest ->
|
| i :: rest ->
|
||||||
|
@ -92,10 +106,11 @@ let rec step fr =
|
||||||
exec fr i;
|
exec fr i;
|
||||||
step fr
|
step fr
|
||||||
|
|
||||||
let run prog self =
|
and run prog self (* args *) =
|
||||||
let r = Array.make (Code.frame_size prog) Value.Nil in
|
let r = Array.make (Code.frame_size prog) Value.Nil in
|
||||||
let fr = { r; pc = [] } in
|
let fr = { r; pc = [] } in
|
||||||
r.(0) <- self;
|
r.(0) <- self;
|
||||||
jmp fr prog.entry;
|
jmp fr prog.entry;
|
||||||
step fr;
|
step fr;
|
||||||
r.(0)
|
r.(0)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue