blob: 15bb3851bcb775dd576049908c11193f00c1704f [file] [edit]
type sexpr = Atom of string | Node of string * sexpr list
type rope = Leaf of string | Concat of rope list
let (^+) s r = Concat [Leaf s; r]
let (+^) r s = Concat [r; Leaf s]
let rec iter f = function
| Leaf s -> f s
| Concat rs -> List.iter (iter f) rs
let rec concat = function
| Leaf s -> s
| Concat rs -> String.concat "" (List.map concat rs)
let rec pp off width = function
| Atom s -> String.length s, Leaf s
| Node (s, xs) ->
let lens, rs = List.split (List.map (pp (off + 2) width) xs) in
let len = String.length s + List.length rs + List.fold_left (+) 2 lens in
let sep, fin =
if off + len <= width then " ", ""
else let indent = String.make off ' ' in "\n " ^ indent, "\n" ^ indent
in len, "(" ^+ s ^+ Concat (List.map (fun r -> sep ^+ r) rs) +^ fin +^ ")"
let output oc width x =
iter (output_string oc) (snd (pp 0 width x));
output_string oc "\n";
flush oc
let print = output stdout
let to_string width x = concat (snd (pp 0 width x)) ^ "\n"