2023-11-29 22:56:42 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-11-29 21:48:24 +00:00
|
|
|
type t =
|
|
|
|
| Nil
|
|
|
|
| True
|
|
|
|
| False
|
|
|
|
| Int of int64
|
2023-11-29 22:56:42 +00:00
|
|
|
| Obj of vtable * t array
|
2023-11-29 21:48:24 +00:00
|
|
|
|
|
|
|
let equal v1 v2 =
|
|
|
|
match v1, v2 with
|
|
|
|
| Int x, Int y -> Int64.equal x y
|
|
|
|
| _, _ -> v1 == v2
|
|
|
|
|
2023-11-29 22:56:42 +00:00
|
|
|
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
|
2023-11-29 21:48:24 +00:00
|
|
|
| Nil -> "nil"
|
|
|
|
| True -> "true"
|
|
|
|
| False -> "false"
|
2023-11-29 22:56:42 +00:00
|
|
|
| v -> Fmt.str "%a" pp v
|
2023-11-29 21:48:24 +00:00
|
|
|
|
2023-11-29 22:56:42 +00:00
|
|
|
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 "}"
|