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; } type t = | Nil | True | False | Int of int64 | Obj of vtable * t array let make_obj vtable = Obj (vtable, Array.make vtable.n_slots Nil) let bool = function | true -> True | false -> False 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" | True -> "true" | False -> "false" | v -> Fmt.str "%a" pp 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 "}"