Skip to content

Commit a60d33c

Browse files
committed
Add json mapper for pp_ast
Signed-off-by: pedrobslisboa <[email protected]>
1 parent ac7fcfc commit a60d33c

File tree

7 files changed

+514
-8
lines changed

7 files changed

+514
-8
lines changed

Diff for: bin/pp_ast.ml

+8-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ let loc_mode =
9797
in
9898
named (fun x -> `Loc_mode x) Cmdliner.Arg.(value & vflag `Short [ full_locs ])
9999

100+
let json =
101+
let doc = "Show AST as json" in
102+
named (fun x -> `Json x) Cmdliner.Arg.(value & flag & info ~doc [ "json" ])
103+
100104
let kind =
101105
let make_vflag (flag, (kind : Kind.t), doc) =
102106
(Some kind, Cmdliner.Arg.info ~doc [ flag ])
@@ -126,7 +130,7 @@ let input =
126130
let errorf fmt = Printf.ksprintf (fun s -> Error s) fmt
127131

128132
let run (`Show_attrs show_attrs) (`Show_locs show_locs) (`Loc_mode loc_mode)
129-
(`Kind kind) (`Input input) =
133+
(`Json json) (`Kind kind) (`Input input) =
130134
let open Stdppx.Result in
131135
let kind =
132136
match kind with
@@ -147,13 +151,14 @@ let run (`Show_attrs show_attrs) (`Show_locs show_locs) (`Loc_mode loc_mode)
147151
match input with Stdin -> "<stdin>" | File fn -> fn | Source _ -> "<cli>"
148152
in
149153
let ast = load_input ~kind ~input_name input in
150-
let config = Pp_ast.Config.make ~show_attrs ~show_locs ~loc_mode () in
154+
let config = Pp_ast.Config.make ~show_attrs ~show_locs ~loc_mode ~json () in
151155
pp_ast ~config ast;
152156
Format.printf "%!\n";
153157
Ok ()
154158

155159
let term =
156-
Cmdliner.Term.(const run $ show_attrs $ show_locs $ loc_mode $ kind $ input)
160+
Cmdliner.Term.(
161+
const run $ show_attrs $ show_locs $ loc_mode $ json $ kind $ input)
157162

158163
let tool_name = "ppxlib-pp-ast"
159164

Diff for: dune-project

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
(sexplib0 (>= v0.12))
2323
(sexplib0 (and :with-test (>= "v0.15"))) ; Printexc.register_printer in sexplib0 changed
2424
stdlib-shims
25+
yojson
2526
(ocamlfind :with-test)
2627
(re (and :with-test (>= 1.9.0)))
2728
(cinaps (and :with-test (>= v0.12.1)))

Diff for: ppxlib.opam

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ depends: [
2727
"sexplib0" {>= "v0.12"}
2828
"sexplib0" {with-test & >= "v0.15"}
2929
"stdlib-shims"
30+
"yojson"
3031
"ocamlfind" {with-test}
3132
"re" {with-test & >= "1.9.0"}
3233
"cinaps" {with-test & >= "v0.12.1"}

Diff for: src/dune

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
ppx_derivers
1010
ppxlib_traverse_builtins
1111
stdppx
12+
yojson
1213
stdlib-shims
1314
sexplib0)
1415
(flags

Diff for: src/pp_ast.ml

+39-5
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,28 @@ open Import
22

33
module Config = struct
44
type loc_mode = [ `Short | `Full ]
5-
type t = { show_attrs : bool; show_locs : bool; loc_mode : loc_mode }
5+
6+
type t = {
7+
show_attrs : bool;
8+
show_locs : bool;
9+
loc_mode : loc_mode;
10+
json : bool;
11+
}
612

713
module Default = struct
814
let show_attrs = false
915
let show_locs = false
1016
let loc_mode = `Short
17+
let json = false
1118
end
1219

1320
let default =
1421
let open Default in
15-
{ show_attrs; show_locs; loc_mode }
22+
{ show_attrs; show_locs; loc_mode; json }
1623

1724
let make ?(show_attrs = Default.show_attrs) ?(show_locs = Default.show_locs)
18-
?(loc_mode = Default.loc_mode) () =
19-
{ show_attrs; show_locs; loc_mode }
25+
?(json = Default.json) ?(loc_mode = Default.loc_mode) () =
26+
{ show_attrs; show_locs; loc_mode; json }
2027
end
2128

2229
let cnum (pos : Lexing.position) = pos.pos_cnum - pos.pos_bol
@@ -77,6 +84,29 @@ let rec pp_simple_val fmt simple_val =
7784
and pp_field fmt (fname, simple_val) =
7885
Format.fprintf fmt "@[<hv 2>%s =@ %a@]" fname pp_simple_val simple_val
7986

87+
let rec pp_simple_val_to_yojson = function
88+
| Unit -> `String "null"
89+
| Int i -> `Int i
90+
| String s -> `String s
91+
| Bool b -> `Bool b
92+
| Char c -> `String (String.make 1 c)
93+
| Array l -> `List (List.map ~f:pp_simple_val_to_yojson l)
94+
| Float f -> `Float f
95+
| Int32 i32 -> `Int (Int32.to_int i32)
96+
| Int64 i64 -> `Int (Int64.to_int i64)
97+
| Nativeint ni -> `Int (Nativeint.to_int ni)
98+
| Record fields ->
99+
`Assoc (List.map ~f:(fun (k, v) -> (k, pp_simple_val_to_yojson v)) fields)
100+
| Constr (cname, []) -> `String cname
101+
| Constr (cname, [ (Constr (_, _ :: _) as x) ]) ->
102+
`Assoc [ (cname, pp_simple_val_to_yojson x) ]
103+
| Constr (cname, [ x ]) -> `Assoc [ (cname, pp_simple_val_to_yojson x) ]
104+
| Constr (cname, l) ->
105+
`Assoc [ (cname, `List (List.map ~f:pp_simple_val_to_yojson l)) ]
106+
| Tuple l -> `List (List.map ~f:pp_simple_val_to_yojson l)
107+
| List l -> `List (List.map ~f:pp_simple_val_to_yojson l)
108+
| Special s -> `String s
109+
80110
class lift_simple_val =
81111
object (self)
82112
inherit [simple_val] Ast_traverse.lift as super
@@ -271,7 +301,11 @@ let with_config ~config ~f =
271301

272302
let pp_with_config (type a) (lifter : a -> simple_val)
273303
?(config = Config.default) fmt (x : a) =
274-
with_config ~config ~f:(fun () -> pp_simple_val fmt (lifter x))
304+
with_config ~config ~f:(fun () ->
305+
if config.json then
306+
Format.fprintf fmt "%s"
307+
(Yojson.pretty_to_string (pp_simple_val_to_yojson (lifter x)))
308+
else pp_simple_val fmt (lifter x))
275309

276310
let structure = pp_with_config lift_simple_val#structure
277311
let structure_item = pp_with_config lift_simple_val#structure_item

Diff for: src/pp_ast.mli

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ module Config : sig
4040
val make :
4141
?show_attrs:bool ->
4242
?show_locs:bool ->
43+
?json:bool ->
4344
?loc_mode:[ `Short | `Full ] ->
4445
unit ->
4546
t

0 commit comments

Comments
 (0)