Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 310 lines (243 sloc) 7.11 kB
fccc685 Initial open-source release
MLstate authored
1 (*
2 Copyright © 2011 MLstate
3
4 This file is part of OPA.
5
6 OPA is free software: you can redistribute it and/or modify it under the
7 terms of the GNU Affero General Public License, version 3, as published by
8 the Free Software Foundation.
9
10 OPA is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
13 more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with OPA. If not, see <http://www.gnu.org/licenses/>.
17 *)
18
19 (**
20 Definition of register directives for building external primitives libraries.
21
22 @author Mathieu Barbin
23 *)
24
25 (**
26 This module defines the type of the preprocess directives you can find in
27 the different files given to {b bslregister}, for example :
28 {[
29 ##register myfun : int, string -> string
30 ]}
31
32 As a complement, see also the module [BslTags.t] which manage only the optionnal
33 parameters for directives :
34 {[
35 ##register [tag:attribute] ....
36 like in :
37 ##register [noprojection] ....
38 ]}
39
40 For extanding tags, it is really easy, you just have to modify 1 file : BslTags.
41
42 For extanding directives, it is a little bit more work, you have to modify this
43 file, the parser of course, and all implementation of Generation for any language.
44 - BslOcaml
45 - BslJs
46 *)
47
48 (** {6 Alias, just for lisibility} *)
49
50 type pos = FilePos.pos
51 type source_code = string
52 type filename = string
53 type regexp = string
54 type injected = bool
55 type bslkey = string
56 type path = string
57 type skey = string
58
59
60
61 (** {6 Generic Types} *)
62 (**
63 The generic type of a directive.
64
65 Tags are some extra options you can give to the directive,
66 as in
67 {[
68 ##mydirective [mytag1, mytag:with_1_argument] directive_contents....
69 ]}
70 *)
71
72 type ('tags, 'directive) decorated_source_elt =
73 | Directive of pos * 'tags * 'directive
74 | Source of pos * source_code
75
76
77 type ('tags, 'directive) decorated_file = {
78 filename : filename ;
79 decorated_source : ('tags, 'directive) decorated_source_elt list
80 }
81
82 (** {6 Positions} *)
83
84 (**
85 This ast follows the guidelines about positions,
86 for error reporting.
87 *)
88
89 (** *)
90 let pos = LangAst.pos
91 let reset_pos = LangAst.reset_pos
92 let merge_pos = LangAst.merge_pos
93
94
95 (** {6 GUIDELINES for matching a [decorated_source_elt]} *)
96 (**
97
98 Verbose:
99 {[
100 | Directive (pos, tags, directive)
101 | Source (pos, source)
102 ]}
103
104 Shorter:
105 {[
106 | Directive (p, t, d)
107 | Source (p, s)
108 ]}
109 *)
110
111
112 (** {6 Opa files directives} *)
113 (**
114 Note:
115 There are no position in this AST, because such a directive
116 is always wrapped into a [decorated_source_elt] which already
117 provides the position.
118 *)
119 (** *)
120 type opalang_directive =
121 | IncludeType of regexp
122 | Include of BslIncludeFormats.fmt * path
123 | FormatDefinition of string
124
125 (**
126 Specialization of the generic [decorated_file] for opa files.
127 *)
128 type opalang_decorated_file =
129 (BslTags.t, opalang_directive) decorated_file
130
131 (**
132 {9 IncludeType}
133
134 A directive for producing all types definitions matching a regexp.
135 A typicall example, is to include all type from a given path
136
137 {[
138 ##extern-type mymodule.*
139 ]}
140 is represented as :
141 {[
142 IncludeType "mymodule.*"
143 ]}
144
145 {9 Include}
146
147 Inclusion preprocess is a mechanism for producting directly code from
148 bypass definitions, without rewritting the code with the type manually.
149
150 TODO: document format, cf BslIncludeFormat.
151 {[
152 ##include <format> path
153 ]}
154
155 {9 FormatDefinition}
156 TODO: documentation
157 *)
158
159 (** {6 GUIDELINES for matching a [opalang_directive]} *)
160 (**
161
162 Verbose:
163 {[
164 | IncludeType regexp
165 | Include (iformat, path)
166 | FormatDefinition name
167 ]}
168
169 Shorter:
170 {[
171 | IncludeType rgx
172 | Include (ifmt, p)
173 | FormatDefinition n
174 ]}
175 *)
176
177
178 (** {6 Bypass files directives} *)
179 (**
180 Note:
181 There are no position in this AST, because such a directive
182 is always wrapped into a [decorated_source_elt] which already
183 provides the position.
184 *)
185 (** *)
186 type bypasslang_directive =
187 | ExternalTypeDef of skey * BslTypes.typevar list * source_code option
188 | OpaTypeDef of skey * BslTypes.typevar list
189 | Module of skey * source_code option
190 | EndModule
191 | Register of skey * source_code option * injected * BslTypes.t
192 | Args of skey * (string * BslTypes.t) list * BslTypes.t
193 | Property of BslTags.parsed_t
194
195 (**
196 Specialization of the generic [decorated_file] for Ocaml and Javascript files.
197 *)
198 type bypasslang_decorated_file =
199 (BslTags.t, bypasslang_directive) decorated_file
200
201 (**
202 {9 ExternTypeDef}
203
204 A extern type definition.
205
206 This makes actually sence only in Ocaml files.
207 It introduces a new ocaml type.
208
209 {[
210 ##extern-type ('a, 'b, 'c) toto = Ka of 'a | Kb of 'b | Kc of 'c
211 ]}
212 is represented as :
213 {[
214 ExternTypeDef ("toto", ['a ; 'b ; 'c], "Ka of 'a | Kb of 'b | Kc of 'c")
215 ]}
216
217 @see "BslTypesGeneration.Ocaml" to see how this type is defined in opa, and how it is printed
218 in the [ml] and [mli] of the generated [MLRuntime]
219
220 {9 Module}
221
222 {[
223 ##module skey \ impl_name
224 ]}
225 is represented as :
226 {[
227 Module ("skey", "impl_name")
228 ]}
229
230 {9 EndModule}
231
232 For closing a module previously open.
233
234 Syntax:
235 {[
236 ##endmodule
237 ]}
238
239 {9 Register}
240
241 For defining a new primitive.
242 + The name of the key can be different than the name of the primitive in the
243 target language.
244 + The primitive can be injected from an existing implementation. In this case,
245 the implementation will be directly injected in the generated code. (cf Syntax 3)
246
247 Syntax 1:
248 {[
249 ##register skey : int, int -> int
250 ]}
251 is represented as :
252 {[
253 Register ("skey", "skey", false, BslTypes.(int, int -> int))
254 ]}
255
256 Syntax 2:
257 {[
258 ##register skey \ different_name : int, int -> int
259 ]}
260 is represented as :
261 {[
262 Register ("skey", "different_name", false, BslTypes.(int, int -> int))
263 ]}
264
265 Syntax 3:
266 {[
267 ##register skey \ `Pervasives.(+)` : int, int -> int
268 ]}
269 is represented as :
270 {[
271 Register ("skey", "Pervasives.(+)", true, BslTypes.(int, int -> int))
272 ]}
273
274 This is the only case where the injected bool is set to [true]
275
276 {9 Args}
277
278 TODO: documentation for args.
279 [impl], [arg_name, arg_type], return_type
280
281 {9 Property}
282
283 TODO: documentation for property
284 *)
285
286
287 (** {6 GUIDELINES for matching a [bypasslang_directive]} *)
288 (**
289
290 Verbose:
291 {[
292 | ExternalTypeDef (skey, params, implementation)
293 | Module (skey, implementation)
294 | EndModule
295 | Register (skey, implementation, injected, bslty)
296 | Args (name, args, bslty)
297 | Property (props)
298 ]}
299
300 Shorter:
301 {[
302 | ExternalTypeDef (n, p, imp)
303 | Module (n, imp)
304 | EndModule
305 | Register (n, imp, inj, ty)
306 | Args (n, xs, ty)
307 | Property p
308 ]}
309 *)
Something went wrong with that request. Please try again.