Skip to content

Commit 3f54124

Browse files
committed
Separate ops building from code generation
1 parent 29c3882 commit 3f54124

File tree

1 file changed

+80
-81
lines changed

1 file changed

+80
-81
lines changed

ppx/ppx_cstruct.ml

Lines changed: 80 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -150,67 +150,51 @@ let op_name s op =
150150

151151
let op_pvar s op = Ast.pvar (op_name s op)
152152
let op_evar s op = Ast.evar (op_name s op)
153-
let op_val_typ loc s op ty =
154-
Sig.value (Val.mk (Loc.mkloc (op_name s op) loc) ty)
155153

156-
let output_get _loc s f =
157-
let m = mode_mod _loc s.endian in
154+
let get_expr loc s f =
155+
let m = mode_mod loc s.endian in
158156
let num x = Ast.int x in
159157
match f.ty with
160158
|Buffer (_, _) ->
161159
let len = width_of_field f in
162-
[%str
163-
let [%p op_pvar s (Op_get f)] =
164-
fun src -> Cstruct.sub src [%e num f.off] [%e num len]
165-
166-
let[@ocaml.warning "-32"] [%p op_pvar s (Op_copy f)] =
167-
fun src -> Cstruct.copy src [%e num f.off] [%e num len]
160+
[%expr
161+
fun src -> Cstruct.sub src [%e num f.off] [%e num len]
168162
]
169163
|Prim prim ->
170-
[%str
171-
let [%p op_pvar s (Op_get f)] = fun v ->
164+
[%expr
165+
fun v ->
172166
[%e match prim with
173167
|Char -> [%expr Cstruct.get_char v [%e num f.off]]
174168
|UInt8 -> [%expr Cstruct.get_uint8 v [%e num f.off]]
175169
|UInt16 -> [%expr [%e m "get_uint16"] v [%e num f.off]]
176170
|UInt32 -> [%expr [%e m "get_uint32"] v [%e num f.off]]
177171
|UInt64 -> [%expr [%e m "get_uint64"] v [%e num f.off]]]]
178172

179-
let output_get loc s f =
180-
(output_get loc s f) [@metaloc loc]
181-
182173
let type_of_int_field = function
183174
|Char -> [%type: char]
184175
|UInt8 -> [%type: Cstruct.uint8]
185176
|UInt16 -> [%type: Cstruct.uint16]
186177
|UInt32 -> [%type: Cstruct.uint32]
187178
|UInt64 -> [%type: Cstruct.uint64]
188179

189-
let output_set _loc s f =
190-
let m = mode_mod _loc s.endian in
180+
let set_expr loc s f =
181+
let m = mode_mod loc s.endian in
191182
let num x = Ast.int x in
192183
match f.ty with
193184
|Buffer (_,_) ->
194185
let len = width_of_field f in
195-
[%str
196-
let[@ocaml.warning "-32"] [%p op_pvar s (Op_set f)] = fun src srcoff dst ->
197-
Cstruct.blit_from_string src srcoff dst [%e num f.off] [%e num len]
198-
199-
let[@ocaml.warning "-32"] [%p op_pvar s (Op_blit f)] = fun src srcoff dst ->
200-
Cstruct.blit src srcoff dst [%e num f.off] [%e num len]]
186+
[%expr
187+
fun src srcoff dst ->
188+
Cstruct.blit_from_string src srcoff dst [%e num f.off] [%e num len]]
201189
|Prim prim ->
202-
[%str
203-
let[@ocaml.warning "-32"] [%p op_pvar s (Op_set f)] = fun v x ->
190+
[%expr fun v x ->
204191
[%e match prim with
205192
|Char -> [%expr Cstruct.set_char v [%e num f.off] x]
206193
|UInt8 -> [%expr Cstruct.set_uint8 v [%e num f.off] x]
207194
|UInt16 -> [%expr [%e m "set_uint16"] v [%e num f.off] x]
208195
|UInt32 -> [%expr [%e m "set_uint32"] v [%e num f.off] x]
209196
|UInt64 -> [%expr [%e m "set_uint64"] v [%e num f.off] x]]]
210197

211-
let output_set _loc s f =
212-
output_set _loc s f [@metaloc _loc]
213-
214198
let type_of_set f =
215199
match f.ty with
216200
|Buffer (_,_) ->
@@ -219,52 +203,84 @@ let type_of_set f =
219203
let retf = type_of_int_field prim in
220204
[%type: Cstruct.t -> [%t retf] -> unit]
221205

222-
let output_sizeof _loc s =
223-
[%stri
224-
let [%p op_pvar s Op_sizeof] = [%e Ast.int s.len]] [@metaloc _loc]
206+
let hexdump_expr s =
207+
[%expr fun v ->
208+
let buf = Buffer.create 128 in
209+
Buffer.add_string buf [%e Ast.str (s.name ^ " = {\n")];
210+
[%e op_evar s Op_hexdump_to_buffer] buf v;
211+
print_endline (Buffer.contents buf);
212+
print_endline "}"
213+
]
225214

226-
let output_hexdump _loc s =
215+
let hexdump_to_buffer_expr s =
227216
let hexdump =
228217
List.fold_left (fun a f ->
229218
let get_f = op_evar s (Op_get f) in
230219
[%expr
231-
[%e a]; Buffer.add_string _buf [%e Ast.str (" "^f.field^" = ")];
220+
[%e a]; Buffer.add_string buf [%e Ast.str (" "^f.field^" = ")];
232221
[%e match f.ty with
233222
|Prim Char ->
234-
[%expr Printf.bprintf _buf "%c\n" ([%e get_f] v)]
223+
[%expr Printf.bprintf buf "%c\n" ([%e get_f] v)]
235224
|Prim (UInt8|UInt16) ->
236-
[%expr Printf.bprintf _buf "0x%x\n" ([%e get_f] v)]
225+
[%expr Printf.bprintf buf "0x%x\n" ([%e get_f] v)]
237226
|Prim UInt32 ->
238-
[%expr Printf.bprintf _buf "0x%lx\n" ([%e get_f] v)]
227+
[%expr Printf.bprintf buf "0x%lx\n" ([%e get_f] v)]
239228
|Prim UInt64 ->
240-
[%expr Printf.bprintf _buf "0x%Lx\n" ([%e get_f] v)]
229+
[%expr Printf.bprintf buf "0x%Lx\n" ([%e get_f] v)]
241230
|Buffer (_,_) ->
242-
[%expr Printf.bprintf _buf "<buffer %s>"
231+
[%expr Printf.bprintf buf "<buffer %s>"
243232
[%e Ast.str (field_to_string f)];
244-
Cstruct.hexdump_to_buffer _buf ([%e get_f] v)]
233+
Cstruct.hexdump_to_buffer buf ([%e get_f] v)]
245234
]]
246235
) (Ast.unit ()) s.fields
247236
in
248-
[
249-
[%stri
250-
let [%p op_pvar s Op_hexdump_to_buffer] = fun _buf v ->
251-
[%e hexdump]];
252-
[%stri
253-
let[@ocaml.warning "-32"] [%p op_pvar s Op_hexdump] = fun v ->
254-
let _buf = Buffer.create 128 in
255-
Buffer.add_string _buf [%e Ast.str (s.name ^ " = {\n")];
256-
[%e op_evar s Op_hexdump_to_buffer] _buf v;
257-
print_endline (Buffer.contents _buf);
258-
print_endline "}"
259-
]
260-
] [@metaloc _loc]
237+
[%expr fun buf v -> [%e hexdump]]
238+
239+
let op_expr loc s = function
240+
| Op_sizeof -> Ast.int s.len
241+
| Op_hexdump -> hexdump_expr s
242+
| Op_hexdump_to_buffer -> hexdump_to_buffer_expr s
243+
| Op_get f -> get_expr loc s f
244+
| Op_set f -> set_expr loc s f
245+
| Op_copy f ->
246+
let len = width_of_field f in
247+
[%expr fun src -> Cstruct.copy src [%e Ast.int f.off] [%e Ast.int len] ]
248+
| Op_blit f ->
249+
let len = width_of_field f in
250+
[%expr fun src srcoff dst ->
251+
Cstruct.blit src srcoff dst [%e Ast.int f.off] [%e Ast.int len]]
261252

262-
let output_struct_one_endian _loc s =
263-
(* Generate functions of the form {get/set}_<struct>_<field> *)
264-
let expr = List.fold_left (fun a f ->
265-
a @ output_get _loc s f @ output_set _loc s f
266-
) [output_sizeof _loc s] s.fields
267-
in expr @ output_hexdump _loc s
253+
let ops_for s =
254+
let field_ops =
255+
List.concat (
256+
List.map (fun f ->
257+
let if_buffer x =
258+
match f.ty with
259+
|Buffer (_,_) -> [x]
260+
|Prim _ -> []
261+
in
262+
List.concat
263+
[ [Op_get f]
264+
; if_buffer (Op_copy f)
265+
; [Op_set f]
266+
; if_buffer (Op_blit f)
267+
]
268+
) s.fields
269+
)
270+
in
271+
( [Op_sizeof]
272+
@ field_ops
273+
@ [Op_hexdump_to_buffer;
274+
Op_hexdump;
275+
])
276+
277+
(** Generate functions of the form {get/set}_<struct>_<field> *)
278+
let output_struct_one_endian loc s =
279+
List.map
280+
(fun op ->
281+
[%stri let[@ocaml.warning "-32"] [%p op_pvar s op] =
282+
[%e op_expr loc s op]])
283+
(ops_for s)
268284

269285
let output_struct _loc s =
270286
match s.endian with
@@ -301,30 +317,13 @@ let op_typ = function
301317

302318
(** Generate signatures of the form {get/set}_<struct>_<field> *)
303319
let output_struct_sig loc s =
304-
let field_ops =
305-
List.concat (
306-
List.map (fun f ->
307-
let if_buffer x =
308-
match f.ty with
309-
|Buffer (_,_) -> [x]
310-
|Prim _ -> []
311-
in
312-
List.concat
313-
[ [Op_get f]
314-
; if_buffer (Op_copy f)
315-
; [Op_set f]
316-
; if_buffer (Op_blit f)
317-
]
318-
) s.fields
319-
)
320-
in
321320
List.map
322-
(fun op -> op_val_typ loc s op (op_typ op))
323-
( [Op_sizeof]
324-
@ field_ops
325-
@ [Op_hexdump_to_buffer;
326-
Op_hexdump;
327-
])
321+
(fun op ->
322+
Sig.value
323+
(Val.mk
324+
(Loc.mkloc (op_name s op) loc)
325+
(op_typ op)))
326+
(ops_for s)
328327

329328
let output_enum _loc name fields width ~sexp =
330329
let intfn,pattfn = match ty_of_string width with

0 commit comments

Comments
 (0)