-
Notifications
You must be signed in to change notification settings - Fork 10
/
m2l.mli
222 lines (176 loc) · 6.29 KB
/
m2l.mli
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
(**
The M2l module (for Module Meta Language) defines the codept AST.
This AST is a restriction of the Ocaml parsetree AST, that can
describe all constructions at the module level but have a very
simplified view of value (and type) level expressions.
For instance,
{[
module A = struct
module Inner = struct let f x = x end
end
let x = 1
open A
module B = struct let y = Inner.f x end
]}
is translated to
{[
module A = struct
module Inner = struct end
end
open A
module B = struct [%access {Inner}] end
]}
*)
(** {2 Main types } *)
type 'a bind = { name: Name.t option; expr:'a }
(** ['a bind] is an auxilliary type used for module/module type binding *)
type kind = Structure | Signature
(** The nature (ml/mli) of an m2l ast *)
(** An m2l ast/code fragment is a list of module level expression *)
type m2l = expression Loc.ext list
(** The [expression] type is the basic building block of the m2l AST *)
and expression =
| Open of module_expr (** [open A.B.C] ⇒ [Open [A;B;C]] *)
| Include of module_expr (** [struct include A end] *)
| SigInclude of module_type
(** [struct include A end] *)
| Bind of module_expr bind
(** [struct module A = struct … end] *)
| Bind_sig of module_type bind (** [struct module type A = sig … end] *)
| Bind_rec of module_expr bind list
(** [module rec A = … and B = … and …] *)
| Minor of minor list
(** value level expression.
Invariant: for any pure outliner [f], [ f (Minor m :: q ) ≡ f q ],
i.e, this expression constructor is only meaningful for dependencies
tracking.
*)
| Extension_node of extension
(** [[%ext …]] *)
(** A minor element represents a short description of type or value level
constructions, that contains only the information relevant for
dependency tracking.
*)
and minor =
| Access of access (** see {!access} below *)
| Pack of module_expr Loc.ext (** (module struct ... end) *)
| Extension_node of extension Loc.ext (** [%ext ... ] *)
| Local_open of Loc.t * module_expr * minor list
(** let open struct ... end in ... *)
| Local_bind of Loc.t * module_expr bind * minor list
(** let module M = ... in ... *)
and access = (Loc.t * Deps.Edge.t) Paths.E.map
(** [M.N.L.x] ⇒ access \{M.N.L = Normal \}
type t = A.t ⇒ access \{ A = ε \}
*)
(** Module level expression representation *)
and module_expr =
| Ident of Paths.Simple.t (** [A.B…] **)
| Apply of {f: module_expr; x:module_expr} (** [F(X)] *)
| Fun of module_expr fn (** [functor (X:S) -> M] *)
| Constraint of module_expr * module_type (** [M:S] *)
| Str of m2l (** [struct … end] *)
| Val of minor list (** [val … ] *)
| Extension_node of extension (** [[%ext …]] *)
| Abstract
(** empty module expression, used as a placeholder.
In particular, it is useful for constraining first class module unpacking
as [Constraint(Abstract, signature)]. *)
| Unpacked (** [(module M)] *)
| Open_me of { opens:Paths.Simple.t Loc.ext list; expr:module_expr}
(** [M.(…N.( module_expr)…)]
Note: This construction does not exist (yet?) in OCaml proper.
It is used here to simplify the interaction between
pattern open and first class module.*)
| Proj of {me:module_expr; proj:Paths.Simple.t }
(** Module type level representation *)
and module_type =
| Alias of Paths.Simple.t (** [module m = A…] *)
| Ident of Paths.Expr.t
(** [module M : F(X).s]
Note: Paths.Expr is used due to [F.(X).s] expressions
that do not have an equivalent on the module level
*)
| Sig of m2l (** [sig … end] *)
| Fun of module_type fn (** [functor (X:S) → M] *)
| Of of module_expr (** [module type of …] *)
| Extension_node of extension (** [%%… ] *)
| Abstract (** module type T *)
| With of {
body: module_type;
with_constraints: with_constraint list;
}
(** [ S with ... ] *)
and with_constraint = { lhs: Paths.S.t; delete:bool; rhs: with_rhs }
and with_rhs =
| Type of minor list
(** [S with type t =/:= ...] *)
| Module of Paths.S.t Loc.ext
(** [S with module N.M := …]
we need to track abstract module type strenghthening.
*)
| Module_type of module_type
(** Functor auxiliary type *)
and 'a fn = { arg: module_type Module.Arg.t option; body:'a }
(** An specific represention for an extension node *)
and extension = {name:string; extension:extension_core}
(** A type for extension payload *)
and extension_core =
| Module of m2l
| Val of minor list
type t = m2l
(** {2 Schematic serialization } *)
val sch: m2l Schematic.t
module Sch: sig
val expr: expression Schematic.t
val module_expr: module_expr Schematic.t
val module_type: module_type Schematic.t
val minors: minor list Schematic.t
end
module Annot : sig
type t = minor list Loc.ext
module Access: sig
type t = access
val empty: t
val merge: t -> t -> t
end
val empty: t
val is_empty: t -> bool
val merge: t -> t -> t
val (++): t -> t -> t
(** [ (++) ≡ merge ]*)
val union: t list -> t
val union_map: ('a -> t) -> 'a list -> t
val pack: module_expr Loc.ext -> t
val ext: extension Loc.ext -> t
val access: Paths.E.t Loc.ext -> t
val abbrev: Paths.E.t Loc.ext -> t
val local_open: Loc.t -> module_expr -> t -> t
val local_bind: Loc.t -> module_expr bind -> t -> t
val opt: ('a -> t) -> 'a option -> t
val epsilon_promote: t -> t
end
module Build: sig
val ghost: expression -> expression Loc.ext
val access: Paths.Expr.t Loc.ext -> expression Loc.ext
val open_path: Paths.Simple.t Loc.ext -> expression Loc.ext
val open_: module_expr Loc.ext -> expression Loc.ext
val open_me: Paths.Simple.t Loc.ext list -> module_expr -> module_expr
val fn_sig: module_type fn -> module_type
val fn: module_expr fn -> module_expr
end
(**
{2 Basis analysis }
*)
(** {2 Signature filter} *)
module Sig_only: sig
val filter: m2l -> m2l
end
(** {2 Printers } *)
val pp: Format.formatter -> m2l -> unit
val pp_expression: Format.formatter -> expression -> unit
val pp_annot: Format.formatter -> minor list -> unit
val pp_me: Format.formatter -> module_expr -> unit
val pp_mt: Format.formatter -> module_type -> unit
val pp_with_constraints: Format.formatter -> with_constraint list -> unit
val pp_access: access Pp.t