Skip to content

Commit b12844d

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

File tree

4 files changed

+89
-39
lines changed

4 files changed

+89
-39
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

+38-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,29 @@ 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 json_printer fmt value = Yojson.Basic.pp fmt (simple_val_to_yojson value)
43+
2144
module Input = struct
2245
type t = Stdin | File of string | Source of string
2346

@@ -66,13 +89,13 @@ let load_input ~kind ~input_name input =
6689
| (Expression | Pattern | Core_type), _ | _, Source _ ->
6790
parse_node ~kind ~input_name input
6891

69-
let pp_ast ~config ast =
92+
let pp_ast ~config ?printer ast =
7093
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
94+
| Str str -> Pp_ast.structure ~config ?printer Format.std_formatter str
95+
| Sig sig_ -> Pp_ast.signature ~config ?printer Format.std_formatter sig_
96+
| Exp exp -> Pp_ast.expression ~config ?printer Format.std_formatter exp
97+
| Pat pat -> Pp_ast.pattern ~config ?printer Format.std_formatter pat
98+
| Typ typ -> Pp_ast.core_type ~config ?printer Format.std_formatter typ
7699

77100
let named f = Cmdliner.Term.(app (const f))
78101

@@ -97,6 +120,10 @@ let loc_mode =
97120
in
98121
named (fun x -> `Loc_mode x) Cmdliner.Arg.(value & vflag `Short [ full_locs ])
99122

123+
let json =
124+
let doc = "Show AST as json" in
125+
named (fun x -> `Json x) Cmdliner.Arg.(value & flag & info ~doc [ "json" ])
126+
100127
let kind =
101128
let make_vflag (flag, (kind : Kind.t), doc) =
102129
(Some kind, Cmdliner.Arg.info ~doc [ flag ])
@@ -126,7 +153,7 @@ let input =
126153
let errorf fmt = Printf.ksprintf (fun s -> Error s) fmt
127154

128155
let run (`Show_attrs show_attrs) (`Show_locs show_locs) (`Loc_mode loc_mode)
129-
(`Kind kind) (`Input input) =
156+
(`Json json) (`Kind kind) (`Input input) =
130157
let open Stdppx.Result in
131158
let kind =
132159
match kind with
@@ -148,12 +175,14 @@ let run (`Show_attrs show_attrs) (`Show_locs show_locs) (`Loc_mode loc_mode)
148175
in
149176
let ast = load_input ~kind ~input_name input in
150177
let config = Pp_ast.Config.make ~show_attrs ~show_locs ~loc_mode () in
151-
pp_ast ~config ast;
178+
let custom_printer = if json then Some json_printer else None in
179+
pp_ast ~config ?printer:custom_printer ast;
152180
Format.printf "%!\n";
153181
Ok ()
154182

155183
let term =
156-
Cmdliner.Term.(const run $ show_attrs $ show_locs $ loc_mode $ kind $ input)
184+
Cmdliner.Term.(
185+
const run $ show_attrs $ show_locs $ loc_mode $ json $ kind $ input)
157186

158187
let tool_name = "ppxlib-pp-ast"
159188

Diff for: src/pp_ast.ml

+20-17
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ let pp_collection ~pp_elm ~open_ ~close ~sep fmt l =
4646
List.iter tl ~f:(fun sv -> Format.fprintf fmt "%s %a@," sep pp_elm sv);
4747
Format.fprintf fmt "%s@]" close
4848

49-
let rec pp_simple_val fmt simple_val =
49+
type printer = Format.formatter -> simple_val -> unit
50+
51+
let rec pp_simple_val : printer =
52+
fun fmt simple_val ->
5053
match simple_val with
5154
| Unit -> Format.fprintf fmt "()"
5255
| Int i -> Format.fprintf fmt "%i" i
@@ -303,30 +306,30 @@ class lift_simple_val =
303306
end
304307

305308
type 'a pp = Format.formatter -> 'a -> unit
306-
type 'a configurable = ?config:Config.t -> 'a pp
309+
type 'a configurable = ?config:Config.t -> ?printer:printer -> 'a pp
307310
type 'a configured = 'a pp
308311

309312
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
313+
type 'a ast_printer
314+
315+
val structure : structure ast_printer
316+
val structure_item : structure_item ast_printer
317+
val signature : signature ast_printer
318+
val signature_item : signature_item ast_printer
319+
val expression : expression ast_printer
320+
val pattern : pattern ast_printer
321+
val core_type : core_type ast_printer
319322
end
320323

321324
module type Conf = sig
322325
val config : Config.t
323326
end
324327

325-
module type Configured = S with type 'a printer = 'a configured
326-
module type Configurable = S with type 'a printer = 'a configurable
328+
module type Configured = S with type 'a ast_printer = 'a configured
329+
module type Configurable = 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

+30-12
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,46 @@ 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
6381
type 'a pp = Format.formatter -> 'a -> unit
64-
type 'a configurable = ?config:Config.t -> 'a pp
82+
type 'a configurable = ?config:Config.t -> ?printer:printer -> 'a pp
6583
type 'a configured = 'a pp
6684

6785
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
86+
type 'a ast_printer
87+
88+
val structure : structure ast_printer
89+
val structure_item : structure_item ast_printer
90+
val signature : signature ast_printer
91+
val signature_item : signature_item ast_printer
92+
val expression : expression ast_printer
93+
val pattern : pattern ast_printer
94+
val core_type : core_type ast_printer
7795
end
7896

7997
module type Conf = sig
8098
val config : Config.t
8199
end
82100

83-
module type Configured = S with type 'a printer = 'a configured
84-
module type Configurable = S with type 'a printer = 'a configurable
101+
module type Configured = S with type 'a ast_printer = 'a configured
102+
module type Configurable = S with type 'a ast_printer = 'a configurable
85103

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

0 commit comments

Comments
 (0)