-
Notifications
You must be signed in to change notification settings - Fork 125
/
imp_MatchGeneration.doc
312 lines (215 loc) · 6.55 KB
/
imp_MatchGeneration.doc
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
(**
*)
1ere Version, dans normalisation de pattern.
Cette version sera conservée sur master un temps,
et devrait déjà ameliorer les perfs comparé à jsfun.
Par la suite, on pourra étudier l'apport des tags et/ou
de la normalisation de patterns.
On reprend l'analyse du flat sur les pattern.
trivial_pat ==>
soit y'en a beaucoup, et on fait un bdd
soit y'en a pas beaucoup, et on fait des if sequentiels
closed_pat ==>
avec des if sequentiels (sauf que ce sont des cond, avec (? :), et que les affect ai sont des letin)
mais si on les ecrit comme ca, on comprendra rien ici.
if ( e1 ) {
a1 ;
<right-side>
} else
if ( e2 ) {
a1;
<right-side>
} else
if ( e3 ) {
} etc.
A) ei:
Chaque expression ei est un conjonction de clauses, décomposée 2 parties :
1) affectation par dot hypothetiques, avec enrichissement du penv.dot, et gardes de niveau 0
f1 = m.field1 , f2 = m.field2, etc...
Ces dots sont utilisés abilement pour detecter le cas de la somme dans lequel on se trouve.
Dans la plupart des cas, un unique dot est suffisant.
Ces dots peuvent affecter undefined aux variables.
Il s'agit de tests conjonctifs visant à valider le pattern, au niveau 0.
il en existe 3 types : present, absent, et size.
L'utilisation des size est surement à eviter, car cela est moins efficace avec l'optique par cache.
Quelques exemples :
Choix, le choix etant fait en priorité decroissantes selon:
+ ce qui est partageable avec un binding dans la partie droite (ie bindé dans le pattern)
+ si le type de la variable et un non-false JS
+ ce qui est partageable entre les guardes
(hd,tl|nil)[hd,tl] = present(hd) ou present(tl)
(hd,tl|nil)[nil] = present(nil) ou absent(hd) ou absent(tl)
(a|a,b)[a] = absent(b)
(a|a,b)[a,b] = present(b)
(a|b|a,b)[a] = absent(b)
(a|b|a,b)[b] = absent(a)
(a|b|a,b)[a,b] = present(a) AND present(b)
les tests present(field) et absent(field) revient à chercher la variable qui dot le field.
soit elle est dans l'affectation par dot hypothetiques qui la precede immediatement,
soit elle est dans une des affectations precedentes.
dans les 2 cas, le nom de la variable est recherché dans le penv.dot.
present(field) ==> v != undefined
absent(field) ==> v == undefined
où v = penv.dot(field)
Dans le cas où le type de la valeur n'est jamais habité par une valeur pouvant etre évaluée
à false dans un test js, on utilise directement le resultat de l'affectation comme test.
2) gardes d'imbrications
Il s'agit de tests conjonctifs visant à valider entièrement le pattern dans toutes ses imbrications.
Note pour plus tard: cette partie devient obsolète dans le cas de pattern normalisés.
B) ai:
Ensuite, vient une partie qui recree les bindings introduit par les pattern, implementé par dot garantis,
et par des alias. (ce sont les ai).
Quelques exemples:
==============================================
(a|a,b)
| ~{ a }
| ~{ a b }
cas avec valeur pouvant etre false ==>
v0 = m.a
if ( v1 = m.b, v1 == undefined ) {
a = v0;
<right-side>
} else {
a = v0;
b = v1;
<right-side>
}
cas avec valeur NE pouvant PAS etre false ==>
v0 = m.a
if ( !(v1 = m.b) ) {
a = v0;
<right-side>
} else {
a = v0;
b = v1;
<right-side>
}
==============================================
option
| { some = a }
| { none }
==>
if ( v0 = m.some, v0 != undefined ) {
a = v0;
<right-side>
} else {
<right-side>
}
==============================================
list
| [ hd | tl ]
| []
==>
if ( a = m.tl )
hd = m.hd ;
tl = a ;
<right-side>
} else {
<right-side>
}
list
| []
| [ hd | tl ]
==>
if ( !(a = m.tl) )
<right-side>
} else {
hd = m.hd ;
tl = a ;
<right-side>
}
==============================================
list
| []
| [ a ]
| [ a, b ]
| [ a, b, c ]
| [ a, b, c, d | tl ]
==>
// []
if ( !(v0 = m.tl) ) {
<right-side>
} else
// help: { hd = a ; tl = v0 }
// [ a ]
if ( (v1 = v0.nil) ) {
a = m.hd;
<right-side>
} else
// help: { hd = a ; tl = { hd = b ; tl = v2 } }
// [ a, b ]
if ( v2 = v0.tl && v3 = v2.nil ) {
a = m.hd ;
b = v0.hd ;
<right-side>
} else
// help: { hd = a ; tl = { hd = b ; tl = { hd = c ; tl = v4 } } }
// [ a, b, c ]
if ( v4 = v2.tl && v5 = v4.nil ) {
a = m.hd ;
b = v0.hd ;
c = v2.hd ;
<right-side>
} else
// help: { hd = a ; tl = { hd = b ; tl = { hd = c ; tl = { hd = c ; tl = v6 } } } }
// [ a, b, c, d | tl ]
if ( v6 = v4.tl ) {
a = m.hd ;
b = v0.hd ;
c = v2.hd ;
d = v4.hd ;
<right-side>
}
==============================================
list
| []
| [ a, b, c | tl ]
| [ a ]
| [ a, b ]
==>
// []
if ( !(v0 = m.tl) ) {
<right-side>
} else
// help: { hd = a ; tl = v0{ hd = b ; tl = v1{ hd = c ; tl = v2 } } }
// [ a, b, c | tl ]
if ( v1 = v0.tl && v2 = v1.tl ) {
a = m.hd ;
b = v0.hd ;
c = v1.hd ;
<right-side>
}
// help: { hd = a ; tl = v0 }
// [ a ]
if ( (v3 = v0.nil) ) {
a = m.hd;
<right-side>
} else
// help: { hd = a ; tl = v0{ hd = b ; tl = v4 } }
// [ a, b ]
if ( v4 = v1.nil ) { // ou else au mieux
a = m.hd ;
b = v0.hd ;
<right-side>
}
DECOUPAGE:
la fonction ()[]:
(a,b|c)[a,b] = present(a) ou present(b) ou absent(c)
on a besoin d'une fonction plus large, qui rend l'ensemble des propriétés vrais
type flagvar = Present | Absent
savoir si un type est un non-false js
IMPLEMENTATION:
private_env:
(*
C'est la liste des dot déjà effectués dans la partie gauche des tests.
Ces tests sont toujours regroupés en partie gauche des expressions sous les if,
et peuvent etre partagés d'un cas à l'autre.
*)
dot : ident StringMap.t (* a voir, peut etre l'indexation se fait sur une liste de champs, pour partager l'intermediaire des cas m.tl.tl.tl.hd *)
plus complexe:
on peut conserver un ensemble de condition sous lesquelles l'affectation a été faite,
et si on se retrouve sous un ensemble de condition plus fort, reprendre le meme ident
[18:16:50] <francois-regis.sinot@jabber.mlstate.com> http://mir.aculo.us/dom-monster/
[18:16:57] <francois-regis.sinot@jabber.mlstate.com> (si tu ne connais pas)
[18:17:03] <francois-regis.sinot@jabber.mlstate.com> (lien de David)
[18:17:18] <francois-regis.sinot@jabber.mlstate.com> Found 12386 JavaScript globals. Cutting back on globals can increase JavaScript performance.