Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 203 lines (164 sloc) 5.295 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 Abtract type of annotation, for decorated AST.
20 *)
21
22 (**
23 Some recent benches have shown that the indirection introduced by having a record
24 {[{ e : expr ; annot : annot }]}
25 for manipulating the AST is less efficient that having the annotation as
26 field0 of the constructors. (allocation, GC, etc.)
27 {[
28 K of annot * arg1 * arg2 * etc.
29 ]}
30
31 In an other side, AnnotMaps in libqmlcompil are much too complex, and correspond
32 to a louable (but partially deprecated) effort to follow the complexe needs of several
33 versions of hacky typers.
34
35 Finally, the experience has shown that positions are very important, and can
36 have a special traitement to be sure that we do have always a position for warnings,
37 error messages, etc.
38
39 This module is a proposition for reacting to these remarks.
40 The changes in the framework are considerable in term of portion of code touched,
41 but it is just a matter of time (no fondamental difficulty).
42 *)
43
44 (** {6 Annotation} *)
45
46 (**
47 The abstract type of a annot key.
48 *)
49 type t
50
51 (**
52 The comparaison on [t]
53 *)
54 val compare : t -> t -> int
55
56 (**
57 equality on [t]
58 *)
59 val equal : t -> t -> bool
60
61 (**
62 hash on [t]
63 *)
64 val hash : t -> int
65
66 (**
67 Get a string representation of the annot. Injective.
68 *)
69 val to_string : t -> string
70
71 (**
72 Generate a fresh annot. Global stamps.
73 *)
74 val next : unit -> t
75
76 (**
77 FIXME: document there why we need to transform an annot into a int.
78 If there is no good reason, the function should not be exported
79 *)
80 val to_int : t -> int
81
82 (** {6 Collections} *)
83 module AnnotMap : BaseMapSig.S with type key = t
84 module AnnotSet : BaseSetSig.S with type elt = t
85
86 (** {6 AST} *)
87
88 (**
89 Originally defined in QmlLoc, the type [label] regroups in a record a position, and an annot.
90 This type is meant to be used as field0 of Konstructors of AST.
91 {[
92 type ast =
93 | K1 of label * arg1 * arg2 * etc.
94 | K2 of label * args * etc.
95 ]}
96
97 It will lead to have an underscore in pattern matching, most of the time,
98 but it is the price to pay for removing the indirection [.expr, .annot] which is
99 not better to manipulate for deep patterns.
100
101 Note:
102 We could also have had a version :
103 {[
104 type ast =
105 | K1 of pos * annot * arg1 * arg2 * etc.
106 | K2 of pos * annot * args * etc.
107 ]}
108 but the couple (pos * annot) is not often separatly refreshed, so it brings probably nothing
109 in term of performances, but make 2 underscore in patterns instead of 1.
110 *)
111
112 (**
113 The type used for positions : defined in module [FilePos]
114 *)
115 type pos = FilePos.pos
116
117 (**
118 The type label.
119 + annot : A unique annotation.
120 + pos : The position in the source, produced by the parser, or empty for generated code.
121 *)
122 type label
123
124 val pos : label -> pos
125 val annot : label -> t
126 val make_label : t -> pos -> label
127
128 (**
129 Fresh label, with a fresh annot.
130 *)
131 val next_label : pos -> label
132
133 (**
134 Fresh label, with the same pos
135 *)
136 val refresh : label -> label
137
138 (**
139 Frehs annot, with a [no_pos] positions.
140 Should be used only for compatibility with old code.
141 The string is an indication to the path to the function which
142 build the label.
143 *)
144 val nolabel : string -> label
145
146 (**
147 If your AST follows guidelines about label, you can use these functions,
148 by reexporting them in a mli for restricting the type ['ast] to your AST.
149
150 The guidelines is the following :
151 The type ['a] should have a [label] in its [field0]
152 *)
153
154 module Magic :
155 sig
156
157 (**
158 Get the label of an expression.
159 *)
160 val label : 'ast -> label
161
162 (**
163 Get the annot of an expression.
164 *)
165 val annot : 'ast -> t
166
167 (**
168 Return a new expression by changing the label.
169 + new allocation of the block of the expression constructor
170 + shallow copy of old children of the constructor
171 *)
172 val new_label : 'ast -> label -> 'ast
173
174 (**
175 Return a new expression by changing the annotation.
176 + new allocation of the block of the expression constructor
177 + new allocation of a label
178 + shallow copy of old children of the constructor
179 + shallow copy of the old position
180 *)
181 val new_annot : 'ast -> t -> 'ast
182
183 (**
184 Get the pos of an expression.
185 *)
186 val pos : 'ast -> pos
187
188 (**
189 Return a new expression by changing the position.
190 + new allocation of the block of the expression constructor
191 + new allocation of a label
192 + shallow copy of old children of the constructor
193 + shallow copy of the old position
194 *)
195 val new_pos : 'ast -> pos -> 'ast
196
197 (**
198 Same than [new_pos] in term of allocation, but merge the old pos and the new pos.
199 *)
200 val merge_pos : 'ast -> pos -> 'ast
201
202 end
Something went wrong with that request. Please try again.