let rec to_string r =
if Obj.is_int r
then
(let i : int = Obj.magic r
in (string_of_int i) ^ (" | CstTag" ^ (string_of_int (i + 1))))
else
(let rec get_fields acc =
function
| 0 -> acc
| n -> let n = n - 1 in get_fields ((Obj.field r n) :: acc) n in
let rec is_list r =
if Obj.is_int r
then r = (Obj.repr 0)
else
(let s = Obj.size r
and t = Obj.tag r
in (t = 0) && ((s = 2) && (is_list (Obj.field r 1)))) in
let rec get_list r =
if Obj.is_int r
then []
else
(let h = Obj.field r 0
and t = get_list (Obj.field r 1)
in h :: t) in
let opaque name = "<" ^ (name ^ ">") in
let s = Obj.size r
and t = Obj.tag r
in
match t with
| _ when is_list r ->
let fields = get_list r
in
"[" ^
((String.concat "; " (List.map to_string fields)) ^
"]")
| 0 ->
let fields = get_fields [] s
in
"(" ^
((String.concat ", " (List.map to_string fields)) ^
")")
| x when x = Obj.lazy_tag -> opaque "lazy"
| x when x = Obj.closure_tag -> opaque "closure"
| x when x = Obj.object_tag ->
let fields = get_fields [] s in
let (_class, id, slots) =
(match fields with
| h :: h' :: t -> (h, h', t)
| _ -> assert false)
in
"Object #" ^
((to_string id) ^
(" (" ^
((String.concat ", " (List.map to_string slots))
^ ")")))
| x when x = Obj.infix_tag -> opaque "infix"
| x when x = Obj.forward_tag -> opaque "forward"
| x when x < Obj.no_scan_tag ->
let fields = get_fields [] s
in
"Tag" ^
((string_of_int t) ^
(" (" ^
((String.concat ", " (List.map to_string fields))
^ ")")))
| x when x = Obj.string_tag ->
"\"" ^ ((String.escaped (Obj.magic r : string)) ^ "\"")
| x when x = Obj.double_tag ->
string_of_float (Obj.magic r : float)
| x when x = Obj.abstract_tag -> opaque "abstract"
| x when x = Obj.custom_tag -> opaque "custom"
| x when x = Obj.final_tag -> opaque "final"
| _ ->
failwith
("ObjTools.to_string: unknown tag (" ^
((string_of_int t) ^ ")")))