Skip to content

Instantly share code, notes, and snippets.

@edwintorok
Created October 3, 2017 08:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edwintorok/5ea6c06f7e23c38fadf0a529fcfcc416 to your computer and use it in GitHub Desktop.
Save edwintorok/5ea6c06f7e23c38fadf0a529fcfcc416 to your computer and use it in GitHub Desktop.
open Sexplib
let reformat sexp = sexp
let vparens pp ppf = Fmt.pf ppf "@[<v1>(%a)@]" pp
let slist = Fmt.(list ~sep:sp)
let spair = Fmt.(pair ~sep:sp)
let canonicalize_set = List.sort_uniq (*Sexp.*)compare
let rec canonicalize_ordered_set accum =
let open Sexp in
function
| Atom "\\" as atom :: rest ->
(* TODO: flatten nesting if possible, canonicalize inside nesting *)
List.rev_append (atom :: accum) (canonicalize_set rest)
| _ as item :: rest ->
canonicalize_ordered_set (item :: accum) rest
| [] -> List.rev accum
let rec pp_jbuild ppf =
let open Sexp in function
| List[Atom (( "c_flags"
| "c_library_flags"
| "cxx_flags"
| "flags"
| "modules"
| "ocamlc_flags"
| "ocamlopt_flags") as atom); List oset] ->
pp_atom_list (canonicalize_ordered_set []) ppf (atom, oset)
| List[Atom (( "c_names"
| "cxx_names"
| "deps"
| "files"
| "install_c_headers"
| "libraries"
| "modes"
| "names"
| "ocamllex"
| "ocamlyacc"
| "ppx_runtime_libraries"
| "preprocessor_deps"
| "public_names"
| "targets"
| "virtual_deps") as atom); List set] ->
let vertical = List.length set > 1 in
pp_atom_list ~vertical canonicalize_set ppf (atom, set)
| List( Atom _ :: List(List _ :: _) :: _ | List _ :: _ as l) ->
(pp_jbuild |> slist |> vparens) ppf l
| List l ->
(pp_jbuild |> slist |> Fmt.parens) ppf l (* single line if it fits *)
| Atom ("\\" as c) -> Fmt.string ppf c
| Atom _ as s -> Sexp.pp_hum ppf s (* this does escaping properly *)
and pp_atom_list ?(vertical=false) xform ppf =
let wrap = if vertical then vparens else Fmt.parens in
(spair Fmt.string (slist pp_jbuild |> wrap |> Fmt.using xform) |> wrap) ppf
let cut2 ppf () =
Fmt.cut ppf ();
Fmt.cut ppf ()
let () =
let open Sexp.Annotated in
let parse_pos = Sexp.Parse_pos.create () in
Format.set_margin 80;
stdin |> input_rev_sexps ~parse_pos |> List.rev_map get_sexp |>
Fmt.pf Format.std_formatter "%a@." Fmt.(pp_jbuild |> list ~sep:cut2 |> vbox)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment