add object values, CON instruction
This commit is contained in:
parent
fb8a2cdcab
commit
7569cd2ee4
35
bin/main.ml
35
bin/main.ml
|
@ -1,23 +1,28 @@
|
||||||
let () =
|
open Spice
|
||||||
|
|
||||||
|
let[@warning "-26"] () =
|
||||||
Logs.set_reporter (Logs.format_reporter ());
|
Logs.set_reporter (Logs.format_reporter ());
|
||||||
Logs.set_level (Some Logs.Debug);
|
Logs.set_level (Some Logs.Debug);
|
||||||
|
|
||||||
try
|
try
|
||||||
let int n = Spice.Code.Cst_int (Int64.of_int n) in
|
let int n = Code.Cst_int (Int64.of_int n) in
|
||||||
let reg n = Spice.Code.Reg n in
|
let reg n = Code.Reg n in
|
||||||
|
|
||||||
let l0 = Spice.Code.make_basic_block [ MUL (0, reg 1); RET ] in
|
let posn_vt = Value.make_vtable [ "x"; "y" ] in
|
||||||
let ep =
|
let ep =
|
||||||
Spice.Code.make_basic_block
|
Code.make_basic_block
|
||||||
[ MOV (0, int 4); MOV (1, int 5); ADD (1, int 6); JMP l0 ]
|
[
|
||||||
|
CON (0, posn_vt);
|
||||||
|
(* MOV (1, int 0); "x" *)
|
||||||
|
(* MOV (2, int 100); *)
|
||||||
|
(* SET (0, 1); *)
|
||||||
|
(* MOV (1, int 1); "y" *)
|
||||||
|
(* MOV (2, int 100); *)
|
||||||
|
(* SET (0, 1); *)
|
||||||
|
]
|
||||||
in
|
in
|
||||||
|
|
||||||
let prog = Spice.Code.make_program ep in
|
let prog = Code.make_program ep in
|
||||||
let ret = Spice.run prog in
|
let ret = run prog in
|
||||||
Fmt.pr
|
Fmt.pr "{\"program\":%a,\"output\":%a}" Code.pp_program prog Value.pp ret
|
||||||
"{\"program\":%a,\"output\":%a}"
|
with Error msg -> Logs.err (fun m -> m "%s" msg)
|
||||||
Spice.Code.pp_program
|
|
||||||
prog
|
|
||||||
Spice.Value.pp
|
|
||||||
ret
|
|
||||||
with Spice.Error msg -> Logs.err (fun m -> m "%s" msg)
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ and ins =
|
||||||
| ADD of regidx * operand
|
| ADD of regidx * operand
|
||||||
| SUB of regidx * operand
|
| SUB of regidx * operand
|
||||||
| MUL of regidx * operand
|
| MUL of regidx * operand
|
||||||
|
| CON of regidx * Value.vtable
|
||||||
| JMP of basic_block
|
| JMP of basic_block
|
||||||
| BRT of operand * basic_block * basic_block
|
| BRT of operand * basic_block * basic_block
|
||||||
| RET
|
| RET
|
||||||
|
@ -50,7 +51,8 @@ let frame_size prog =
|
||||||
| _ -> acc
|
| _ -> acc
|
||||||
in
|
in
|
||||||
let ins acc = function
|
let ins acc = function
|
||||||
| MOV (l, r) | ADD (l, r) | SUB (l, r) | MUL (l, r) -> op (reg acc l) r
|
| MOV (r, v) | ADD (r, v) | SUB (r, v) | MUL (r, v) -> op (reg acc r) v
|
||||||
|
| CON (r, _) -> reg acc r
|
||||||
| BRT (v, b1, b2) ->
|
| BRT (v, b1, b2) ->
|
||||||
enqueue b1;
|
enqueue b1;
|
||||||
enqueue b2;
|
enqueue b2;
|
||||||
|
@ -86,9 +88,11 @@ let pp_ins ~get_bb_name ppf = function
|
||||||
| ADD (l, r) -> Fmt.pf ppf "add %a, %a" pp_reg l pp_operand r
|
| ADD (l, r) -> Fmt.pf ppf "add %a, %a" pp_reg l pp_operand r
|
||||||
| SUB (l, r) -> Fmt.pf ppf "sub %a, %a" pp_reg l pp_operand r
|
| SUB (l, r) -> Fmt.pf ppf "sub %a, %a" pp_reg l pp_operand r
|
||||||
| MUL (l, r) -> Fmt.pf ppf "mul %a, %a" pp_reg l pp_operand r
|
| MUL (l, r) -> Fmt.pf ppf "mul %a, %a" pp_reg l pp_operand r
|
||||||
|
| CON (l, vt) -> Fmt.pf ppf "con %a, %a" pp_reg l Value.pp_vtable vt
|
||||||
| RET -> Fmt.pf ppf "ret"
|
| RET -> Fmt.pf ppf "ret"
|
||||||
| JMP l -> Fmt.pf ppf "jmp %s" (get_bb_name l)
|
| JMP l -> Fmt.pf ppf "jmp %s" (get_bb_name l)
|
||||||
| _ -> failwith "..."
|
| BRT (v, l1, l2) ->
|
||||||
|
Fmt.pf ppf "brt %a, %s, %s" pp_operand v (get_bb_name l1) (get_bb_name l2)
|
||||||
|
|
||||||
let pp_program ppf pr =
|
let pp_program ppf pr =
|
||||||
let ep = pr.entrypoint in
|
let ep = pr.entrypoint in
|
||||||
|
|
|
@ -46,6 +46,7 @@ let exec fr = function
|
||||||
| Code.ADD (l, r) -> fr.regs.(l) <- Op.add fr.regs.(l) (eval fr r)
|
| Code.ADD (l, r) -> fr.regs.(l) <- Op.add fr.regs.(l) (eval fr r)
|
||||||
| Code.SUB (l, r) -> fr.regs.(l) <- Op.add fr.regs.(l) (eval fr r)
|
| Code.SUB (l, r) -> fr.regs.(l) <- Op.add fr.regs.(l) (eval fr r)
|
||||||
| Code.MUL (l, r) -> fr.regs.(l) <- Op.mul fr.regs.(l) (eval fr r)
|
| Code.MUL (l, r) -> fr.regs.(l) <- Op.mul fr.regs.(l) (eval fr r)
|
||||||
|
| Code.CON (l, vt) -> fr.regs.(l) <- Value.make_obj vt
|
||||||
| Code.RET -> fr.pc <- []
|
| Code.RET -> fr.pc <- []
|
||||||
| Code.JMP l -> fr.pc <- Code.instructions l
|
| Code.JMP l -> fr.pc <- Code.instructions l
|
||||||
| Code.BRT (v, l1, l2) ->
|
| Code.BRT (v, l1, l2) ->
|
||||||
|
|
|
@ -1,19 +1,65 @@
|
||||||
|
type vtable = {
|
||||||
|
n_slots : int;
|
||||||
|
elems : (string, elem) Hashtbl.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
and slotidx = int
|
||||||
|
|
||||||
|
and elem =
|
||||||
|
| Field of slotidx
|
||||||
|
| Method (* of callable *)
|
||||||
|
|
||||||
|
let make_vtable fields =
|
||||||
|
{
|
||||||
|
n_slots = List.length fields;
|
||||||
|
elems = List.to_seq fields |> Seq.mapi (fun i name -> name, Field i) |> Hashtbl.of_seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pp_vtable ppf vt =
|
||||||
|
Fmt.pf ppf "<%d>{" vt.n_slots;
|
||||||
|
let sep = ref "" in
|
||||||
|
Hashtbl.iter
|
||||||
|
(fun name -> function
|
||||||
|
| Method -> ()
|
||||||
|
| Field idx ->
|
||||||
|
Fmt.pf ppf "%s%s@%d" !sep name idx;
|
||||||
|
sep := ";")
|
||||||
|
vt.elems;
|
||||||
|
Fmt.pf ppf "}"
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
| Nil
|
| Nil
|
||||||
| True
|
| True
|
||||||
| False
|
| False
|
||||||
| Int of int64
|
| Int of int64
|
||||||
(* | Obj of vtable * slots *)
|
| Obj of vtable * t array
|
||||||
|
|
||||||
let equal v1 v2 =
|
let equal v1 v2 =
|
||||||
match v1, v2 with
|
match v1, v2 with
|
||||||
| Int x, Int y -> Int64.equal x y
|
| Int x, Int y -> Int64.equal x y
|
||||||
| _, _ -> v1 == v2
|
| _, _ -> v1 == v2
|
||||||
|
|
||||||
let to_string = function
|
let make_obj vtable = Obj (vtable, Array.make vtable.n_slots Nil)
|
||||||
|
|
||||||
|
let rec pp ppf = function
|
||||||
|
| Obj (vtable, slots) -> pp_obj ppf vtable slots
|
||||||
|
| Int n -> Fmt.string ppf (Int64.to_string n)
|
||||||
|
| v -> Fmt.pf ppf "%S" (to_string v)
|
||||||
|
|
||||||
|
and to_string = function
|
||||||
| Nil -> "nil"
|
| Nil -> "nil"
|
||||||
| True -> "true"
|
| True -> "true"
|
||||||
| False -> "false"
|
| False -> "false"
|
||||||
| Int n -> Int64.to_string n
|
| v -> Fmt.str "%a" pp v
|
||||||
|
|
||||||
let pp ppf v = Format.pp_print_string ppf (to_string v)
|
and pp_obj ppf vtable slots =
|
||||||
|
Fmt.pf ppf "{";
|
||||||
|
let sep = ref "" in
|
||||||
|
Hashtbl.iter
|
||||||
|
(fun name -> function
|
||||||
|
| Method -> ()
|
||||||
|
| Field idx ->
|
||||||
|
Fmt.pf ppf "%s%S:%a" !sep name pp slots.(idx);
|
||||||
|
sep := ",")
|
||||||
|
vtable.elems;
|
||||||
|
Fmt.pf ppf "}"
|
||||||
|
|
Loading…
Reference in New Issue