shithub: martian9

ref: 60993540fa2f1383724705faf0796202250c63f6
dir: /printer.ml/

View raw version
module T = Types.Types

let meta obj =
  match obj with
  | T.List {T.value= _; T.meta} ->
      meta
  | T.Proc {T.value= _; T.meta} ->
      meta
  | T.Symbol {T.value= _; T.meta} ->
      meta
  | T.Vector {T.value= _; T.meta} ->
      meta
  | T.Record {T.value= _; T.meta} ->
      meta
  | _ ->
      T.Nil

let rec print obj readable =
  let r = readable in
  match obj with
  | T.Bool true ->
      "#t"
  | T.Bool false ->
      "#f"
  | T.Char c ->
      "#\\" ^ Char.escaped c
  | T.Nil ->
      "nil"
  | T.Macro {T.value= xs; T.meta= _} ->
      "#<macro>" ^ print xs r
  | T.Map {T.value= xs; T.meta= _} ->
      "{" ^ Types.M9map.fold (fun k v s -> s ^ (if s = "" then "" else " ") ^ print k r ^ " " ^ print v r) xs "" ^ "}"
  | T.Unspecified ->
      "#unspecified"
  | T.Eof_object ->
      "#eof"
  (* | T.Pair ({ T.value = one }, { T.value = two }) -> "(" ^ (print one readable) ^ " . " ^ (print two readable) ^ ")" *)
  | T.Proc _ ->
      "#<proc>"
  | T.Symbol {T.value= s; T.meta= _} ->
      s
  | T.Bytevector _ ->
      "<bytevector unsupported>"
  | T.Number n ->
      if Types.is_float n.value then string_of_float n.value else string_of_int (int_of_float n.value)
  | T.Port _ ->
      "<port unsupported>"
  | T.String s ->
      if r then "\"" ^ Utils.gsub (Str.regexp "\\([\"\\\n]\\)") (function "\n" -> "\\n" | x -> "\\" ^ x) s ^ "\""
      else s
  | T.List {T.value= xs; T.meta= _} ->
      "(" ^ stringify xs r ^ ")"
  | T.Vector {T.value= v; T.meta= _} ->
      "#(" ^ stringify v r ^ ")"
  | T.Record _ ->
      "<record unsupported>"

and stringify obj human =
  String.concat " "
    (List.filter (function T.Unspecified | T.Eof_object -> human | _ -> true) obj |> List.map (fun s -> print s human))

let dump obj = String.concat " " (List.map (fun s -> print s true) obj)

let to_string obj = print obj true