Source file pp_ast.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
open Import
module Config = struct
type loc_mode = [ `Short | `Full ]
type t = { show_attrs : bool; show_locs : bool; loc_mode : loc_mode }
module Default = struct
let show_attrs = false
let show_locs = false
let loc_mode = `Short
end
let default =
let open Default in
{ show_attrs; show_locs; loc_mode }
let make ?(show_attrs = Default.show_attrs) ?(show_locs = Default.show_locs)
?(loc_mode = Default.loc_mode) () =
{ show_attrs; show_locs; loc_mode }
end
let cnum (pos : Lexing.position) = pos.pos_cnum - pos.pos_bol
type simple_val =
| Unit
| Int of int
| String of string
| Bool of bool
| Char of char
| Array of simple_val list
| Float of float
| Int32 of int32
| Int64 of int64
| Nativeint of nativeint
| Record of (string * simple_val) list
| Constr of string * simple_val list
| Tuple of simple_val list
| List of simple_val list
| Special of string
let pp_collection ~pp_elm ~open_ ~close ~sep fmt l =
match l with
| [] -> Format.fprintf fmt "%s%s" open_ close
| hd :: tl ->
Format.fprintf fmt "@[<hv>%s %a@," open_ pp_elm hd;
List.iter tl ~f:(fun sv -> Format.fprintf fmt "%s %a@," sep pp_elm sv);
Format.fprintf fmt "%s@]" close
let rec pp_simple_val fmt simple_val =
match simple_val with
| Unit -> Format.fprintf fmt "()"
| Int i -> Format.fprintf fmt "%i" i
| String s -> Format.fprintf fmt "%S" s
| Special s -> Format.fprintf fmt "%s" s
| Bool b -> Format.fprintf fmt "%B" b
| Char c -> Format.fprintf fmt "%c" c
| Float f -> Format.fprintf fmt "%f" f
| Int32 i32 -> Format.fprintf fmt "%li" i32
| Int64 i64 -> Format.fprintf fmt "%Li" i64
| Nativeint ni -> Format.fprintf fmt "%ni" ni
| Array l ->
pp_collection ~pp_elm:pp_simple_val ~open_:"[|" ~close:"|]" ~sep:";" fmt l
| Tuple l ->
pp_collection ~pp_elm:pp_simple_val ~open_:"(" ~close:")" ~sep:"," fmt l
| List l ->
pp_collection ~pp_elm:pp_simple_val ~open_:"[" ~close:"]" ~sep:";" fmt l
| Record fields ->
pp_collection ~pp_elm:pp_field ~open_:"{" ~close:"}" ~sep:";" fmt fields
| Constr (cname, []) -> Format.fprintf fmt "%s" cname
| Constr (cname, [ (Constr (_, _ :: _) as x) ]) ->
Format.fprintf fmt "@[<hv 2>%s@ (%a)@]" cname pp_simple_val x
| Constr (cname, [ x ]) ->
Format.fprintf fmt "@[<hv 2>%s@ %a@]" cname pp_simple_val x
| Constr (cname, l) ->
Format.fprintf fmt "@[<hv 2>%s@ %a@]" cname pp_simple_val (Tuple l)
and pp_field fmt (fname, simple_val) =
Format.fprintf fmt "@[<hv 2>%s =@ %a@]" fname pp_simple_val simple_val
class lift_simple_val =
object (self)
inherit [simple_val] Ast_traverse.lift as super
val mutable config = Config.default
method set_config new_config = config <- new_config
method get_config () = config
method unit () = Unit
method int i = Int i
method string s = String s
method bool b = Bool b
method char c = Char c
method float f = Float f
method int32 i32 = Int32 i32
method int64 i64 = Int64 i64
method nativeint ni = Nativeint ni
method! list lift_a list = List (List.map ~f:lift_a list)
method tuple res_list = Tuple res_list
method record fields = Record fields
method constr ctr res_list = Constr (ctr, res_list)
method array lift_a array =
Array (Array.map ~f:lift_a array |> Array.to_list)
method other _a = Special "__"
method! location_stack _ls = Special "__lstack"
method! position pos =
match (config.Config.show_locs, config.Config.loc_mode) with
| true, `Full -> super#position pos
| _, _ -> Special "__pos"
method! loc lift_a a_loc =
match config.Config.show_locs with
| true -> super#loc lift_a a_loc
| false -> lift_a a_loc.txt
method! location loc =
match (config.Config.show_locs, config.Config.loc_mode) with
| false, _ -> Special "__loc"
| true, `Full -> super#location loc
| true, `Short ->
let begin_line = loc.loc_start.pos_lnum in
let begin_char = cnum loc.loc_start in
let end_line = loc.loc_end.pos_lnum in
let end_char = cnum loc.loc_end in
let repr =
if Int.equal begin_line end_line then
Format.sprintf "l%ic%i..%i" begin_line begin_char end_char
else
Format.sprintf "l%ic%i..l%ic%i" begin_line begin_char end_line
end_char
in
let with_ghost = if loc.loc_ghost then repr ^ "(g)" else repr in
Special with_ghost
method! attributes attrs =
match config.Config.show_attrs with
| false -> Special "__attrs"
| true -> super#attributes attrs
method lift_record_with_desc
: 'record 'desc.
lift_desc:('desc -> simple_val) ->
lift_record:('record -> simple_val) ->
desc:'desc ->
attrs:attributes ->
'record ->
simple_val =
fun ~lift_desc ~lift_record ~desc ~attrs x ->
match (config.show_locs, config.show_attrs, attrs) with
| false, false, _ | false, true, [] -> lift_desc desc
| _, true, _ | true, _, _ -> lift_record x
method! core_type ct =
self#lift_record_with_desc ~lift_desc:self#core_type_desc
~lift_record:super#core_type ~desc:ct.ptyp_desc
~attrs:ct.ptyp_attributes ct
method! row_field rf =
self#lift_record_with_desc ~lift_desc:self#row_field_desc
~lift_record:super#row_field ~desc:rf.prf_desc ~attrs:rf.prf_attributes
rf
method! object_field obf =
self#lift_record_with_desc ~lift_desc:self#object_field_desc
~lift_record:super#object_field ~desc:obf.pof_desc
~attrs:obf.pof_attributes obf
method! pattern pat =
self#lift_record_with_desc ~lift_desc:self#pattern_desc
~lift_record:super#pattern ~desc:pat.ppat_desc
~attrs:pat.ppat_attributes pat
method! expression exp =
self#lift_record_with_desc ~lift_desc:self#expression_desc
~lift_record:super#expression ~desc:exp.pexp_desc
~attrs:exp.pexp_attributes exp
method! class_type cty =
self#lift_record_with_desc ~lift_desc:self#class_type_desc
~lift_record:super#class_type ~desc:cty.pcty_desc
~attrs:cty.pcty_attributes cty
method! class_type_field ctf =
self#lift_record_with_desc ~lift_desc:self#class_type_field_desc
~lift_record:super#class_type_field ~desc:ctf.pctf_desc
~attrs:ctf.pctf_attributes ctf
method! class_expr cl =
self#lift_record_with_desc ~lift_desc:self#class_expr_desc
~lift_record:super#class_expr ~desc:cl.pcl_desc ~attrs:cl.pcl_attributes
cl
method! class_field cf =
self#lift_record_with_desc ~lift_desc:self#class_field_desc
~lift_record:super#class_field ~desc:cf.pcf_desc
~attrs:cf.pcf_attributes cf
method! module_type mty =
self#lift_record_with_desc ~lift_desc:self#module_type_desc
~lift_record:super#module_type ~desc:mty.pmty_desc
~attrs:mty.pmty_attributes mty
method! module_expr mod_ =
self#lift_record_with_desc ~lift_desc:self#module_expr_desc
~lift_record:super#module_expr ~desc:mod_.pmod_desc
~attrs:mod_.pmod_attributes mod_
method! structure_item stri = self#structure_item_desc stri.pstr_desc
method! signature_item sigi = self#signature_item_desc sigi.psig_desc
method! structure str =
match config.show_attrs with
| true -> super#structure str
| false ->
List.filter
~f:(function
| { pstr_desc = Pstr_attribute _; _ } -> false | _ -> true)
str
|> super#structure
method! signature sig_ =
match config.show_attrs with
| true -> super#signature sig_
| false ->
List.filter
~f:(function
| { psig_desc = Psig_attribute _; _ } -> false | _ -> true)
sig_
|> super#signature
method! class_structure cstr =
match config.show_attrs with
| true -> super#class_structure cstr
| false ->
let pcstr_fields =
List.filter
~f:(function
| { pcf_desc = Pcf_attribute _; _ } -> false | _ -> true)
cstr.pcstr_fields
in
super#class_structure { cstr with pcstr_fields }
method! class_signature csig =
match config.show_attrs with
| true -> super#class_signature csig
| false ->
let pcsig_fields =
List.filter
~f:(function
| { pctf_desc = Pctf_attribute _; _ } -> false | _ -> true)
csig.pcsig_fields
in
super#class_signature { csig with pcsig_fields }
method! directive_argument dira =
self#directive_argument_desc dira.pdira_desc
method! rec_flag rec_flag =
match rec_flag with
| Nonrecursive -> Constr ("Nonrecursive", [])
| Recursive -> Constr ("Recursive", [])
method! direction_flag direction_flag =
match direction_flag with
| Upto -> Constr ("Upto", [])
| Downto -> Constr ("Downto", [])
method! private_flag private_flag =
match private_flag with
| Private -> Constr ("Private", [])
| Public -> Constr ("Public", [])
method! mutable_flag mutable_flag =
match mutable_flag with
| Mutable -> Constr ("Mutable", [])
| Immutable -> Constr ("Immutable", [])
method! virtual_flag virtual_flag =
match virtual_flag with
| Virtual -> Constr ("Virtual", [])
| Concrete -> Constr ("Concrete", [])
method! override_flag override_flag =
match override_flag with
| Override -> Constr ("Override", [])
| Fresh -> Constr ("Fresh", [])
method! closed_flag closed_flag =
match closed_flag with
| Closed -> Constr ("Closed", [])
| Open -> Constr ("Open", [])
method! variance variance =
match variance with
| Covariant -> Constr ("Covariant", [])
| Contravariant -> Constr ("Contravariant", [])
| NoVariance -> Constr ("NoVariance", [])
method! injectivity injectivity =
match injectivity with
| Injective -> Constr ("Injective", [])
| NoInjectivity -> Constr ("NoInjectivity", [])
end
type 'a pp = Format.formatter -> 'a -> unit
type 'a configurable = ?config:Config.t -> 'a pp
type 'a configured = 'a pp
module type S = sig
type 'a printer
val structure : structure printer
val structure_item : structure_item printer
val signature : signature printer
val signature_item : signature_item printer
val expression : expression printer
val pattern : pattern printer
val core_type : core_type printer
end
module type Conf = sig
val config : Config.t
end
module type Configured = S with type 'a printer = 'a configured
module type Configurable = S with type 'a printer = 'a configurable
module Make (Conf : Conf) : Configured = struct
type 'a printer = 'a configured
let lsv =
let lift_simple_val = new lift_simple_val in
lift_simple_val#set_config Conf.config;
lift_simple_val
let structure fmt str = pp_simple_val fmt (lsv#structure str)
let structure_item fmt str = pp_simple_val fmt (lsv#structure_item str)
let signature fmt str = pp_simple_val fmt (lsv#signature str)
let signature_item fmt str = pp_simple_val fmt (lsv#signature_item str)
let expression fmt str = pp_simple_val fmt (lsv#expression str)
let pattern fmt str = pp_simple_val fmt (lsv#pattern str)
let core_type fmt str = pp_simple_val fmt (lsv#core_type str)
end
let make config =
(module Make (struct
let config = config
end) : Configured)
module Default = Make (struct
let config = Config.default
end)
type 'a printer = 'a configurable
let lift_simple_val = new lift_simple_val
let with_config ~config ~f =
let old_config = lift_simple_val#get_config () in
lift_simple_val#set_config config;
let res = f () in
lift_simple_val#set_config old_config;
res
let pp_with_config (type a) (lifter : a -> simple_val)
?(config = Config.default) fmt (x : a) =
with_config ~config ~f:(fun () -> pp_simple_val fmt (lifter x))
let structure = pp_with_config lift_simple_val#structure
let structure_item = pp_with_config lift_simple_val#structure_item
let signature = pp_with_config lift_simple_val#signature
let signature_item = pp_with_config lift_simple_val#signature_item
let expression = pp_with_config lift_simple_val#expression
let pattern = pp_with_config lift_simple_val#pattern
let core_type = pp_with_config lift_simple_val#core_type