This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,18 @@
(library
(name ppx_sexp_conv_test_sexp_grammar)
(libraries base expect_test_helpers_core.expect_test_helpers_base
sexp_grammar)
(preprocess
(pps ppx_sexp_conv ppx_expect ppx_here)))
(rule
(targets regular_vs_polymorphic_variants.diff)
(deps test_regular_variants.ml test_polymorphic_variants.ml)
(mode promote)
(action
(bash
"%{bin:patdiff-for-review} %{bin:patdiff} %{deps} > %{targets} || true")))
(alias
(name DEFAULT)
(deps regular_vs_polymorphic_variants.diff))

View file

@ -0,0 +1,119 @@
open! Base
module _ = struct
type t = { a : int } [@@sexp.allow_extra_fields] [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Fields
{ allow_extra_fields = true
; fields =
[ No_tag
{ name = "a"
; required = true
; args = Cons (int_sexp_grammar.untyped, Empty)
}
]
})))
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
type t = { a : int } [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "a"
; required = true
; args = Cons (int_sexp_grammar.untyped, Empty)
}
]
})))
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
type t =
| Allow_extra_fields of { foo : int } [@sexp.allow_extra_fields]
| Forbid_extra_fields of { bar : int }
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "Allow_extra_fields"
; clause_kind =
List_clause
{ args =
Fields
{ allow_extra_fields = true
; fields =
[ No_tag
{ name = "foo"
; required = true
; args = Cons (int_sexp_grammar.untyped, Empty)
}
]
}
}
}
; No_tag
{ name = "Forbid_extra_fields"
; clause_kind =
List_clause
{ args =
Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "bar"
; required = true
; args = Cons (int_sexp_grammar.untyped, Empty)
}
]
}
}
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
let _ = Allow_extra_fields { foo = 1 }
let _ = Forbid_extra_fields { bar = 1 }
end

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,117 @@
open! Base
module type S = sig
type t [@@deriving sexp_grammar]
end
let show_grammar (module M : S) =
Expect_test_helpers_base.print_s ([%sexp_of: _ Sexp_grammar.t] [%sexp_grammar: M.t])
;;
module Grammarless = struct
type t =
[ `A
| `B of string
]
end
let the_grammar = [%sexp_grammar: [ `A | `B of string ]]
let%expect_test "[@sexp_grammar.custom] in [@@deriving]" =
show_grammar
(module struct
type t = (Grammarless.t[@sexp_grammar.custom the_grammar]) * int
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Cons
( (the_grammar : Grammarless.t Sexplib0.Sexp_grammar.t).untyped
, Cons (int_sexp_grammar.untyped, Empty) ))))
}
;;
let _ = t_sexp_grammar
[@@@end]
end);
[%expect
{|
(List (
Cons
(Variant (
(case_sensitivity Case_sensitive)
(clauses (
(No_tag (
(name A)
(clause_kind Atom_clause)))
(No_tag (
(name B) (clause_kind (List_clause (args (Cons String Empty))))))))))
(Cons Integer Empty)))
|}]
;;
let%expect_test "[@sexp_grammar.custom] in [%sexp_grammar]" =
show_grammar
(module struct
type t = Grammarless.t * int
let t_sexp_grammar =
[%sexp_grammar: (Grammarless.t[@sexp_grammar.custom the_grammar]) * int]
;;
end);
[%expect
{|
(List (
Cons
(Variant (
(case_sensitivity Case_sensitive)
(clauses (
(No_tag (
(name A)
(clause_kind Atom_clause)))
(No_tag (
(name B) (clause_kind (List_clause (args (Cons String Empty))))))))))
(Cons Integer Empty)))
|}]
;;
let%expect_test "[@sexp_grammar.any] in [@@deriving]" =
show_grammar
(module struct
type t =
(Grammarless.t[@sexp_grammar.any "GRAMMARLESS"])
* (Grammarless.t[@sexp_grammar.any])
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped = List (Cons (Any "GRAMMARLESS", Cons (Any "ANY", Empty))) }
;;
let _ = t_sexp_grammar
[@@@end]
end);
[%expect {| (List (Cons (Any GRAMMARLESS) (Cons (Any ANY) Empty))) |}]
;;
let%expect_test "[@sexp_grammar.any] in [%sexp_grammar]" =
show_grammar
(module struct
type t = Grammarless.t * Grammarless.t
let t_sexp_grammar =
[%sexp_grammar:
(Grammarless.t[@sexp_grammar.any "GRAMMARLESS"])
* (Grammarless.t[@sexp_grammar.any])]
;;
end);
[%expect {| (List (Cons (Any GRAMMARLESS) (Cons (Any ANY) Empty))) |}]
;;

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,35 @@
open! Base
module type S = sig
type t [@@deriving sexp_grammar]
end
module Key = struct
type t = int [@@deriving sexp_grammar]
end
module Pair = struct
type ('a, 'b) t = 'a * 'b [@@deriving sexp_grammar]
module M (A : T) = struct
type 'b t = A.t * 'b
end
let m__t_sexp_grammar (type a) (module Key : S with type t = a) v_sexp_grammar =
t_sexp_grammar Key.t_sexp_grammar v_sexp_grammar
;;
end
type t = string Pair.M(Key).t [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy (lazy (Pair.m__t_sexp_grammar (module Key) string_sexp_grammar).untyped)
}
;;
let _ = t_sexp_grammar
[@@@end]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,616 @@
open Ppx_sexp_conv_lib.Conv
[@@@warning "-37"] (* allow unused constructors *)
type abstract_a [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : abstract_a) -> ()
let (abstract_a_sexp_grammar : abstract_a Sexplib0.Sexp_grammar.t) =
{ untyped = Any "Test_coverage_for_deriving.abstract_a" }
;;
let _ = abstract_a_sexp_grammar
[@@@end]
type abstract_b [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : abstract_b) -> ()
let (abstract_b_sexp_grammar : abstract_b Sexplib0.Sexp_grammar.t) =
{ untyped = Any "Test_coverage_for_deriving.abstract_b" }
;;
let _ = abstract_b_sexp_grammar
[@@@end]
type integer = int [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : integer) -> ()
let (integer_sexp_grammar : integer Sexplib0.Sexp_grammar.t) = int_sexp_grammar
let _ = integer_sexp_grammar
[@@@end]
type tuple = int * string [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : tuple) -> ()
let (tuple_sexp_grammar : tuple Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Cons (int_sexp_grammar.untyped, Cons (string_sexp_grammar.untyped, Empty)))))
}
;;
let _ = tuple_sexp_grammar
[@@@end]
type pos =
{ x : float
; y : float
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : pos) -> ()
let (pos_sexp_grammar : pos Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "x"
; required = true
; args = Cons (float_sexp_grammar.untyped, Empty)
}
; No_tag
{ name = "y"
; required = true
; args = Cons (float_sexp_grammar.untyped, Empty)
}
]
})))
}
;;
let _ = pos_sexp_grammar
[@@@end]
type 'a unary = 'a list [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a unary) -> ()
let unary_sexp_grammar :
'a. 'a Sexplib0.Sexp_grammar.t -> 'a unary Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar -> list_sexp_grammar _'a_sexp_grammar
;;
let _ = unary_sexp_grammar
[@@@end]
type enum =
| One
| Two
| Three
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : enum) -> ()
let (enum_sexp_grammar : enum Sexplib0.Sexp_grammar.t) =
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag { name = "One"; clause_kind = Atom_clause }
; No_tag { name = "Two"; clause_kind = Atom_clause }
; No_tag { name = "Three"; clause_kind = Atom_clause }
]
}
}
;;
let _ = enum_sexp_grammar
[@@@end]
type ('a, 'b) which =
| This of 'a
| That of 'b
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : ('a, 'b) which) -> ()
let which_sexp_grammar :
'a 'b.
'a Sexplib0.Sexp_grammar.t
-> 'b Sexplib0.Sexp_grammar.t
-> ('a, 'b) which Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar _'b_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "This"
; clause_kind =
List_clause { args = Cons (_'a_sexp_grammar.untyped, Empty) }
}
; No_tag
{ name = "That"
; clause_kind =
List_clause { args = Cons (_'b_sexp_grammar.untyped, Empty) }
}
]
}
}
;;
let _ = which_sexp_grammar
[@@@end]
type 'a optional =
| No
| Yes of 'a
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a optional) -> ()
let optional_sexp_grammar :
'a. 'a Sexplib0.Sexp_grammar.t -> 'a optional Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag { name = "No"; clause_kind = Atom_clause }
; No_tag
{ name = "Yes"
; clause_kind =
List_clause { args = Cons (_'a_sexp_grammar.untyped, Empty) }
}
]
}
}
;;
let _ = optional_sexp_grammar
[@@@end]
type empty = | [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : empty) -> ()
let (empty_sexp_grammar : empty Sexplib0.Sexp_grammar.t) = { untyped = Union [] }
let _ = empty_sexp_grammar
[@@@end]
type _ phantom = int [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : _ phantom) -> ()
let phantom_sexp_grammar :
'a__086_.
'a__086_ Sexplib0.Sexp_grammar.t -> 'a__086_ phantom Sexplib0.Sexp_grammar.t
=
fun _'a__086__sexp_grammar -> int_sexp_grammar
;;
let _ = phantom_sexp_grammar
[@@@end]
type color =
[ `Red
| `Blue
]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : color) -> ()
let (color_sexp_grammar : color Sexplib0.Sexp_grammar.t) =
{ untyped =
Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag { name = "Red"; clause_kind = Atom_clause }
; No_tag { name = "Blue"; clause_kind = Atom_clause }
]
}
}
;;
let _ = color_sexp_grammar
[@@@end]
type adjective =
[ color
| `Fast
| `Slow
| `Count of int
]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : adjective) -> ()
let (adjective_sexp_grammar : adjective Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Union
[ color_sexp_grammar.untyped
; Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag { name = "Fast"; clause_kind = Atom_clause }
; No_tag { name = "Slow"; clause_kind = Atom_clause }
; No_tag
{ name = "Count"
; clause_kind =
List_clause { args = Cons (int_sexp_grammar.untyped, Empty) }
}
]
}
]))
}
;;
let _ = adjective_sexp_grammar
[@@@end]
type 'a tree =
{ data : 'a
; children : 'a tree list
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a tree) -> ()
include struct
open struct
let (grammars__118_ : Sexplib0.Sexp_grammar.defn Stdlib.List.t Stdlib.Lazy.t) =
lazy
(let tree_sexp_grammar
: 'a. 'a Sexplib0.Sexp_grammar.t -> 'a tree Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar ->
{ untyped = Recursive ("tree", [ _'a_sexp_grammar.untyped ]) }
in
[ { tycon = "tree"
; tyvars = [ "a" ]
; grammar =
List
(Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "data"
; required = true
; args = Cons (Tyvar "a", Empty)
}
; No_tag
{ name = "children"
; required = true
; args =
Cons
( (list_sexp_grammar
(tree_sexp_grammar { untyped = Tyvar "a" }))
.untyped
, Empty )
}
]
})
}
])
;;
let _ = grammars__118_
end
let tree_sexp_grammar :
'a. 'a Sexplib0.Sexp_grammar.t -> 'a tree Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar ->
{ untyped =
Tycon ("tree", [ _'a_sexp_grammar.untyped ], Stdlib.Lazy.force grammars__118_)
}
;;
let _ = tree_sexp_grammar
end
[@@@end]
type alpha = int
and beta =
{ alpha : alpha
; betas : beta list
}
and gamma = beta list [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : alpha) -> ()
let _ = fun (_ : beta) -> ()
let _ = fun (_ : gamma) -> ()
include struct
open struct
let (grammars__131_ : Sexplib0.Sexp_grammar.defn Stdlib.List.t Stdlib.Lazy.t) =
lazy
(let (alpha_sexp_grammar : alpha Sexplib0.Sexp_grammar.t) =
{ untyped = Recursive ("alpha", []) }
and (beta_sexp_grammar : beta Sexplib0.Sexp_grammar.t) =
{ untyped = Recursive ("beta", []) }
in
[ { tycon = "alpha"; tyvars = []; grammar = int_sexp_grammar.untyped }
; { tycon = "beta"
; tyvars = []
; grammar =
List
(Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "alpha"
; required = true
; args = Cons (alpha_sexp_grammar.untyped, Empty)
}
; No_tag
{ name = "betas"
; required = true
; args =
Cons ((list_sexp_grammar beta_sexp_grammar).untyped, Empty)
}
]
})
}
])
;;
let _ = grammars__131_
end
let (alpha_sexp_grammar : alpha Sexplib0.Sexp_grammar.t) =
{ untyped = Lazy (lazy (Tycon ("alpha", [], Stdlib.Lazy.force grammars__131_))) }
and (beta_sexp_grammar : beta Sexplib0.Sexp_grammar.t) =
{ untyped = Lazy (lazy (Tycon ("beta", [], Stdlib.Lazy.force grammars__131_))) }
;;
let _ = alpha_sexp_grammar
and _ = beta_sexp_grammar
end
let (gamma_sexp_grammar : gamma Sexplib0.Sexp_grammar.t) =
{ untyped = Lazy (lazy (list_sexp_grammar beta_sexp_grammar).untyped) }
;;
let _ = gamma_sexp_grammar
[@@@end]
type record_attributes =
{ a : int [@default 0]
; b : bool [@sexp.bool]
; c : float option [@sexp.option]
; d : string list [@sexp.list]
; e : bytes array [@sexp.array]
; f : Ppx_sexp_conv_lib.Sexp.t [@sexp.omit_nil]
}
[@@sexp.allow_extra_fields] [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : record_attributes) -> ()
let (record_attributes_sexp_grammar : record_attributes Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Fields
{ allow_extra_fields = true
; fields =
[ No_tag
{ name = "a"
; required = false
; args = Cons (int_sexp_grammar.untyped, Empty)
}
; No_tag { name = "b"; required = false; args = Empty }
; No_tag
{ name = "c"
; required = false
; args = Cons (float_sexp_grammar.untyped, Empty)
}
; No_tag
{ name = "d"
; required = false
; args = Cons (List (Many string_sexp_grammar.untyped), Empty)
}
; No_tag
{ name = "e"
; required = false
; args = Cons (List (Many bytes_sexp_grammar.untyped), Empty)
}
; No_tag
{ name = "f"
; required = false
; args =
Cons (Ppx_sexp_conv_lib.Sexp.t_sexp_grammar.untyped, Empty)
}
]
})))
}
;;
let _ = record_attributes_sexp_grammar
[@@@end]
type variant_attributes =
| A
| B of int list [@sexp.list]
| C of
{ a : int [@default 0]
; b : bool [@sexp.bool]
; c : float option [@sexp.option]
; d : string list [@sexp.list]
; e : bytes array [@sexp.array]
; f : Ppx_sexp_conv_lib.Sexp.t [@sexp.omit_nil]
} [@sexp.allow_extra_fields]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : variant_attributes) -> ()
let (variant_attributes_sexp_grammar : variant_attributes Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag { name = "A"; clause_kind = Atom_clause }
; No_tag
{ name = "B"
; clause_kind = List_clause { args = Many int_sexp_grammar.untyped }
}
; No_tag
{ name = "C"
; clause_kind =
List_clause
{ args =
Fields
{ allow_extra_fields = true
; fields =
[ No_tag
{ name = "a"
; required = false
; args = Cons (int_sexp_grammar.untyped, Empty)
}
; No_tag
{ name = "b"; required = false; args = Empty }
; No_tag
{ name = "c"
; required = false
; args = Cons (float_sexp_grammar.untyped, Empty)
}
; No_tag
{ name = "d"
; required = false
; args =
Cons
( List (Many string_sexp_grammar.untyped)
, Empty )
}
; No_tag
{ name = "e"
; required = false
; args =
Cons
( List (Many bytes_sexp_grammar.untyped)
, Empty )
}
; No_tag
{ name = "f"
; required = false
; args =
Cons
( Ppx_sexp_conv_lib.Sexp.t_sexp_grammar
.untyped
, Empty )
}
]
}
}
}
]
}))
}
;;
let _ = variant_attributes_sexp_grammar
[@@@end]
type polymorphic_variant_attributes =
[ `A
| `B of int list [@sexp.list]
]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : polymorphic_variant_attributes) -> ()
let (polymorphic_variant_attributes_sexp_grammar :
polymorphic_variant_attributes Sexplib0.Sexp_grammar.t)
=
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag { name = "A"; clause_kind = Atom_clause }
; No_tag
{ name = "B"
; clause_kind = List_clause { args = Many int_sexp_grammar.untyped }
}
]
}))
}
;;
let _ = polymorphic_variant_attributes_sexp_grammar
[@@@end]
type opaque =
{ x : (string[@sexp.opaque])
; y : int -> int
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : opaque) -> ()
let (opaque_sexp_grammar : opaque Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "x"
; required = true
; args =
Cons (Sexplib0.Sexp_conv.opaque_sexp_grammar.untyped, Empty)
}
; No_tag
{ name = "y"
; required = true
; args = Cons (Sexplib0.Sexp_conv.fun_sexp_grammar.untyped, Empty)
}
]
})))
}
;;
let _ = opaque_sexp_grammar
[@@@end]

View file

@ -0,0 +1,283 @@
(** This file covers a lot of cases for [@@deriving], for both interface and
implementation. They are also exported for validation. *)
type abstract_a [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val abstract_a_sexp_grammar : abstract_a Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type abstract_b [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val abstract_b_sexp_grammar : abstract_b Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type integer = int [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val integer_sexp_grammar : integer Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type tuple = int * string [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val tuple_sexp_grammar : tuple Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type pos =
{ x : float
; y : float
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val pos_sexp_grammar : pos Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type 'a unary = 'a list [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val unary_sexp_grammar : 'a Sexplib0.Sexp_grammar.t -> 'a unary Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type enum =
| One
| Two
| Three
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val enum_sexp_grammar : enum Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type ('a, 'b) which =
| This of 'a
| That of 'b
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val which_sexp_grammar
: 'a Sexplib0.Sexp_grammar.t
-> 'b Sexplib0.Sexp_grammar.t
-> ('a, 'b) which Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type 'a optional =
| No
| Yes of 'a
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val optional_sexp_grammar
: 'a Sexplib0.Sexp_grammar.t
-> 'a optional Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type empty = | [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val empty_sexp_grammar : empty Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type _ phantom = int [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val phantom_sexp_grammar
: 'a__003_ Sexplib0.Sexp_grammar.t
-> 'a__003_ phantom Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type color =
[ `Red
| `Blue
]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val color_sexp_grammar : color Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type adjective =
[ color
| `Fast
| `Slow
| `Count of int
]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val adjective_sexp_grammar : adjective Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type 'a tree =
{ data : 'a
; children : 'a tree list
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val tree_sexp_grammar : 'a Sexplib0.Sexp_grammar.t -> 'a tree Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type alpha = int
and beta =
{ alpha : alpha
; betas : beta list
}
and gamma = beta list [@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val alpha_sexp_grammar : alpha Sexplib0.Sexp_grammar.t
val beta_sexp_grammar : beta Sexplib0.Sexp_grammar.t
val gamma_sexp_grammar : gamma Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type record_attributes =
{ a : int
; b : bool
; c : float option
; d : string list
; e : bytes array
; f : Ppx_sexp_conv_lib.Sexp.t
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val record_attributes_sexp_grammar : record_attributes Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type variant_attributes =
| A
| B of int list
| C of
{ a : int
; b : bool
; c : float option
; d : string list
; e : bytes array
; f : Ppx_sexp_conv_lib.Sexp.t
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val variant_attributes_sexp_grammar : variant_attributes Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type polymorphic_variant_attributes =
[ `A
| `B of int list
]
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val polymorphic_variant_attributes_sexp_grammar
: polymorphic_variant_attributes Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]
type opaque =
{ x : string
; y : int -> int
}
[@@deriving sexp] [@@deriving_inline sexp_grammar]
include sig
[@@@ocaml.warning "-32"]
val opaque_sexp_grammar : opaque Sexplib0.Sexp_grammar.t
end
[@@ocaml.doc "@inline"]
[@@@end]

View file

@ -0,0 +1,19 @@
open! Base
(* Not sure how much people will want to use this, considering that the input is more
complicated and specific than the output, but they have it. *)
module type S = sig
val t_sexp_grammar : [%sexp_grammar: int Map.M(String).t]
end
module _ (M : S) : sig
val t_sexp_grammar : int Map.M(String).t Sexplib0.Sexp_grammar.t [@@warning "-32"]
end =
M
(* The grammar is illegible, so just make sure it builds. *)
let (_ : _ Sexplib0.Sexp_grammar.t) = [%sexp_grammar: int Map.M(String).t]
(* This used to give a compilation error. *)
let (_ : _ Sexplib0.Sexp_grammar.t) = [%sexp_grammar: _ list]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,158 @@
open! Base
module Maybe = struct
type 'a t = 'a option [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar -> option_sexp_grammar _'a_sexp_grammar
;;
let _ = t_sexp_grammar
[@@@end]
end
module Make (T : sig
type 'a t [@@deriving sexp_grammar]
end) =
struct
[@@@warning "-37"]
type 'a t = T of 'a T.t u
and 'a u = U of 'a T.t t Maybe.t [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let _ = fun (_ : 'a u) -> ()
include struct
open struct
let (grammars__001_ : Sexplib0.Sexp_grammar.defn Stdlib.List.t Stdlib.Lazy.t) =
lazy
(let t_sexp_grammar
: 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar ->
{ untyped = Recursive ("t", [ _'a_sexp_grammar.untyped ]) }
and u_sexp_grammar
: 'a. 'a Sexplib0.Sexp_grammar.t -> 'a u Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar ->
{ untyped = Recursive ("u", [ _'a_sexp_grammar.untyped ]) }
in
[ { tycon = "t"
; tyvars = [ "a" ]
; grammar =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause
{ args =
Cons
( (u_sexp_grammar
(T.t_sexp_grammar { untyped = Tyvar "a" }))
.untyped
, Empty )
}
}
]
}
}
; { tycon = "u"
; tyvars = [ "a" ]
; grammar =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "U"
; clause_kind =
List_clause
{ args =
Cons
( (Maybe.t_sexp_grammar
(t_sexp_grammar
(T.t_sexp_grammar { untyped = Tyvar "a" })))
.untyped
, Empty )
}
}
]
}
}
])
;;
let _ = grammars__001_
end
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Tycon ("t", [ _'a_sexp_grammar.untyped ], Stdlib.Lazy.force grammars__001_)
}
and u_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a u Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Tycon ("u", [ _'a_sexp_grammar.untyped ], Stdlib.Lazy.force grammars__001_)
}
;;
let _ = t_sexp_grammar
and _ = u_sexp_grammar
end
[@@@end]
type 'a v = V of 'a t [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a v) -> ()
let v_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a v Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "V"
; clause_kind =
List_clause
{ args = Cons ((t_sexp_grammar _'a_sexp_grammar).untyped, Empty) }
}
]
}
}
;;
let _ = v_sexp_grammar
[@@@end]
end
module T1 = Make (Maybe)
module T2 = Make (T1)
type t = int T2.t * int T1.t [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Cons
( (T2.t_sexp_grammar int_sexp_grammar).untyped
, Cons ((T1.t_sexp_grammar int_sexp_grammar).untyped, Empty) ))))
}
;;
let _ = t_sexp_grammar
[@@@end]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,75 @@
open! Base
type t = T : ('a[@sexp.opaque]) -> t [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause
{ args =
Cons (Sexplib0.Sexp_conv.opaque_sexp_grammar.untyped, Empty)
}
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
type nullary = Nullary : nullary [@@deriving sexp] [@@deriving_inline sexp_grammar]
let _ = fun (_ : nullary) -> ()
let (nullary_sexp_grammar : nullary Sexplib0.Sexp_grammar.t) =
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses = [ No_tag { name = "Nullary"; clause_kind = Atom_clause } ]
}
}
;;
let _ = nullary_sexp_grammar
[@@@end]
(* We can't derive [of_sexp], but we can derive a sensible grammar for this type. *)
type _ grammar_only = Grammar_only : int -> string grammar_only
[@@warning "-37"] [@@deriving_inline sexp_grammar]
let _ = fun (_ : _ grammar_only) -> ()
let grammar_only_sexp_grammar :
'a__016_.
'a__016_ Sexplib0.Sexp_grammar.t -> 'a__016_ grammar_only Sexplib0.Sexp_grammar.t
=
fun _'a__016__sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "Grammar_only"
; clause_kind =
List_clause { args = Cons (int_sexp_grammar.untyped, Empty) }
}
]
}
}
;;
let _ = grammar_only_sexp_grammar
[@@@end]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,19 @@
open! Base
open struct
type t = int [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) = int_sexp_grammar
let _ = t_sexp_grammar
[@@@end]
end
type nonrec t = t [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) = t_sexp_grammar
let _ = t_sexp_grammar
[@@@end]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,15 @@
open! Base
type t = (int[@sexp.opaque]) list [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy (lazy (list_sexp_grammar Sexplib0.Sexp_conv.opaque_sexp_grammar).untyped)
}
;;
let _ = t_sexp_grammar
[@@@end]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,171 @@
open Base
[@@@warning "-37"]
module _ = struct
type 'a t =
[ `A
| `B
]
[@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag { name = "A"; clause_kind = Atom_clause }
; No_tag { name = "B"; clause_kind = Atom_clause }
]
}
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
module With_sexp = struct
type t =
[ `A of int * int
| `B of string
]
[@@deriving sexp_of]
end
type t =
[ `A of int * int
| `B of string
]
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "A"
; clause_kind =
List_clause
{ args =
Cons
( List
(Cons
( int_sexp_grammar.untyped
, Cons (int_sexp_grammar.untyped, Empty) ))
, Empty )
}
}
; No_tag
{ name = "B"
; clause_kind =
List_clause
{ args = Cons (string_sexp_grammar.untyped, Empty) }
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
open Expect_test_helpers_base
let%expect_test _ =
print_s (With_sexp.sexp_of_t (`A (1, 2)));
print_s (With_sexp.sexp_of_t (`B "foo"));
[%expect {|
(A (1 2))
(B foo)
|}]
;;
end
module _ = struct
module With_sexp = struct
type t =
[ `Int of int
| `List of int list
| `Sexp_dot_list of int list [@sexp.list]
]
[@@deriving sexp]
end
type t =
[ `Int of int
| `List of int list
| `Sexp_dot_list of int list [@sexp.list]
]
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "Int"
; clause_kind =
List_clause { args = Cons (int_sexp_grammar.untyped, Empty) }
}
; No_tag
{ name = "List"
; clause_kind =
List_clause
{ args =
Cons ((list_sexp_grammar int_sexp_grammar).untyped, Empty)
}
}
; No_tag
{ name = "Sexp_dot_list"
; clause_kind =
List_clause { args = Many int_sexp_grammar.untyped }
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
let (T : (With_sexp.t, t) Type_equal.t) = T
open Expect_test_helpers_base
let%expect_test _ =
print_s (With_sexp.sexp_of_t (`Int 1));
List.iter
[ []; [ 1 ]; [ 1; 2 ] ]
~f:(fun l ->
print_s (With_sexp.sexp_of_t (`List l));
print_s (With_sexp.sexp_of_t (`Sexp_dot_list l)));
[%expect
{|
(Int 1)
(List ())
(Sexp_dot_list)
(List (1))
(Sexp_dot_list 1)
(List (1 2))
(Sexp_dot_list 1 2)
|}]
;;
end

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,115 @@
(* This toplevel test exercises some polymorphic variants that sexp_grammar rejects. We
show that in each case, the compiler or sexp would have given an error anyway. *)
open Base
type t = [ `A of int & string ] [@@deriving sexp]
[%%expect
{|
Line _, characters _-_:
Error: unsupported: polymorphic variant intersection type
|}]
type t = [ `A of int & string ] [@@deriving sexp_grammar]
[%%expect
{|
Line _, characters _-_:
Error: sexp_grammar: intersection types are unsupported
|}]
type t = [> `A ] [@@deriving sexp]
[%%expect
{|
Line _, characters _-_:
Error: Type unsupported for ppx [of_sexp] conversion
|}]
type t = [> `A ] [@@deriving sexp_grammar]
[%%expect
{|
Line _, characters _-_:
Error: sexp_grammar: open polymorphic variant types are unsupported
|}]
type t = [< `A ] [@@deriving sexp]
[%%expect
{|
Line _, characters _-_:
Error: A type variable is unbound in this type declaration.
In type [< `A ] as 'a the variable 'a is unbound
|}]
type t = [< `A ] [@@deriving sexp_grammar]
[%%expect
{|
Line _, characters _-_:
Error: A type variable is unbound in this type declaration.
In type [< `A ] as 'a the variable 'a is unbound
|}]
type 'a t = [< `A ] as 'a [@@deriving sexp]
[%%expect
{|
Line _, characters _-_:
Error: Type unsupported for ppx [of_sexp] conversion
|}]
type 'a t = [< `A ] as 'a [@@deriving sexp_grammar]
[%%expect
{|
Line _, characters _-_:
Error: sexp_grammar: type aliases are unsupported
|}]
type a = A : [> ] -> a [@@deriving sexp]
[%%expect
{|
Line _, characters _-_:
Error: Type unsupported for ppx [of_sexp] conversion
|}]
type a = A : [> ] -> a [@@deriving sexp_of]
[%%expect
{|
Line _, characters _-_:
Error: Type unsupported for ppx [sexp_of] conversion
|}]
type a = [ `A ] [@@deriving sexp];;
#verbose true
let f = [%sexp_of: [< a ]]
[%%expect
{|
val f : [< a ] -> Sexp.t = <fun>
|}]
let f = [%of_sexp: [> a ]]
[%%expect
{|
Line _, characters _-_:
Error: Type unsupported for ppx [of_sexp] conversion
|}]
let f = [%of_sexp: [ | a ]]
[%%expect
{|
val f : Sexp.t -> a = <fun>
|}]
;;
#verbose false

View file

@ -0,0 +1,34 @@
open! Base
type ('a, _, 'b) t = 'a * 'b
and u = (string, int, float) t [@@deriving_inline sexp_grammar]
let _ = fun (_ : ('a, _, 'b) t) -> ()
let _ = fun (_ : u) -> ()
let t_sexp_grammar :
'a 'b__001_ 'b.
'a Sexplib0.Sexp_grammar.t
-> 'b__001_ Sexplib0.Sexp_grammar.t
-> 'b Sexplib0.Sexp_grammar.t
-> ('a, 'b__001_, 'b) t Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar _'b__001__sexp_grammar _'b_sexp_grammar ->
{ untyped =
List (Cons (_'a_sexp_grammar.untyped, Cons (_'b_sexp_grammar.untyped, Empty)))
}
;;
let _ = t_sexp_grammar
let (u_sexp_grammar : u Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(t_sexp_grammar string_sexp_grammar int_sexp_grammar float_sexp_grammar).untyped)
}
;;
let _ = u_sexp_grammar
[@@@end]

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,112 @@
open Base
[@@@warning "-37"]
module _ = struct
type t = T of int [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause { args = Cons (int_sexp_grammar.untyped, Empty) }
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
type t =
| T_int of int
| T_u of u
and u =
| U_int of int
| U_t of t
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let _ = fun (_ : u) -> ()
include struct
open struct
let (grammars__001_ : Sexplib0.Sexp_grammar.defn Stdlib.List.t Stdlib.Lazy.t) =
lazy
(let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped = Recursive ("t", []) }
and (u_sexp_grammar : u Sexplib0.Sexp_grammar.t) =
{ untyped = Recursive ("u", []) }
in
[ { tycon = "t"
; tyvars = []
; grammar =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "T_int"
; clause_kind =
List_clause
{ args = Cons (int_sexp_grammar.untyped, Empty) }
}
; No_tag
{ name = "T_u"
; clause_kind =
List_clause { args = Cons (u_sexp_grammar.untyped, Empty) }
}
]
}
}
; { tycon = "u"
; tyvars = []
; grammar =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "U_int"
; clause_kind =
List_clause
{ args = Cons (int_sexp_grammar.untyped, Empty) }
}
; No_tag
{ name = "U_t"
; clause_kind =
List_clause { args = Cons (t_sexp_grammar.untyped, Empty) }
}
]
}
}
])
;;
let _ = grammars__001_
end
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped = Lazy (lazy (Tycon ("t", [], Stdlib.Lazy.force grammars__001_))) }
and (u_sexp_grammar : u Sexplib0.Sexp_grammar.t) =
{ untyped = Lazy (lazy (Tycon ("u", [], Stdlib.Lazy.force grammars__001_))) }
;;
let _ = t_sexp_grammar
and _ = u_sexp_grammar
end
[@@@end]
end

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,163 @@
open Base
[@@@warning "-37"]
module _ = struct
type 'a t =
| A
| B
[@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag { name = "A"; clause_kind = Atom_clause }
; No_tag { name = "B"; clause_kind = Atom_clause }
]
}
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
module With_sexp = struct
type t =
| A of int * int
| B of string
[@@deriving sexp_of]
end
type t = With_sexp.t =
| A of int * int
| B of string
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "A"
; clause_kind =
List_clause
{ args =
Cons
( int_sexp_grammar.untyped
, Cons (int_sexp_grammar.untyped, Empty) )
}
}
; No_tag
{ name = "B"
; clause_kind =
List_clause
{ args = Cons (string_sexp_grammar.untyped, Empty) }
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
open Expect_test_helpers_base
let%expect_test _ =
print_s (With_sexp.sexp_of_t (A (1, 2)));
print_s (With_sexp.sexp_of_t (B "foo"));
[%expect {|
(A 1 2)
(B foo)
|}]
;;
end
module _ = struct
module With_sexp = struct
type t =
| Int of int
| List of int list
| Sexp_dot_list of int list [@sexp.list]
[@@deriving sexp]
end
type t = With_sexp.t =
| Int of int
| List of int list
| Sexp_dot_list of int list [@sexp.list]
[@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "Int"
; clause_kind =
List_clause { args = Cons (int_sexp_grammar.untyped, Empty) }
}
; No_tag
{ name = "List"
; clause_kind =
List_clause
{ args =
Cons ((list_sexp_grammar int_sexp_grammar).untyped, Empty)
}
}
; No_tag
{ name = "Sexp_dot_list"
; clause_kind =
List_clause { args = Many int_sexp_grammar.untyped }
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
let (T : (With_sexp.t, t) Type_equal.t) = T
open Expect_test_helpers_base
let%expect_test _ =
print_s (With_sexp.sexp_of_t (Int 1));
List.iter
[ []; [ 1 ]; [ 1; 2 ] ]
~f:(fun l ->
print_s (With_sexp.sexp_of_t (List l));
print_s (With_sexp.sexp_of_t (Sexp_dot_list l)));
[%expect
{|
(Int 1)
(List ())
(Sexp_dot_list)
(List (1))
(Sexp_dot_list 1)
(List (1 2))
(Sexp_dot_list 1 2)
|}]
;;
end

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,179 @@
open! Base
module _ = struct
(* Nonrecursive constant *)
type t = [ `T of int ] [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause { args = Cons (int_sexp_grammar.untyped, Empty) }
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
(* Recursive constant *)
type t = [ `T of t ] [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
include struct
open struct
let (grammars__001_ : Sexplib0.Sexp_grammar.defn Stdlib.List.t Stdlib.Lazy.t) =
lazy
(let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped = Recursive ("t", []) }
in
[ { tycon = "t"
; tyvars = []
; grammar =
Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause { args = Cons (t_sexp_grammar.untyped, Empty) }
}
]
}
}
])
;;
let _ = grammars__001_
end
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped = Lazy (lazy (Tycon ("t", [], Stdlib.Lazy.force grammars__001_))) }
;;
let _ = t_sexp_grammar
end
[@@@end]
end
module _ = struct
(* Nonrecursive parameterized *)
type 'a t = [ `T of 'a ] [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause { args = Cons (_'a_sexp_grammar.untyped, Empty) }
}
]
}
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
(* Recursive parameterized *)
type 'a t = [ `T of 'a t ] [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
include struct
open struct
let (grammars__002_ : Sexplib0.Sexp_grammar.defn Stdlib.List.t Stdlib.Lazy.t) =
lazy
(let t_sexp_grammar
: 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar ->
{ untyped = Recursive ("t", [ _'a_sexp_grammar.untyped ]) }
in
[ { tycon = "t"
; tyvars = [ "a" ]
; grammar =
Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause
{ args =
Cons
( (t_sexp_grammar { untyped = Tyvar "a" }).untyped
, Empty )
}
}
]
}
}
])
;;
let _ = grammars__002_
end
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Tycon ("t", [ _'a_sexp_grammar.untyped ], Stdlib.Lazy.force grammars__002_)
}
;;
let _ = t_sexp_grammar
end
[@@@end]
end
module _ = struct
(* Aliasing of non-parameterized type *)
type t = int [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) = int_sexp_grammar
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
(* Aliasing of parameterized type *)
type 'a t = 'a list [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar -> list_sexp_grammar _'a_sexp_grammar
;;
let _ = t_sexp_grammar
[@@@end]
end

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,493 @@
open Base
module _ = struct
module type S = sig
type t [@@deriving sexp_grammar]
end
let show_grammar (module M : S) =
Expect_test_helpers_base.print_s ([%sexp_of: _ Sexp_grammar.t] [%sexp_grammar: M.t])
;;
let%expect_test "basic" =
show_grammar
(module struct
type nonrec t = (unit[@tag "key" = Atom "value"]) [@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key key)
(value value)
(grammar (List Empty))))
|}]
;;
let%expect_test "tag ordering" =
show_grammar
(module struct
type nonrec t =
(unit
[@tag
"key1" = Atom "value1";
"key2" = Atom "value2"])
[@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key key1)
(value value1)
(grammar (
Tagged (
(key key2)
(value value2)
(grammar (List Empty)))))))
|}]
;;
let%expect_test "tag idents/expressions" =
show_grammar
(module struct
let k = "key"
let v = Sexp.Atom "value"
let kf () = k
let vf () = v
type nonrec t =
(unit
[@tag
k = v;
kf () = vf ()])
[@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key key)
(value value)
(grammar (
Tagged (
(key key)
(value value)
(grammar (List Empty)))))))
|}]
;;
let%expect_test "tag nesting" =
show_grammar
(module struct
type nonrec t' = (unit[@sexp_grammar.tag "inner" = Atom "inner value"])
[@@deriving sexp_grammar]
type nonrec t = (t'[@sexp_grammar.tag "outer" = Atom "outer value"])
[@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key outer)
(value "outer value")
(grammar (
Tagged (
(key inner)
(value "inner value")
(grammar (List Empty)))))))
|}]
;;
let%expect_test "@tags attribute" =
(* literal constant *)
show_grammar
(module struct
type t = (unit[@tags [ "y", Atom "Y"; "z", Atom "Z" ]]) [@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key y)
(value Y)
(grammar (
Tagged (
(key z)
(value Z)
(grammar (List Empty)))))))
|}];
(* non-constant expression *)
show_grammar
(module struct
type t =
(unit
[@tags List.concat [ [ "x", Sexp.Atom "X" ]; [ "y", Atom "Y"; "z", Atom "Z" ] ]])
[@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key x)
(value X)
(grammar (
Tagged (
(key y)
(value Y)
(grammar (
Tagged (
(key z)
(value Z)
(grammar (List Empty))))))))))
|}];
(* cons onto non-constant expression *)
show_grammar
(module struct
type t =
(unit
[@tags
("w", Sexp.Atom "W")
:: List.concat [ [ "x", Sexp.Atom "X" ]; [ "y", Atom "Y"; "z", Atom "Z" ] ]])
[@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key w)
(value W)
(grammar (
Tagged (
(key x)
(value X)
(grammar (
Tagged (
(key y)
(value Y)
(grammar (
Tagged (
(key z)
(value Z)
(grammar (List Empty)))))))))))))
|}];
(* empty *)
show_grammar
(module struct
type t = (unit[@tags List.concat []]) [@@deriving sexp_grammar]
end);
[%expect {| (List Empty) |}];
(* with [@tag] *)
show_grammar
(module struct
type t = (unit[@tag "a" = Atom "A"] [@tags [ "b", Atom "B" ]])
[@@deriving sexp_grammar]
end);
[%expect
{|
(Tagged (
(key a)
(value A)
(grammar (
Tagged (
(key b)
(value B)
(grammar (List Empty)))))))
|}]
;;
let%expect_test "doc comments - variant clauses" =
show_grammar
(module struct
[@@@ocaml.warning "-37"]
(** IGNORED *)
type t =
| Clause0 of (unit[@tag "k0" = Atom "v0"]) (** first clause *)
| Clause1 [@tag "k1" = Atom "v1"] (** second clause *)
[@@deriving sexp_grammar ~tags_of_doc_comments]
(** IGNORED *)
end);
[%expect
{|
(Variant (
(case_sensitivity Case_sensitive_except_first_character)
(clauses (
(Tag (
(key sexp_grammar.doc_comment)
(value " first clause ")
(grammar (
No_tag (
(name Clause0)
(clause_kind (
List_clause (
args (
Cons
(Tagged (
(key k0)
(value v0)
(grammar (List Empty))))
Empty)))))))))
(Tag (
(key sexp_grammar.doc_comment)
(value " second clause ")
(grammar (
Tag (
(key k1)
(value v1)
(grammar (
No_tag (
(name Clause1)
(clause_kind Atom_clause)))))))))))))
|}]
;;
let%expect_test "doc comments - poly variant clauses" =
show_grammar
(module struct
[@@@ocaml.warning "-37"]
(** IGNORED *)
type t =
([ `Clause0 of (unit[@tag "k0" = Atom "v0"]) (** first clause *)
| `Clause1 [@tag "k1" = Atom "v1"] (** second clause *)
]
[@tag "kouter" = Atom "vouter"])
[@@deriving sexp_grammar ~tags_of_doc_comments]
(** IGNORED *)
end);
[%expect
{|
(Tagged (
(key kouter)
(value vouter)
(grammar (
Variant (
(case_sensitivity Case_sensitive)
(clauses (
(Tag (
(key sexp_grammar.doc_comment)
(value " first clause ")
(grammar (
No_tag (
(name Clause0)
(clause_kind (
List_clause (
args (
Cons
(Tagged (
(key k0)
(value v0)
(grammar (List Empty))))
Empty)))))))))
(Tag (
(key sexp_grammar.doc_comment)
(value " second clause ")
(grammar (
Tag (
(key k1)
(value v1)
(grammar (
No_tag (
(name Clause1)
(clause_kind Atom_clause))))))))))))))))
|}]
;;
let%expect_test "doc comments - record fields" =
show_grammar
(module struct
(** IGNORED *)
type t =
{ field0 : (unit[@tag "k0" = Atom "v0"]) (** first field *)
; field1 : unit [@tag "k1" = Atom "v1"] (** second field *)
}
[@@deriving sexp_grammar ~tags_of_doc_comments]
(** IGNORED *)
end);
[%expect
{|
(List (
Fields (
(allow_extra_fields false)
(fields (
(Tag (
(key sexp_grammar.doc_comment)
(value " first field ")
(grammar (
No_tag (
(name field0)
(required true)
(args (
Cons
(Tagged (
(key k0)
(value v0)
(grammar (List Empty))))
Empty)))))))
(Tag (
(key sexp_grammar.doc_comment)
(value " second field ")
(grammar (
Tag (
(key k1)
(value v1)
(grammar (
No_tag (
(name field1)
(required true)
(args (Cons (List Empty) Empty)))))))))))))))
|}]
;;
let%expect_test "deriving sexp_grammar without tags_of_doc_comments" =
show_grammar
(module struct
type t = { field : unit (** IGNORED *) } [@@deriving sexp_grammar]
end);
[%expect
{|
(List (
Fields (
(allow_extra_fields false)
(fields ((
No_tag (
(name field)
(required true)
(args (Cons (List Empty) Empty)))))))))
|}]
;;
let%expect_test "doc comments on subexpressions" =
show_grammar
(module struct
[@@@ocaml.warning "-37"]
type t = Foo of { bar : int (** inner *) } (** outer *)
[@@deriving sexp_grammar ~tags_of_doc_comments]
end);
[%expect
{|
(Variant (
(case_sensitivity Case_sensitive_except_first_character)
(clauses ((
Tag (
(key sexp_grammar.doc_comment)
(value " outer ")
(grammar (
No_tag (
(name Foo)
(clause_kind (
List_clause (
args (
Fields (
(allow_extra_fields false)
(fields ((
Tag (
(key sexp_grammar.doc_comment)
(value " inner ")
(grammar (
No_tag (
(name bar)
(required true)
(args (Cons Integer Empty)))))))))))))))))))))))
|}];
show_grammar
(module struct
[@@@ocaml.warning "-37"]
type t = [ `A of [ `B (** inner *) ] (** outer *) ]
[@@deriving sexp_grammar ~tags_of_doc_comments]
end);
[%expect
{|
(Variant (
(case_sensitivity Case_sensitive)
(clauses ((
Tag (
(key sexp_grammar.doc_comment)
(value " outer ")
(grammar (
No_tag (
(name A)
(clause_kind (
List_clause (
args (
Cons
(Variant (
(case_sensitivity Case_sensitive)
(clauses ((
Tag (
(key sexp_grammar.doc_comment)
(value " inner ")
(grammar (
No_tag (
(name B)
(clause_kind Atom_clause))))))))))
Empty)))))))))))))
|}];
show_grammar
(module struct
[@@@ocaml.warning "-37"]
type t = { a : [ `B of int (** inner *) ] (** outer *) }
[@@deriving sexp_grammar ~tags_of_doc_comments]
end);
[%expect
{|
(List (
Fields (
(allow_extra_fields false)
(fields ((
Tag (
(key sexp_grammar.doc_comment)
(value " outer ")
(grammar (
No_tag (
(name a)
(required true)
(args (
Cons
(Variant (
(case_sensitivity Case_sensitive)
(clauses ((
Tag (
(key sexp_grammar.doc_comment)
(value " inner ")
(grammar (
No_tag (
(name B)
(clause_kind (List_clause (args (Cons Integer Empty)))))))))))))
Empty))))))))))))
|}];
show_grammar
(module struct
[@@@ocaml.warning "-37"]
type t = [ `A of [ `B (** inner *) ] option (** outer *) ]
[@@deriving sexp_grammar ~tags_of_doc_comments]
end);
[%expect
{|
(Variant (
(case_sensitivity Case_sensitive)
(clauses ((
Tag (
(key sexp_grammar.doc_comment)
(value " outer ")
(grammar (
No_tag (
(name A)
(clause_kind (
List_clause (
args (
Cons
(Option (
Variant (
(case_sensitivity Case_sensitive)
(clauses ((
Tag (
(key sexp_grammar.doc_comment)
(value " inner ")
(grammar (
No_tag (
(name B)
(clause_kind Atom_clause)))))))))))
Empty)))))))))))))
|}]
;;
end

View file

@ -0,0 +1 @@
(* This interface intentionally left empty. *)

View file

@ -0,0 +1,62 @@
open Ppx_sexp_conv_lib
open Conv;;
#verbose true
module No_keys = struct
type t = (unit[@sexp_grammar.tag]) [@@deriving sexp_grammar]
end
[%%expect
{|
Line _, characters _-_:
Error: :: expected
|}]
module Key_literal_is_not_string = struct
type t = (unit[@sexp_grammar.tag 1 = [%sexp ""]]) [@@deriving sexp_grammar]
end
[%%expect
{|
Line _, characters _-_:
Error: This expression has type int but an expression was expected of type
string
|}]
module Key_ident_is_not_string = struct
let k = 1
type t = (unit[@sexp_grammar.tag k = [%sexp ""]]) [@@deriving sexp_grammar]
end
[%%expect
{|
Line _, characters _-_:
Error: This expression has type int but an expression was expected of type
string
|}]
module Value_literal_is_not_sexp = struct
type t = (unit[@sexp_grammar.tag "key" = 1]) [@@deriving sexp_grammar]
end
[%%expect
{|
Line _, characters _-_:
Error: This expression has type int but an expression was expected of type
Sexp.t
|}]
module Value_ident_is_not_sexp = struct
let v = 1
type t = (unit[@sexp_grammar.tag "key" = v]) [@@deriving sexp_grammar]
end
[%%expect
{|
Line _, characters _-_:
Error: This expression has type int but an expression was expected of type
Sexp.t
|}]

View file

@ -0,0 +1,86 @@
open! Base
module _ = struct
type t = int [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) = int_sexp_grammar
let _ = t_sexp_grammar
[@@@deriving.end]
end
module _ = struct
type 'a t = T of 'a
and 'a u = U of 'a t option [@@deriving_inline sexp_grammar]
let _ = fun (_ : 'a t) -> ()
let _ = fun (_ : 'a u) -> ()
let t_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a t Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "T"
; clause_kind =
List_clause { args = Cons (_'a_sexp_grammar.untyped, Empty) }
}
]
}
}
;;
let _ = t_sexp_grammar
let u_sexp_grammar : 'a. 'a Sexplib0.Sexp_grammar.t -> 'a u Sexplib0.Sexp_grammar.t =
fun _'a_sexp_grammar ->
{ untyped =
Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "U"
; clause_kind =
List_clause
{ args =
Cons
( (option_sexp_grammar (t_sexp_grammar _'a_sexp_grammar))
.untyped
, Empty )
}
}
]
}
}
;;
let _ = u_sexp_grammar
[@@@deriving.end]
(* Avoid unused constructor warnings. *)
let _ = T ()
let _ = U None
end
module _ = struct
type ('a, 'b) t = 'a -> 'b [@@deriving_inline sexp_grammar]
let _ = fun (_ : ('a, 'b) t) -> ()
let t_sexp_grammar :
'a 'b.
'a Sexplib0.Sexp_grammar.t
-> 'b Sexplib0.Sexp_grammar.t
-> ('a, 'b) t Sexplib0.Sexp_grammar.t
=
fun _'a_sexp_grammar _'b_sexp_grammar -> Sexplib0.Sexp_conv.fun_sexp_grammar
;;
let _ = t_sexp_grammar
[@@@end]
end

View file

@ -0,0 +1 @@
(*_ This signature is deliberately empty. *)

View file

@ -0,0 +1,93 @@
open Base
[@@@warning "-37"]
module _ = struct
type t = A of [ `A of int ] [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(Variant
{ case_sensitivity = Case_sensitive_except_first_character
; clauses =
[ No_tag
{ name = "A"
; clause_kind =
List_clause
{ args =
Cons
( Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "A"
; clause_kind =
List_clause
{ args =
Cons
( int_sexp_grammar.untyped
, Empty )
}
}
]
}
, Empty )
}
}
]
}))
}
;;
let _ = t_sexp_grammar
[@@@end]
end
module _ = struct
type t = { a : [ `A of int ] } [@@deriving_inline sexp_grammar]
let _ = fun (_ : t) -> ()
let (t_sexp_grammar : t Sexplib0.Sexp_grammar.t) =
{ untyped =
Lazy
(lazy
(List
(Fields
{ allow_extra_fields = false
; fields =
[ No_tag
{ name = "a"
; required = true
; args =
Cons
( Variant
{ case_sensitivity = Case_sensitive
; clauses =
[ No_tag
{ name = "A"
; clause_kind =
List_clause
{ args =
Cons
(int_sexp_grammar.untyped, Empty)
}
}
]
}
, Empty )
}
]
})))
}
;;
let _ = t_sexp_grammar
[@@@end]
end