Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add a `sexp` optional decorator to `cenum` to output the values as s-…

…expressions.

This is compatible with the `sexplib` convention.  The syntax is;

```
cenum foo64 {
  ONE64;
  TWO64;
  THREE64
} as uint64_t(sexp)
```

And `sexp_of_foo64` and `foo64_of_sexp` functions will also be available.
The representation of the Sexp is the string representation of the enum.

Closes #20
  • Loading branch information...
commit f228ca5e677c92cd38df016169aa34956768a024 1 parent 758ea71
@avsm authored
View
18 CHANGES
@@ -1,4 +1,20 @@
-1.1.0 (2014-02-19)
+1.2.0 (2014-06-06):
+
+Add a `sexp` optional decorator to `cenum` to output the values as s-expressions.
+This is compatible with the `sexplib` convention. The syntax is;
+
+```
+cenum foo64 {
+ ONE64;
+ TWO64;
+ THREE64
+} as uint64_t(sexp)
+```
+
+And `sexp_of_foo64` and `foo64_of_sexp` functions will also be available.
+The representation of the Sexp is the string representation of the enum.
+
+1.1.0 (2014-02-19):
* Improve bounds checks on sub, shift, set_len, add_len.
* Add `to_bigarray` to convert back into a Bigarray slice.
View
15 README.md
@@ -135,6 +135,21 @@ val bar16_to_string : bar16 -> string
val string_to_bar16 : string -> bar16 option
```
+You can also add a `(sexp)` decorator to output s-expression convertors
+for use with the `sexplib` library.
+
+```
+cenum foo32 {
+ ONE32;
+ TWO32 = 0xfffffffel;
+ THREE32
+} as uint32_t(sexp)
+```
+
+And `sexp_of_foo64` and `foo64_of_sexp` functions will also be available.
+The representation of the Sexp is the string representation of the enum.
+
+
Please see the `lib_test/` directory for more in-depth examples.
[![Build Status](https://travis-ci.org/avsm/ocaml-cstruct.png)](https://travis-ci.org/avsm/ocaml-cstruct)
View
2  _oasis
@@ -1,6 +1,6 @@
OASISFormat: 0.3
Name: cstruct
-Version: 1.1.0
+Version: 1.2.0
Synopsis: Manipulate external buffers as C-like structs
Authors: Anil Madhavapeddy, Richard Mortier, Thomas Gazagnaire, Pierre Chambart
License: ISC
View
2  lib_test/enum.ml
@@ -18,7 +18,7 @@ cenum foo64 {
ONE64;
TWO64;
THREE64
-} as uint64_t
+} as uint64_t(sexp)
cenum foo32 {
ONE32;
View
2  lib_test/enum.mli
@@ -18,7 +18,7 @@ cenum foo64 {
ONE64;
TWO64;
THREE64
-} as uint64_t
+} as uint64_t(sexp)
cenum foo32 {
ONE32;
View
67 syntax/pa_cstruct.ml
@@ -253,7 +253,7 @@ let output_struct_sig _loc s =
) <:sig_item< $output_sizeof_sig _loc s$ >> s.fields
in <:sig_item< $expr$; $output_hexdump_sig _loc s$ >>
-let output_enum _loc name fields width =
+let output_enum _loc name fields width ~sexp =
let intfn,pattfn = match ty_of_string width with
|None -> loc_err _loc ("enum: unknown width specifier " ^ width)
|Some (UInt8 | UInt16) ->
@@ -282,15 +282,32 @@ let output_enum _loc name fields width =
let setter x = sprintf "%s_to_int" x in
let printer x = sprintf "%s_to_string" x in
let parse x = sprintf "string_to_%s" x in
+ let of_sexp x = sprintf "%s_of_sexp" x in
+ let to_sexp x = sprintf "sexp_of_%s" x in
+ let output_sexp_struct =
+ <:str_item<
+ value $lid:to_sexp name$ x = Sexplib.Sexp.Atom ($lid:printer name$ x) ;
+ value $lid:of_sexp name$ x =
+ match x with [
+ Sexplib.Sexp.List _ ->
+ raise (Sexplib.Pre_sexp.Of_sexp_error (Failure "expected Atom, got List", x))
+ | Sexplib.Sexp.Atom v ->
+ match $lid:parse name$ v with [
+ None -> raise (Sexplib.Pre_sexp.Of_sexp_error (Failure "unable to parse enum string", x))
+ | Some r -> r
+ ]
+ ] ;
+ >> in
<:str_item<
type $lid:name$ = [ $decls$ ] ;
value $lid:getter name$ x = match x with [ $getters$ ] ;
value $lid:setter name$ x = match x with [ $setters$ ] ;
value $lid:printer name$ x = match x with [ $printers$ ] ;
value $lid:parse name$ x = match x with [ $parsers$ | _ -> None ] ;
+ $if sexp then output_sexp_struct else <:str_item<>>$
>>
-let output_enum_sig _loc name fields width =
+let output_enum_sig _loc name fields width ~sexp =
let oty = match ty_of_string width with
|None -> loc_err _loc ("enum: unknown width specifier " ^ width)
|Some (UInt8|UInt16) -> <:ctyp<int>>
@@ -299,18 +316,26 @@ let output_enum_sig _loc name fields width =
in
let decls = tyOr_of_list (List.map (fun (f,_) ->
<:ctyp< $uid:f$ >>) fields) in
- let getter x = sprintf "int_to_%s" x in
- let setter x = sprintf "%s_to_int" x in
+ let getter x = sprintf "int_to_%s" x in
+ let setter x = sprintf "%s_to_int" x in
let printer x = sprintf "%s_to_string" x in
- let parse x = sprintf "string_to_%s" x in
+ let parse x = sprintf "string_to_%s" x in
+ let of_sexp x = sprintf "%s_of_sexp" x in
+ let to_sexp x = sprintf "sexp_of_%s" x in
let ctyo = <:ctyp< option $lid:name$ >> in
let cty = <:ctyp< $lid:name$ >> in
+ let output_sexp_sig =
+ <:sig_item<
+ value $lid:to_sexp name$ : $cty$ -> Sexplib.Sexp.t ;
+ value $lid:of_sexp name$ : Sexplib.Sexp.t -> $cty$ ;
+ >> in
<:sig_item<
type $lid:name$ = [ $decls$ ] ;
value $lid:getter name$ : $oty$ -> $ctyo$ ;
value $lid:setter name$ : $cty$ -> $oty$ ;
value $lid:printer name$ : $cty$ -> string ;
value $lid:parse name$ : string -> option $cty$ ;
+ $if sexp then output_sexp_sig else <:sig_item<>>$
>>
EXTEND Gram
@@ -350,13 +375,25 @@ EXTEND Gram
[ "{"; enums = constr_enum_decl; "}" -> enums ]
];
+ cenum_decorators : [
+ [ "as"; width = LIDENT; "("; decorator = LIDENT; ")" -> (width, Some decorator)
+ | "as"; width = LIDENT -> (width, None)
+ ]
+ ];
+
sig_item: [
[ "cstruct"; name = LIDENT; fields = constr_fields;
"as"; endian = LIDENT ->
output_struct_sig _loc (create_struct _loc endian name fields)
] |
- [ "cenum"; name = LIDENT; fields = constr_enums;
- "as"; width = LIDENT ->
+ [ "cenum"; name = LIDENT; fields = constr_enums;
+ info = cenum_decorators ->
+ let width = fst info in
+ let sexp = match snd info with
+ | None -> false
+ | Some "sexp" -> true
+ | Some x -> raise (Failure "unknown cenum decorator: only 'sexp' supported")
+ in
let n = ref Int64.minus_one in
let incr_n () = n := Int64.succ !n in
let fields =
@@ -364,17 +401,23 @@ EXTEND Gram
| (f, None) -> incr_n (); (f, !n)
| (f, Some i) -> n := i; (f, i)
) fields in
- output_enum_sig _loc name fields width
- ]
+ output_enum_sig _loc name fields width ~sexp
+ ]
];
-
+
str_item: [
[ "cstruct"; name = LIDENT; fields = constr_fields;
"as"; endian = LIDENT ->
output_struct _loc (create_struct _loc endian name fields)
] |
[ "cenum"; name = LIDENT; fields = constr_enums;
- "as"; width = LIDENT ->
+ info = cenum_decorators ->
+ let width = fst info in
+ let sexp = match snd info with
+ | None -> false
+ | Some "sexp" -> true
+ | Some x -> raise (Failure "unknown cenum decorator: only 'sexp' supported")
+ in
let n = ref Int64.minus_one in
let incr_n () = n := Int64.succ !n in
let fields =
@@ -382,7 +425,7 @@ EXTEND Gram
| (f, None) -> incr_n (); (f, !n)
| (f, Some i) -> n := i; (f, i)
) fields in
- output_enum _loc name fields width
+ output_enum _loc name fields width ~sexp
]
];
View
10 test.sh
@@ -1,6 +1,8 @@
#!/bin/sh -ex
endian=`ocamlfind query ocplib-endian.bigstring -format "-I %d %a" -predicates native,archive`
+sexplib=`ocamlfind query -r sexplib -format "-I %d %a" -predicates native,archive`
+sexplibi=`ocamlfind query -r sexplib -format "-I %d" -predicates native`
test() {
echo $1
@@ -8,13 +10,13 @@ mkdir -p _build/lib_test
cp lib_test/$1.ml _build/lib_test/$1.ml
camlp4orf -printer o _build/syntax/cstruct-syntax.cma lib_test/$1.ml > _build/lib_test/$1.gen.ml
camlp4orf -printer o _build/syntax/cstruct-syntax.cma lib_test/$1.mli > _build/lib_test/$1.gen.mli
-ocamlopt -pp 'camlp4orf _build/syntax/cstruct-syntax.cma' -I _build/lib -I _build/unix -i lib_test/$1.ml > _build/lib_test/$1.inferred.mli
+ocamlopt -pp 'camlp4orf _build/syntax/cstruct-syntax.cma' -I _build/lib -I _build/unix $sexplibi -i lib_test/$1.ml > _build/lib_test/$1.inferred.mli
cp _build/lib_test/$1.inferred.mli _build/lib_test/$1.mli
rm -f _build/lib_test/$1.cmi
cd _build/lib_test
-ocamlopt -pp 'camlp4orf ../syntax/cstruct-syntax.cma' -I ../lib -I ../unix -c $1.mli
-ocamlopt -pp 'camlp4orf ../syntax/cstruct-syntax.cma' -I ../lib -I ../unix -c $1.ml
-ocamlopt -I ../lib -I ../unix $endian unix.cmxa bigarray.cmxa cstruct.cmxa unix_cstruct.cmxa $1.cmx -o $1.opt
+ocamlopt -pp 'camlp4orf ../syntax/cstruct-syntax.cma' -I ../lib -I ../unix $sexplibi -c $1.mli
+ocamlopt -pp 'camlp4orf ../syntax/cstruct-syntax.cma' -I ../lib -I ../unix $sexplibi -c $1.ml
+ocamlopt -I ../lib -I ../unix $endian $sexplib cstruct.cmxa unix_cstruct.cmxa $1.cmx -o $1.opt
time ./$1.opt
#cp $1.gen.mli $1.mli
#ocamlopt -pp 'camlp4orf ../syntax/cstruct-syntax.cma' -I ../lib -c $1.mli
Please sign in to comment.
Something went wrong with that request. Please try again.