Skip to content

Commit

Permalink
Add sexp_of cenum attribute, use sexplib0
Browse files Browse the repository at this point in the history
The sexp_of_* functions now return Sexplib0.Sexp.t instead of
Sexplib.Sexp.t. The cenum attribute [@@sexp_of] is like [@@sexp] except
it only produces the sexp_of* function. This allows for generating
sexp_of converters without depending on the full sexplib library.
  • Loading branch information
reynir committed Sep 9, 2024
1 parent 21aceac commit 8f95106
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
24 changes: 15 additions & 9 deletions ppx/ppx_cstruct.ml
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ type cenum =
{ name : string Loc.t;
fields : (string Loc.t * int64) list;
prim : prim;
sexp : bool;
sexp : [ `None | `Sexp_of | `Sexp ];
}

let enum_op_name cenum =
Expand Down Expand Up @@ -429,7 +429,7 @@ let enum_integer ~loc {prim; _} =

let declare_enum_expr ~loc ({fields; _} as cenum) = function
| Enum_to_sexp ->
[%expr fun x -> Sexplib.Sexp.Atom ([%e Ast.evar ~loc (enum_op_name cenum Enum_print)] x) ]
[%expr fun x -> Sexplib0.Sexp.Atom ([%e Ast.evar ~loc (enum_op_name cenum Enum_print)] x) ]
| Enum_of_sexp ->
[%expr
fun x ->
Expand Down Expand Up @@ -474,12 +474,15 @@ let enum_ops_for {sexp; _} =
Enum_compare ::
Enum_print ::
Enum_parse ::
if sexp then
match sexp with
| `None -> []
| `Sexp_of ->
[ Enum_to_sexp ]
| `Sexp ->

[ Enum_to_sexp
; Enum_of_sexp
]
else
[]

let enum_type_decl {name; fields; _} =
let decls = List.map (fun (f,_) -> Type.constructor f) fields in
Expand Down Expand Up @@ -508,7 +511,7 @@ let enum_op_type ~loc {name; prim; _} =
| Enum_set -> [%type: [%t cty] -> [%t oty]]
| Enum_print -> [%type: [%t cty] -> string]
| Enum_parse -> [%type: string -> [%t cty] option]
| Enum_to_sexp -> [%type: [%t cty] -> Sexplib.Sexp.t]
| Enum_to_sexp -> [%type: [%t cty] -> Sexplib0.Sexp.t]
| Enum_of_sexp -> [%type: Sexplib.Sexp.t -> [%t cty]]
| Enum_compare -> [%type: [%t cty] -> [%t cty] -> int]

Expand Down Expand Up @@ -598,11 +601,14 @@ let cenum decl =
in
let width, sexp =
match attrs with
| ({attr_name = {txt = width; _};attr_payload= PStr [];_})
| ({attr_name = {txt = width; _};attr_payload= PStr [];_})
:: ({attr_name = {txt = "sexp"; _};attr_payload = PStr []; _}) :: [] ->
width, true
width, `Sexp
| ({attr_name = {txt = width; _};attr_payload= PStr [];_})
:: ({attr_name = {txt = "sexp_of"; _};attr_payload = PStr []; _}) :: [] ->
width, `Sexp_of
| ({attr_name = {txt = width; _};attr_payload= PStr [];_}) :: [] ->
width, false
width, `None
| _ ->
loc_err loc "invalid cenum attributes"
in
Expand Down
11 changes: 11 additions & 0 deletions ppx_test/with-sexp-of/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(executable
(name ppx_cstruct_and_sexp_of)
(preprocess
(pps ppx_cstruct ppx_sexp_conv -- -no-check))
(libraries cstruct sexplib0 cstruct-sexp))

(rule
(alias runtest)
(package ppx_cstruct)
(action
(run ./ppx_cstruct_and_sexp_of.exe)))
6 changes: 6 additions & 0 deletions ppx_test/with-sexp-of/ppx_cstruct_and_sexp_of.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(* inspect output with [dune describe pp ppx_test/with-sexp-of/ppx_cstruct_and_sexp_of.ml] *)
[%%cenum
type enum =
| One [@id 1]
| Three [@id 3]
[@@uint8_t][@@sexp_of]]

0 comments on commit 8f95106

Please sign in to comment.