Skip to content

Commit 4889a55

Browse files
committed
Add json mapper for pp_ast
Signed-off-by: Pedro B S Lisboa <[email protected]>
1 parent 2ea8145 commit 4889a55

File tree

5 files changed

+92
-38
lines changed

5 files changed

+92
-38
lines changed

Diff for: bin/dune

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
(name pp_ast)
33
(public_name ppxlib-pp-ast)
44
(package ppxlib-tools)
5-
(libraries cmdliner ppxlib ppxlib.ast ppxlib.astlib ppxlib.stdppx))
5+
(libraries cmdliner ppxlib ppxlib.ast ppxlib.astlib ppxlib.stdppx yojson))

Diff for: bin/pp_ast.ml

+39-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,30 @@ module Ast = struct
1818
| Typ of core_type
1919
end
2020

21+
let rec simple_val_to_yojson : Pp_ast.simple_val -> Yojson.Basic.t = function
22+
| Unit -> `Null
23+
| Int i -> `Int i
24+
| String s -> `String s
25+
| Special s -> `String s
26+
| Bool b -> `Bool b
27+
| Char c -> `String (String.make 1 c)
28+
| Float f -> `Float f
29+
| Int32 i32 -> `Int (Int32.to_int i32)
30+
| Int64 i64 -> `Int (Int64.to_int i64)
31+
| Nativeint ni -> `Int (Nativeint.to_int ni)
32+
| Array l -> `List (List.map simple_val_to_yojson l)
33+
| Tuple l -> `List (List.map simple_val_to_yojson l)
34+
| List l -> `List (List.map simple_val_to_yojson l)
35+
| Record fields ->
36+
`Assoc (List.map (fun (k, v) -> (k, simple_val_to_yojson v)) fields)
37+
| Constr (cname, []) -> `String cname
38+
| Constr (cname, [ x ]) -> `Assoc [ (cname, simple_val_to_yojson x) ]
39+
| Constr (cname, l) ->
40+
`Assoc [ (cname, `List (List.map simple_val_to_yojson l)) ]
41+
42+
let pp_json fmt simple_val =
43+
Yojson.Basic.pp fmt (simple_val_to_yojson simple_val)
44+
2145
module Input = struct
2246
type t = Stdin | File of string | Source of string
2347

@@ -66,13 +90,13 @@ let load_input ~kind ~input_name input =
6690
| (Expression | Pattern | Core_type), _ | _, Source _ ->
6791
parse_node ~kind ~input_name input
6892

69-
let pp_ast ~config ast =
93+
let pp_ast ~config ?printer ast =
7094
match (ast : Ast.t) with
71-
| Str str -> Pp_ast.structure ~config Format.std_formatter str
72-
| Sig sig_ -> Pp_ast.signature ~config Format.std_formatter sig_
73-
| Exp exp -> Pp_ast.expression ~config Format.std_formatter exp
74-
| Pat pat -> Pp_ast.pattern ~config Format.std_formatter pat
75-
| Typ typ -> Pp_ast.core_type ~config Format.std_formatter typ
95+
| Str str -> Pp_ast.structure ~config ?printer Format.std_formatter str
96+
| Sig sig_ -> Pp_ast.signature ~config ?printer Format.std_formatter sig_
97+
| Exp exp -> Pp_ast.expression ~config ?printer Format.std_formatter exp
98+
| Pat pat -> Pp_ast.pattern ~config ?printer Format.std_formatter pat
99+
| Typ typ -> Pp_ast.core_type ~config ?printer Format.std_formatter typ
76100

77101
let named f = Cmdliner.Term.(app (const f))
78102

@@ -97,6 +121,10 @@ let loc_mode =
97121
in
98122
named (fun x -> `Loc_mode x) Cmdliner.Arg.(value & vflag `Short [ full_locs ])
99123

124+
let json =
125+
let doc = "Show AST as json" in
126+
named (fun x -> `Json x) Cmdliner.Arg.(value & flag & info ~doc [ "json" ])
127+
100128
let kind =
101129
let make_vflag (flag, (kind : Kind.t), doc) =
102130
(Some kind, Cmdliner.Arg.info ~doc [ flag ])
@@ -126,7 +154,7 @@ let input =
126154
let errorf fmt = Printf.ksprintf (fun s -> Error s) fmt
127155

128156
let run (`Show_attrs show_attrs) (`Show_locs show_locs) (`Loc_mode loc_mode)
129-
(`Kind kind) (`Input input) =
157+
(`Json json) (`Kind kind) (`Input input) =
130158
let open Stdppx.Result in
131159
let kind =
132160
match kind with
@@ -148,12 +176,14 @@ let run (`Show_attrs show_attrs) (`Show_locs show_locs) (`Loc_mode loc_mode)
148176
in
149177
let ast = load_input ~kind ~input_name input in
150178
let config = Pp_ast.Config.make ~show_attrs ~show_locs ~loc_mode () in
151-
pp_ast ~config ast;
179+
let custom_printer = if json then Some pp_json else None in
180+
pp_ast ~config ?printer:custom_printer ast;
152181
Format.printf "%!\n";
153182
Ok ()
154183

155184
let term =
156-
Cmdliner.Term.(const run $ show_attrs $ show_locs $ loc_mode $ kind $ input)
185+
Cmdliner.Term.(
186+
const run $ show_attrs $ show_locs $ loc_mode $ json $ kind $ input)
157187

158188
let tool_name = "ppxlib-pp-ast"
159189

Diff for: src/pp_ast.ml

+19-16
Original file line numberDiff line numberDiff line change
@@ -302,31 +302,34 @@ class lift_simple_val =
302302
| NoInjectivity -> Constr ("NoInjectivity", [])
303303
end
304304

305+
type printer = Format.formatter -> simple_val -> unit
305306
type 'a pp = Format.formatter -> 'a -> unit
306-
type 'a configurable = ?config:Config.t -> 'a pp
307+
type 'a configurable = ?config:Config.t -> ?printer: printer -> 'a pp
307308
type 'a configured = 'a pp
308309

309310
module type S = sig
310-
type 'a printer
311-
312-
val structure : structure printer
313-
val structure_item : structure_item printer
314-
val signature : signature printer
315-
val signature_item : signature_item printer
316-
val expression : expression printer
317-
val pattern : pattern printer
318-
val core_type : core_type printer
311+
type 'a ast_printer
312+
313+
val structure : structure ast_printer
314+
val structure_item : structure_item ast_printer
315+
val signature : signature ast_printer
316+
val signature_item : signature_item ast_printer
317+
val expression : expression ast_printer
318+
val pattern : pattern ast_printer
319+
val core_type : core_type ast_printer
319320
end
320321

321322
module type Conf = sig
322323
val config : Config.t
323324
end
324325

325-
module type Configured = S with type 'a printer = 'a configured
326-
module type Configurable = S with type 'a printer = 'a configurable
326+
module type Configured = S with type 'a ast_printer = 'a configured
327+
328+
module type Configurable =
329+
S with type 'a ast_printer = 'a configurable
327330

328331
module Make (Conf : Conf) : Configured = struct
329-
type 'a printer = 'a configured
332+
type 'a ast_printer = 'a configured
330333

331334
let lsv =
332335
let lift_simple_val = new lift_simple_val in
@@ -351,7 +354,7 @@ module Default = Make (struct
351354
let config = Config.default
352355
end)
353356

354-
type 'a printer = 'a configurable
357+
type 'a ast_printer = 'a configurable
355358

356359
let lift_simple_val = new lift_simple_val
357360

@@ -363,8 +366,8 @@ let with_config ~config ~f =
363366
res
364367

365368
let pp_with_config (type a) (lifter : a -> simple_val)
366-
?(config = Config.default) fmt (x : a) =
367-
with_config ~config ~f:(fun () -> pp_simple_val fmt (lifter x))
369+
?(config = Config.default) ?(printer = pp_simple_val) fmt (x : a) =
370+
with_config ~config ~f:(fun () -> printer fmt (lifter x))
368371

369372
let structure = pp_with_config lift_simple_val#structure
370373
let structure_item = pp_with_config lift_simple_val#structure_item

Diff for: src/pp_ast.mli

+32-12
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,48 @@ module Config : sig
6060
be. *)
6161
end
6262

63+
type simple_val =
64+
| Unit
65+
| Int of int
66+
| String of string
67+
| Bool of bool
68+
| Char of char
69+
| Array of simple_val list
70+
| Float of float
71+
| Int32 of int32
72+
| Int64 of int64
73+
| Nativeint of nativeint
74+
| Record of (string * simple_val) list
75+
| Constr of string * simple_val list
76+
| Tuple of simple_val list
77+
| List of simple_val list
78+
| Special of string
79+
80+
type printer = Format.formatter -> simple_val -> unit
81+
val pp_simple_val : printer
82+
6383
type 'a pp = Format.formatter -> 'a -> unit
64-
type 'a configurable = ?config:Config.t -> 'a pp
84+
type 'a configurable = ?config:Config.t -> ?printer: printer -> 'a pp
6585
type 'a configured = 'a pp
6686

6787
module type S = sig
68-
type 'a printer
69-
70-
val structure : structure printer
71-
val structure_item : structure_item printer
72-
val signature : signature printer
73-
val signature_item : signature_item printer
74-
val expression : expression printer
75-
val pattern : pattern printer
76-
val core_type : core_type printer
88+
type 'a ast_printer
89+
90+
val structure : structure ast_printer
91+
val structure_item : structure_item ast_printer
92+
val signature : signature ast_printer
93+
val signature_item : signature_item ast_printer
94+
val expression : expression ast_printer
95+
val pattern : pattern ast_printer
96+
val core_type : core_type ast_printer
7797
end
7898

7999
module type Conf = sig
80100
val config : Config.t
81101
end
82102

83-
module type Configured = S with type 'a printer = 'a configured
84-
module type Configurable = S with type 'a printer = 'a configurable
103+
module type Configured = S with type 'a ast_printer = 'a configured
104+
module type Configurable = S with type 'a ast_printer = 'a configurable
85105

86106
module Make (Conf : Conf) : Configured [@@ocaml.warning "-67"]
87107

Diff for: test.ml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let foo = "x"

0 commit comments

Comments
 (0)