Source file Serialize.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
open AST
open Printf
type buffer = Buffer.t
type 'a printer = buffer -> 'a -> unit
let addb buf s = Buffer.add_string buf s
let with_buf f =
let b = Buffer.create 64 in
let () = f b in
Buffer.contents b
let pp_list pp_elt buf =
let pp_elt_with_sep elt =
addb buf "; ";
pp_elt buf elt
in
function
| [] -> addb buf "[]"
| h :: t ->
addb buf "[";
pp_elt buf h;
List.iter pp_elt_with_sep t;
addb buf "]"
let pp_option pp_some buf = function
| None -> addb buf "None"
| Some elt -> bprintf buf "Some (%a)" pp_some elt
let pp_pair pp_left pp_right f (left, right) =
bprintf f "(%a, %a)" pp_left left pp_right right
let pp_pair_list pp_left pp_right = pp_list (pp_pair pp_left pp_right)
let pp_string f = bprintf f "%S"
let pp_id_assoc pp_elt = pp_pair_list pp_string pp_elt
let pp_annotated f buf { desc; _ } = bprintf buf "annot (%a)" f desc
let pp_binop : binop -> string = function
| AND -> "AND"
| BAND -> "BAND"
| BEQ -> "BEQ"
| BOR -> "BOR"
| DIV -> "DIV"
| DIVRM -> "DIVRM"
| EOR -> "EOR"
| EQ_OP -> "EQ_OP"
| GT -> "GT"
| GEQ -> "GEQ"
| IMPL -> "IMPL"
| LT -> "LT"
| LEQ -> "LEQ"
| MOD -> "MOD"
| MINUS -> "MINUS"
| MUL -> "MUL"
| NEQ -> "NEQ"
| OR -> "OR"
| PLUS -> "PLUS"
| RDIV -> "RDIV"
| SHL -> "SHL"
| SHR -> "SHR"
| POW -> "POW"
| BV_CONCAT -> "BV_CONCAT"
let pp_unop = function BNOT -> "BNOT" | NOT -> "NOT" | NEG -> "NEG"
let pp_literal f = function
| L_Int i -> bprintf f "L_Int (Z.of_string \"%a\")" Z.bprint i
| L_Bool b -> bprintf f "L_Bool %B" b
| L_Real r -> bprintf f "L_Real (Q.of_string \"%a\")" Q.bprint r
| L_BitVector bv ->
bprintf f "L_BitVector (Bitvector.of_string %S)" (Bitvector.to_string bv)
| L_String s -> bprintf f "L_String %S" s
| L_Label s -> bprintf f "L_Label %S" s
let subprogram_type_to_string = function
| ST_Function -> "ST_Function"
| ST_Procedure -> "ST_Procedure"
| ST_Setter -> "ST_Setter"
| ST_Getter -> "ST_Getter"
| ST_EmptyGetter -> "ST_EmptyGetter"
| ST_EmptySetter -> "ST_EmptySetter"
let pp_subprogram_type f st = addb f (subprogram_type_to_string st)
let rec pp_expr =
let pp_desc f = function
| E_Literal v -> bprintf f "E_Literal (%a)" pp_literal v
| E_Var x -> bprintf f "E_Var %S" x
| E_ATC (e, t) -> bprintf f "E_ATC (%a, %a)" pp_expr e pp_ty t
| E_Binop (op, e1, e2) ->
bprintf f "E_Binop (%s, %a, %a)" (pp_binop op) pp_expr e1 pp_expr e2
| E_Unop (op, e) -> bprintf f "E_Unop (%s, %a)" (pp_unop op) pp_expr e
| E_Call { name; args; params; call_type } ->
bprintf f "E_Call {name=%S; args=%a; params=%a; call_type=%a}" name
pp_expr_list args pp_expr_list params pp_subprogram_type call_type
| E_Slice (e, args) ->
bprintf f "E_Slice (%a, %a)" pp_expr e pp_slice_list args
| E_Cond (e1, e2, e3) ->
bprintf f "E_Cond (%a, %a, %a)" pp_expr e1 pp_expr e2 pp_expr e3
| E_GetArray (e1, e2) ->
bprintf f "E_GetArray (%a, %a)" pp_expr e1 pp_expr e2
| E_GetEnumArray (e1, e2) ->
bprintf f "E_GetEnumArray (%a, %a)" pp_expr e1 pp_expr e2
| E_GetField (e, x) -> bprintf f "E_GetField (%a, %S)" pp_expr e x
| E_GetFields (e, x) ->
bprintf f "E_GetFields (%a, %a)" pp_expr e (pp_list pp_string) x
| E_GetItem (e, i) -> bprintf f "E_GetItem (%a, %d)" pp_expr e i
| E_Record (ty, li) ->
bprintf f "E_Record (%a, %a)" pp_ty ty (pp_id_assoc pp_expr) li
| E_Tuple es ->
addb f "E_Tuple ";
pp_expr_list f es
| E_Array { length; value } ->
bprintf f "E_Array { length=(%a); value=(%a) }" pp_expr length pp_expr
value
| E_EnumArray { enum; labels; value } ->
bprintf f "E_EnumArray { enum=%S; labels=(%a); value=(%a) }" enum
(pp_list pp_string) labels pp_expr value
| E_Arbitrary ty -> bprintf f "E_Arbitrary (%a)" pp_ty ty
| E_Pattern (e, p) -> bprintf f "E_Pattern (%a, %a)" pp_expr e pp_pattern p
in
fun f e -> pp_annotated pp_desc f e
and pp_expr_list f = pp_list pp_expr f
and pp_slice_list f = pp_list pp_slice f
and pp_slice f = function
| Slice_Single e -> bprintf f "Slice_Single (%a)" pp_expr e
| Slice_Range (e1, e2) ->
bprintf f "Slice_Range (%a, %a)" pp_expr e1 pp_expr e2
| Slice_Length (e1, e2) ->
bprintf f "Slice_Length (%a, %a)" pp_expr e1 pp_expr e2
| Slice_Star (e1, e2) -> bprintf f "Slice_Star (%a, %a)" pp_expr e1 pp_expr e2
and pp_pattern =
let pp_desc f = function
| Pattern_All -> addb f "Pattern_All"
| Pattern_Any li ->
addb f "Pattern_Any ";
pp_list pp_pattern f li
| Pattern_Geq e -> bprintf f "Pattern_Geq (%a)" pp_expr e
| Pattern_Leq e -> bprintf f "Pattern_Leq (%a)" pp_expr e
| Pattern_Mask m ->
bprintf f "Pattern_Mask (Bitvector.mask_of_string \"%S\")"
(Bitvector.mask_to_canonical_string m)
| Pattern_Not p -> bprintf f "Pattern_Not (%a)" pp_pattern p
| Pattern_Range (e1, e2) ->
bprintf f "Pattern_Range (%a, %a)" pp_expr e1 pp_expr e2
| Pattern_Single e -> bprintf f "Pattern_Single (%a)" pp_expr e
| Pattern_Tuple li ->
addb f "Pattern_Tuple ";
pp_list pp_pattern f li
in
fun f p -> pp_annotated pp_desc f p
and pp_ty =
let pp_desc f = function
| T_Int cs -> bprintf f "T_Int (%a)" pp_int_constraints cs
| T_Real -> addb f "T_Real"
| T_String -> addb f "T_String"
| T_Bool -> addb f "T_Bool"
| T_Bits (bits_constraint, fields) ->
bprintf f "T_Bits (%a, %a)" pp_expr bits_constraint pp_bitfields fields
| T_Enum enum_type_desc ->
addb f "T_Enum ";
pp_list pp_string f enum_type_desc
| T_Tuple li ->
addb f "T_Tuple ";
pp_list pp_ty f li
| T_Array (length, elt_type) ->
bprintf f "T_Array (%a, %a)" pp_array_length length pp_ty elt_type
| T_Record li ->
addb f "T_Record ";
pp_id_assoc pp_ty f li
| T_Exception li ->
addb f "T_Exception ";
pp_id_assoc pp_ty f li
| T_Named identifier -> bprintf f "T_Named %S" identifier
in
fun f s -> pp_annotated pp_desc f s
and pp_array_length f = function
| ArrayLength_Expr e -> bprintf f "ArrayLength_Expr (%a)" pp_expr e
| ArrayLength_Enum (enum, labels) ->
bprintf f "ArrayLength_Enum (%s, %a)" enum (pp_list pp_string) labels
and pp_bitfield f = function
| BitField_Simple (name, slices) ->
bprintf f "BitField_Simple (%S, %a)" name pp_slice_list slices
| BitField_Nested (name, slices, bitfields) ->
bprintf f "BitField_Nested (%S, %a, %a)" name pp_slice_list slices
pp_bitfields bitfields
| BitField_Type (name, slices, ty) ->
bprintf f "BitField_Type (%S, %a, %a)" name pp_slice_list slices pp_ty ty
and pp_bitfields f bitfields = pp_list pp_bitfield f bitfields
and pp_int_constraint f = function
| Constraint_Exact e -> bprintf f "Constraint_Exact (%a)" pp_expr e
| Constraint_Range (bot, top) ->
bprintf f "Constraint_Range (%a, %a)" pp_expr bot pp_expr top
and pp_int_constraints f = function
| UnConstrained -> addb f "UnConstrained"
| WellConstrained cs ->
addb f "WellConstrained ";
pp_list pp_int_constraint f cs
| PendingConstrained -> addb f "PendingConstrained"
| Parameterized (i, x) -> bprintf f "Parameterized (%d, %S)" i x
let rec pp_lexpr =
let pp_desc f = function
| LE_Var x -> bprintf f "LE_Var %S" x
| LE_Slice (le, args) ->
bprintf f "LE_Slice (%a, %a)" pp_lexpr le pp_slice_list args
| LE_SetArray (le, e) ->
bprintf f "LE_SetArray (%a, %a)" pp_lexpr le pp_expr e
| LE_SetEnumArray (le, e) ->
bprintf f "LE_SetEnumArray (%a, %a)" pp_lexpr le pp_expr e
| LE_SetField (le, x) -> bprintf f "LE_SetField (%a, %S)" pp_lexpr le x
| LE_SetFields (le, x, _) ->
bprintf f "LE_SetFields (%a, %a)" pp_lexpr le (pp_list pp_string) x
| LE_Discard -> addb f "LE_Discard"
| LE_Destructuring les ->
addb f "LE_Destructuring ";
pp_list pp_lexpr f les
in
fun f le -> pp_annotated pp_desc f le
let pp_local_decl_keyboard f k =
pp_string f
(match k with
| LDK_Var -> "LDK_Var"
| LDK_Constant -> "LDK_Constant"
| LDK_Let -> "LDK_Let")
let pp_local_decl_item f = function
| LDI_Var s -> bprintf f "LDI_Var %S" s
| LDI_Tuple ldis -> bprintf f "LDI_Tuple %a" (pp_list pp_string) ldis
let rec pp_stmt =
let pp_desc f = function
| S_Pass -> addb f "SPass"
| S_Seq (s1, s2) -> bprintf f "S_Seq (%a, %a)" pp_stmt s1 pp_stmt s2
| S_Assign (le, e) -> bprintf f "S_Assign (%a, %a)" pp_lexpr le pp_expr e
| S_Call { name; args; params; call_type } ->
bprintf f "S_Call {name=%S; args=%a; params=%a; call_type=%a}" name
pp_expr_list args pp_expr_list params pp_subprogram_type call_type
| S_Cond (e, s1, s2) ->
bprintf f "S_Cond (%a, %a, %a)" pp_expr e pp_stmt s1 pp_stmt s2
| S_Return e -> bprintf f "S_Return (%a)" (pp_option pp_expr) e
| S_Assert e -> bprintf f "S_Assert (%a)" pp_expr e
| S_While (e, limit, s) ->
bprintf f "S_While(%a, %a, %a)" pp_expr e (pp_option pp_expr) limit
pp_stmt s
| S_Repeat (s, e, limit) ->
bprintf f "S_Repeat(%a, %a, %a)" pp_stmt s pp_expr e (pp_option pp_expr)
limit
| S_For { index_name; start_e; end_e; body; dir; limit } ->
bprintf f
"S_For { index_name=%S; start=%a; dir=%s; end_=%a; body=%a; limit=%a \
}"
index_name pp_expr start_e
(match dir with Up -> "Up" | Down -> "Down")
pp_expr end_e pp_stmt body (pp_option pp_expr) limit
| S_Decl (ldk, ldi, ty_opt, e_opt) ->
bprintf f "S_Decl (%a, %a, %a, %a)" pp_local_decl_keyboard ldk
pp_local_decl_item ldi (pp_option pp_ty) ty_opt (pp_option pp_expr)
e_opt
| S_Throw opt ->
bprintf f "S_Throw (%a)"
(pp_option (pp_pair pp_expr (pp_option pp_ty)))
opt
| S_Try (s, catchers, otherwise) ->
bprintf f "S_Try (%a, %a, %a)" pp_stmt s (pp_list pp_catcher) catchers
(pp_option pp_stmt) otherwise
| S_Print { args; newline; debug } ->
bprintf f "S_Print { args = %a; newline = %B; debug = %B }"
(pp_list pp_expr) args newline debug
| S_Unreachable -> addb f "S_Unreachable"
| S_Pragma (name, exprs) ->
bprintf f "S_Pragma (%S, %a)" name (pp_list pp_expr) exprs
in
fun f s -> pp_annotated pp_desc f s
and pp_catcher f (name, ty, s) =
bprintf f "(%a, %a, %a)" (pp_option pp_string) name pp_ty ty pp_stmt s
let pp_gdk f gdk =
addb f
@@
match gdk with
| GDK_Config -> "GDK_Config"
| GDK_Constant -> "GDK_Constant"
| GDK_Let -> "GDK_Let"
| GDK_Var -> "GDK_Var"
let pp_body f = function
| SB_ASL s -> bprintf f "SB_ASL (%a)" pp_stmt s
| SB_Primitive b -> bprintf f "SB_Primitive %B" b
let pp_decl f d =
match d.desc with
| D_Func { name; args; body; return_type; parameters; subprogram_type } ->
bprintf f
"D_Func { name=%S; args=%a; body=%a; return_type=%a; parameters=%a; \
subprogram_type=%a }"
name (pp_id_assoc pp_ty) args pp_body body (pp_option pp_ty) return_type
(pp_list (pp_pair pp_string (pp_option pp_ty)))
parameters pp_subprogram_type subprogram_type
| D_GlobalStorage { name; keyword; ty; initial_value } ->
bprintf f "D_GlobalConst { name=%S; keyword=%a; ty=%a; initial_value=%a}"
name pp_gdk keyword (pp_option pp_ty) ty (pp_option pp_expr)
initial_value
| D_TypeDecl (name, type_desc, subty_opt) ->
bprintf f "D_TypeDecl (%S, %a, %a)" name pp_ty type_desc
(pp_option (pp_pair pp_string (pp_id_assoc pp_ty)))
subty_opt
| D_Pragma (name, exprs) ->
bprintf f "D_Pragma (%S, %a)" name (pp_list pp_expr) exprs
let pp_t f ast =
addb f "let open AST in let annot = ASTUtils.add_dummy_pos in ";
pp_list pp_decl f ast
let t_to_string ast = with_buf @@ fun b -> pp_t b ast