1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
open Ppxlib
module Make (T : sig
val namespace : string
val default_library : string
end) =
struct
module Attributes = Attributes.Make (T)
let with_engine f ~loc ~path:_ =
let (module S) = Ast_builder.make loc in
f (module Engine.Located (Attributes) (S) : Engine.S)
let deriving_args () =
Deriving.Args.(empty +> arg "name" (estring __) +> arg "lib" __)
let library =
lazy
(let library = ref (Some T.default_library) in
let doc =
Format.sprintf
"<module-path> Set the module path containing the combinators to \
use (defaults to %s). An empty string is interpreted as the \
current module."
T.default_library
in
Ppxlib.Driver.add_arg "--lib"
(Arg.String (function "" -> library := None | s -> library := Some s))
~doc;
library)
let register_deriver () =
let library = Lazy.force library in
let str_type_decl =
let attributes = Attributes.all in
Deriving.Generator.make ~attributes (deriving_args ())
( with_engine @@ fun (module L) input_ast name lib ->
let lib =
match lib with Some s -> L.parse_lib s | None -> !library
in
L.derive_str ?name ?lib input_ast )
in
let sig_type_decl =
Deriving.Generator.make (deriving_args ())
( with_engine @@ fun (module L) input_ast name lib ->
let lib =
match lib with Some s -> L.parse_lib s | None -> !library
in
L.derive_sig ?name ?lib input_ast )
in
Deriving.add ~str_type_decl ~sig_type_decl T.namespace |> Deriving.ignore
let register_extension ?no_reserve_namespace () =
let library = Lazy.force library in
let extension =
Extension.declare (T.namespace ^ ".typ") Extension.Context.expression
Ast_pattern.(ptyp __)
(with_engine @@ fun (module L) -> L.expand_typ ?lib:!library)
in
(match no_reserve_namespace with
| Some () -> ()
| None -> Reserved_namespaces.reserve T.namespace);
Driver.register_transformation ~extensions:[ extension ] T.namespace
end