@@ -332,135 +332,136 @@ let output_struct_sig loc s =
332
332
type enum_op =
333
333
| Enum_to_sexp
334
334
| Enum_of_sexp
335
- | Enum_get of prim * (label Loc .loc * int64 ) list
336
- | Enum_set of prim * (label Loc .loc * int64 ) list
337
- | Enum_print of (label Loc .loc * int64 ) list
338
- | Enum_parse of (label Loc .loc * int64 ) list
339
-
340
- let enum_print name =
341
- sprintf " %s_to_string" name.txt
342
-
343
- let enum_parse name =
344
- sprintf " string_to_%s" name.txt
345
-
346
- let enum_op_name name = function
347
- | Enum_to_sexp -> sprintf " sexp_of_%s" name.txt
348
- | Enum_of_sexp -> sprintf " %s_of_sexp" name.txt
349
- | Enum_get _ -> sprintf " int_to_%s" name.txt
350
- | Enum_set _ -> sprintf " %s_to_int" name.txt
351
- | Enum_print _ -> enum_print name
352
- | Enum_parse _ -> enum_parse name
353
-
354
- let declare_enum_expr name = function
335
+ | Enum_get
336
+ | Enum_set
337
+ | Enum_print
338
+ | Enum_parse
339
+
340
+ type cenum =
341
+ { name : string Loc .loc ;
342
+ fields : (string Loc .loc * int64 ) list ;
343
+ prim : prim ;
344
+ sexp : bool ;
345
+ }
346
+
347
+ let enum_op_name cenum =
348
+ let s = cenum.name.txt in
349
+ function
350
+ | Enum_to_sexp -> sprintf " sexp_of_%s" s
351
+ | Enum_of_sexp -> sprintf " %s_of_sexp" s
352
+ | Enum_get -> sprintf " int_to_%s" s
353
+ | Enum_set -> sprintf " %s_to_int" s
354
+ | Enum_print -> sprintf " %s_to_string" s
355
+ | Enum_parse -> sprintf " string_to_%s" s
356
+
357
+ let enum_pattern {prim; _} =
358
+ let pat_integer f suffix i =
359
+ Pat. constant (Pconst_integer (f i, suffix))
360
+ in
361
+ match prim with
362
+ | Char ->
363
+ (fun i -> Ast. pchar (Char. chr (Int64. to_int i)))
364
+ | (UInt8 | UInt16 ) -> pat_integer Int64. to_string None
365
+ | UInt32 -> pat_integer (fun i -> Int32. to_string (Int64. to_int32 i)) (Some 'l' )
366
+ | UInt64 -> pat_integer Int64. to_string (Some 'L' )
367
+
368
+ let enum_integer {prim; _} =
369
+ let expr_integer f suffix i =
370
+ Exp. constant (Pconst_integer (f i, suffix))
371
+ in
372
+ match prim with
373
+ | Char -> (fun i -> Ast. char (Char. chr (Int64. to_int i)))
374
+ | (UInt8 | UInt16 ) -> expr_integer Int64. to_string None
375
+ | UInt32 -> expr_integer (fun i -> Int32. to_string (Int64. to_int32 i)) (Some 'l' )
376
+ | UInt64 -> expr_integer Int64. to_string (Some 'L' )
377
+
378
+ let declare_enum_expr ({fields; _} as cenum ) = function
355
379
| Enum_to_sexp ->
356
- [% expr Sexplib.Sexp. Atom ([% e Ast. evar (enum_print name )] x) ]
380
+ [% expr Sexplib.Sexp. Atom ([% e Ast. evar (enum_op_name cenum Enum_print )] x) ]
357
381
| Enum_of_sexp ->
358
382
[% expr
359
383
match x with
360
384
| Sexplib.Sexp. List _ ->
361
385
raise (Sexplib.Pre_sexp. Of_sexp_error (Failure " expected Atom, got List" , x))
362
386
| Sexplib.Sexp. Atom v ->
363
- match [% e Ast. evar (enum_parse name )] v with
387
+ match [% e Ast. evar (enum_op_name cenum Enum_parse )] v with
364
388
| None ->
365
389
raise (Sexplib.Pre_sexp. Of_sexp_error (Failure " unable to parse enum string" , x))
366
390
| Some r -> r
367
391
]
368
- | Enum_get (prim , fields ) ->
369
- let pat_integer f suffix i =
370
- Pat. constant (Pconst_integer (f i, suffix))
371
- in
372
- let pattfn = match prim with
373
- | Char ->
374
- (fun i -> Ast. pchar (Char. chr (Int64. to_int i)))
375
- | (UInt8 | UInt16 ) -> pat_integer Int64. to_string None
376
- | UInt32 -> pat_integer (fun i -> Int32. to_string (Int64. to_int32 i)) (Some 'l' )
377
- | UInt64 -> pat_integer Int64. to_string (Some 'L' )
378
- in
392
+ | Enum_get ->
379
393
let getters = (List. map (fun ({txt = f ; _} ,i ) ->
380
- Exp. case (pattfn i) [% expr Some [% e Ast. constr f []]]
394
+ Exp. case (enum_pattern cenum i) [% expr Some [% e Ast. constr f []]]
381
395
) fields) @ [Exp. case [% pat? _] [% expr None ]]
382
396
in
383
397
Exp. match_ [% expr x] getters
384
- | Enum_set (prim , fields ) ->
385
- let expr_integer f suffix i =
386
- Exp. constant (Pconst_integer (f i, suffix))
387
- in
388
- let intfn = match prim with
389
- | Char -> (fun i -> Ast. char (Char. chr (Int64. to_int i)))
390
- | (UInt8 | UInt16 ) -> expr_integer Int64. to_string None
391
- | UInt32 -> expr_integer (fun i -> Int32. to_string (Int64. to_int32 i)) (Some 'l' )
392
- | UInt64 -> expr_integer Int64. to_string (Some 'L' )
393
- in
398
+ | Enum_set ->
394
399
let setters = List. map (fun ({txt = f ; _} ,i ) ->
395
- Exp. case (Ast. pconstr f [] ) (intfn i)
400
+ Exp. case (Ast. pconstr f [] ) (enum_integer cenum i)
396
401
) fields in
397
402
Exp. match_ [% expr x] setters
398
- | Enum_print fields ->
403
+ | Enum_print ->
399
404
let printers = List. map (fun ({txt = f ; _} ,_ ) ->
400
405
Exp. case (Ast. pconstr f [] ) (Ast. str f)
401
406
) fields in
402
407
Exp. match_ [% expr x] printers
403
- | Enum_parse fields ->
408
+ | Enum_parse ->
404
409
let parsers = List. map (fun ({txt = f ; _} ,_ ) ->
405
410
Exp. case (Ast. pstr f) [% expr Some [% e Ast. constr f []]]
406
411
) fields in
407
412
Exp. match_ [% expr x]
408
413
(parsers @ [Exp. case [% pat? _] [% expr None ]])
409
414
410
- let enum_ops_for loc fields width ~ sexp =
411
- let prim = match ty_of_string width with
412
- | None -> loc_err loc " enum: unknown width specifier %s " width
413
- | Some p -> p
414
- in
415
- let output_sexp_struct =
415
+ let enum_ops_for { sexp; _} =
416
+ Enum_get ::
417
+ Enum_set ::
418
+ Enum_print ::
419
+ Enum_parse ::
420
+ if sexp then
416
421
[ Enum_to_sexp
417
422
; Enum_of_sexp
418
423
]
419
- in
420
- (Enum_get (prim, fields)) ::
421
- (Enum_set (prim, fields)) ::
422
- (Enum_print fields) ::
423
- (Enum_parse fields) ::
424
- if sexp then output_sexp_struct else []
424
+ else
425
+ []
425
426
426
- let enum_type_decl name fields =
427
+ let enum_type_decl { name; fields; _} =
427
428
let decls = List. map (fun (f ,_ ) -> Type. constructor f) fields in
428
429
Type. mk ~kind: (Ptype_variant decls) name
429
430
430
- let output_enum loc name fields width ~ sexp =
431
- Str. type_ Recursive [enum_type_decl name fields ] ::
431
+ let output_enum cenum =
432
+ Str. type_ Recursive [enum_type_decl cenum ] ::
432
433
List. map
433
434
(fun op ->
434
435
[% stri
435
- let [@ ocaml.warning " -32" ] [% p Ast. pvar (enum_op_name name op)] =
436
- fun x -> [% e declare_enum_expr name op]
436
+ let [@ ocaml.warning " -32" ] [% p Ast. pvar (enum_op_name cenum op)] =
437
+ fun x -> [% e declare_enum_expr cenum op]
437
438
])
438
- (enum_ops_for loc fields width ~sexp )
439
+ (enum_ops_for cenum )
439
440
440
- let enum_op_type name =
441
- let cty = Ast. tconstr name [] in
442
- let oty prim = match prim with
441
+ let enum_op_type { name; prim; _} =
442
+ let cty = Ast. tconstr name.txt [] in
443
+ let oty = match prim with
443
444
| Char -> [% type : char ]
444
445
| (UInt8 |UInt16 ) -> [% type : int ]
445
446
| UInt32 -> [% type : int32 ]
446
447
| UInt64 -> [% type : int64 ]
447
448
in
448
449
function
449
- | Enum_get ( prim , _ ) -> [% type : [% t oty prim ] -> [% t cty] option ]
450
- | Enum_set ( prim , _ ) -> [% type : [% t cty] -> [% t oty prim ]]
451
- | Enum_print _ -> [% type : [% t cty] -> string ]
452
- | Enum_parse _ -> [% type : string -> [% t cty] option ]
450
+ | Enum_get -> [% type : [% t oty] -> [% t cty] option ]
451
+ | Enum_set -> [% type : [% t cty] -> [% t oty]]
452
+ | Enum_print -> [% type : [% t cty] -> string ]
453
+ | Enum_parse -> [% type : string -> [% t cty] option ]
453
454
| Enum_to_sexp -> [% type : [% t cty] -> Sexplib.Sexp. t]
454
455
| Enum_of_sexp -> [% type : Sexplib.Sexp. t -> [% t cty]]
455
456
456
- let output_enum_sig loc name fields width ~ sexp =
457
- Sig. type_ Recursive [enum_type_decl name fields ] ::
457
+ let output_enum_sig loc ( cenum :cenum ) =
458
+ Sig. type_ Recursive [enum_type_decl cenum ] ::
458
459
List. map
459
460
(fun op ->
460
- let name = enum_op_name name op in
461
- let typ = enum_op_type name op in
461
+ let name = enum_op_name cenum op in
462
+ let typ = enum_op_type cenum op in
462
463
Sig. value (Val. mk (Loc. mkloc name loc) typ))
463
- (enum_ops_for loc fields width ~sexp )
464
+ (enum_ops_for cenum )
464
465
465
466
let constr_enum = function
466
467
| {pcd_name = f ; pcd_args = Pcstr_tuple [] ; pcd_attributes = attrs ; _} ->
@@ -540,7 +541,15 @@ let cenum decl =
540
541
| (f , None) -> incr_n () ; (f, ! n)
541
542
| (f , Some i ) -> n := i; (f, i)
542
543
) fields in
543
- name, fields, width, sexp
544
+ let prim = match ty_of_string width with
545
+ | None -> loc_err loc " enum: unknown width specifier %s" width
546
+ | Some p -> p
547
+ in
548
+ { name;
549
+ fields;
550
+ prim;
551
+ sexp;
552
+ }
544
553
545
554
let signature_item' mapper = function
546
555
| {psig_desc =
@@ -550,8 +559,7 @@ let signature_item' mapper = function
550
559
| {psig_desc =
551
560
Psig_extension (({txt = " cenum" ; _}, PStr [{pstr_desc = Pstr_type (_, [decl]); _}]), _);
552
561
psig_loc = loc} ->
553
- let name, fields, width, sexp = cenum decl in
554
- output_enum_sig loc name fields width ~sexp
562
+ output_enum_sig loc (cenum decl)
555
563
| other ->
556
564
[default_mapper.signature_item mapper other]
557
565
@@ -565,9 +573,8 @@ let structure_item' mapper = function
565
573
output_struct loc (cstruct decl)
566
574
| {pstr_desc =
567
575
Pstr_extension (({txt = " cenum" ; _}, PStr [{pstr_desc = Pstr_type (_, [decl]); _}]), _);
568
- pstr_loc = loc} ->
569
- let name, fields, width, sexp = cenum decl in
570
- output_enum loc name fields width ~sexp
576
+ _ } ->
577
+ output_enum (cenum decl)
571
578
| other ->
572
579
[default_mapper.structure_item mapper other]
573
580
0 commit comments