diff --git a/CHANGES.md b/CHANGES.md index 85b28b7..9a9021d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,9 +1,10 @@ ## unreleased -### Add +### Additions - Add an extension to write Yojson patterns - Add anti-quotations `[%y expr]` in expression extension +- Add support for `int32`, `int64` and `nativeint` payloads ### Fixes diff --git a/README.md b/README.md index 51efaa0..430a7fd 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,9 @@ The expression rewriter supports the following `Yojson` values: - `Float of float`: `[%yojson 1.2e+10]` - `Int of int`: `[%yojson 0xff]`. As long as the int literal in the payload fits in an `int`, the `0x`, `0o` and `0b` notations are accepted. -- `Intlit of string`: `[%yojson 100000000000000000000000000000000]`. For arbitrary long integers, +- `Intlit of string`: `[%yojson 100000000000000000000000000000000]`. For arbitrary long integers. + `int64`, `int32` and `nativeint` literals are also rewritten as `Intlit` for consistency with + `ppx_deriving_yojson` `0x`, `0o` and `0b` notations are currently not supported and the rewriter will raise an error. - `String of string`: `[%yojson "abc"]` - `List of json list`: `[%yojson [1; 2; 3]]`. It supports mixed type list as well such as diff --git a/lib/expression.ml b/lib/expression.ml index 0b57c90..a7e61e0 100644 --- a/lib/expression.ml +++ b/lib/expression.ml @@ -10,6 +10,8 @@ let expand_int ~loc ~pexp_loc s = | None when Integer_const.is_hexadecimal s -> Raise.unsupported_payload ~loc:pexp_loc | None -> [%expr `Intlit [%e Ast_builder.Default.estring ~loc s]] +let expand_intlit ~loc s = [%expr `Intlit [%e Ast_builder.Default.estring ~loc s]] + let expand_float ~loc s = [%expr `Float [%e Ast_builder.Default.efloat ~loc s]] let expand_anti_quotation ~pexp_loc = function @@ -25,12 +27,19 @@ let rec expand ~loc ~path expr = | [%expr true] -> [%expr (`Bool true)] | [%expr false] -> [%expr (`Bool false)] | {pexp_desc = Pexp_constant (Pconst_string (s, None)); _} -> expand_string ~loc s - | {pexp_desc = Pexp_constant (Pconst_integer (s, None)); pexp_loc; _} -> expand_int ~loc ~pexp_loc s + | {pexp_desc = Pexp_constant (Pconst_integer (s, None)); pexp_loc; _} + -> + expand_int ~loc ~pexp_loc s + | {pexp_desc = Pexp_constant (Pconst_integer (s, Some ('l' | 'L' | 'n'))); _} + -> + expand_intlit ~loc s | {pexp_desc = Pexp_constant (Pconst_float (s, None)); _} -> expand_float ~loc s | [%expr []] -> [%expr `List []] | [%expr [%e? _]::[%e? _]] -> [%expr `List [%e expand_list ~loc ~path expr]] | {pexp_desc = Pexp_record (l, None); _} -> [%expr `Assoc [%e expand_record ~loc ~path l]] - | {pexp_desc = Pexp_extension ({txt = "y"; _}, p); pexp_loc; _} -> expand_anti_quotation ~pexp_loc p + | {pexp_desc = Pexp_extension ({txt = "y"; _}, p); pexp_loc; _} + -> + expand_anti_quotation ~pexp_loc p | _ -> Raise.unsupported_payload ~loc:expr.pexp_loc and expand_list ~loc ~path = function | [%expr []] diff --git a/lib/pattern.ml b/lib/pattern.ml index f2eb5ce..a524826 100644 --- a/lib/pattern.ml +++ b/lib/pattern.ml @@ -10,6 +10,8 @@ let expand_int ~loc ~ppat_loc s = | None when Integer_const.is_binary s -> Raise.unsupported_payload ~loc:ppat_loc | None -> [%pat? `Intlit [%p Ast_builder.Default.pstring ~loc s]] +let expand_intlit ~loc s = [%pat? `Intlit [%p Ast_builder.Default.pstring ~loc s]] + let expand_float ~loc s = [%pat? `Float [%p Ast_builder.Default.pfloat ~loc s]] let expand_var ~loc var = Ast_builder.Default.ppat_var ~loc var @@ -24,6 +26,9 @@ let rec expand ~loc ~path pat = | {ppat_desc = Ppat_constant (Pconst_integer (s, None)); ppat_loc; _} -> expand_int ~loc ~ppat_loc s + | {ppat_desc = Ppat_constant (Pconst_integer (s, Some ('l' | 'L' | 'n'))); _} + -> + expand_intlit ~loc s | {ppat_desc = Ppat_constant (Pconst_float (s, None)); _} -> expand_float ~loc s | {ppat_desc = Ppat_var v; _} -> expand_var ~loc v | [%pat? [%p? left] | [%p? right]] diff --git a/test/rewriter/pp.expected b/test/rewriter/pp.expected index 1077250..41e0bdd 100644 --- a/test/rewriter/pp.expected +++ b/test/rewriter/pp.expected @@ -19,6 +19,9 @@ let complex : json = [`Assoc [("name", (`String "Kurt Cobain")); ("age", (`Int 27))]; `Assoc [("name", (`String "Jesus Christ")); ("age", (`Int 33))]]))] let anti_quotation : json = `Assoc [("a", (`String "a")); ("b", (`Int 1))] +let int_64 : json = `Intlit "1" +let int_32 : json = `Intlit "1" +let native_int : json = `Intlit "1" let patterns : json -> unit = ((function | `Null as _null -> () @@ -82,6 +85,9 @@ let patterns : json -> unit = "Jesus Christ")::[]))::[])):: ("description", `String "Some written thing")::[]) as _complex -> () + | `Intlit "1" as _int_64 -> () + | `Intlit "1" as _int_32 -> () + | `Intlit "1" as _native_int -> () | _s as _var -> () | _ as _any -> ()) [@warning "-11"]) diff --git a/test/rewriter/test.ml b/test/rewriter/test.ml index 539ab86..ad35d10 100644 --- a/test/rewriter/test.ml +++ b/test/rewriter/test.ml @@ -21,6 +21,9 @@ let complex : json = } ] let anti_quotation : json = [%yojson {a = [%y `String "a"]; b = 1}] +let int_64 : json = [%yojson 1L] +let int_32 : json = [%yojson 1l] +let native_int : json = [%yojson 1n] let patterns : json -> unit = function [@warning "-11"] | [%yojson? None] as _null -> () @@ -45,5 +48,8 @@ let patterns : json -> unit = function [@warning "-11"] ] as _complex -> () + | [%yojson? 1L] as _int_64 -> () + | [%yojson? 1l] as _int_32 -> () + | [%yojson? 1n] as _native_int -> () | [%yojson? _s] as _var -> () | [%yojson? _] as _any -> ()