shithub: martian9

ref: 02b360fe6c10ef6ec280c44a7935df743e68e0de
dir: martian9/printer.ml

View raw version
module T = Types.Types

let meta obj =
  match obj with
  | T.List { T.meta } -> meta
  | T.Proc { T.meta } -> meta
  | T.Symbol { T.meta } -> meta
  | T.Vector { T.meta } -> meta
  | T.Record { 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 } -> "#<macro>" ^ print xs r
  | T.Map { T.value = xs } ->
    "{"
    ^ 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 p -> "#<proc>"
  | T.Symbol { T.value = s } -> s
  | T.Bytevector bv -> "<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 p -> "<port unsupported>"
  | T.String s ->
    if r
    then
      "\""
      ^ Reader.gsub
          (Str.regexp "\\([\"\\\n]\\)")
          (function
            | "\n" -> "\\n"
            | x -> "\\" ^ x)
          s
      ^ "\""
    else s
  | T.List { T.value = xs } -> "(" ^ stringify xs r ^ ")"
  | T.Vector { T.value = v } -> "#(" ^ stringify v r ^ ")"
  | T.Record r -> "<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)