@@ -13,9 +13,11 @@ class JsInterp extends Interp {
13
13
public var properties : Map <String ,Bool >;
14
14
15
15
16
+ var localNames : Map <String ,String >;
17
+
16
18
override function execute ( expr : Expr ) : Dynamic {
17
19
depth = 0 ;
18
- locals = new Map ();
20
+ localNames = new Map ();
19
21
var str = ' (($$ i) => ${exprValue (expr )})' ;
20
22
var f : Dynamic -> Dynamic = js. Lib .eval (str );
21
23
return f (this );
@@ -58,6 +60,8 @@ class JsInterp extends Interp {
58
60
return ' (() => { ${exprJS (expr )}})()' ;
59
61
case EMeta (_ ,_ ,e ), ECheckType (e ,_ ):
60
62
return exprValue (e );
63
+ case EFunction (_ ,_ ,name ,_ ) if ( name != null ):
64
+ return ' (() => { ${exprJS (expr )}})()' ;
61
65
default :
62
66
return exprJS (expr );
63
67
}
@@ -104,6 +108,17 @@ class JsInterp extends Interp {
104
108
}
105
109
}
106
110
111
+ function declLocal ( n : String ) {
112
+ if ( ! localNames .exists (n ) ) {
113
+ localNames .set (n , n );
114
+ return n ;
115
+ }
116
+ var c = 2 ;
117
+ while ( localNames .exists (n + c ) ) c ++ ;
118
+ localNames .set (n , n + c );
119
+ return n + c ;
120
+ }
121
+
107
122
function exprJS ( expr : Expr ) : String {
108
123
#if hscriptPos
109
124
curExpr = expr ;
@@ -117,8 +132,9 @@ class JsInterp extends Interp {
117
132
case CString (s ): ' "' + escapeString (s )+ ' "' ;
118
133
}
119
134
case EIdent (v ):
120
- if ( locals .exists (v ) )
121
- return v ;
135
+ var v2 = localNames .get (v );
136
+ if ( v2 != null )
137
+ return v2 ;
122
138
if ( isContext (v ) )
123
139
return ' $$ i.ctx. $v ' ;
124
140
switch ( v ) {
@@ -127,16 +143,16 @@ class JsInterp extends Interp {
127
143
}
128
144
return ' $$ i.resolve(" $v ")' ;
129
145
case EVar (n , t , e ):
130
- locals . set ( n , null );
146
+ n = declLocal ( n );
131
147
return e == null ? ' let $n ' : ' let $n = ${exprValue (e )}' ;
132
148
case EParent (e ):
133
149
return ' ( ${exprValue (e )})' ;
134
150
case EBlock (el ):
135
- var old = locals .copy ();
151
+ var old = localNames .copy ();
136
152
// pre define name functions
137
153
for ( e in el )
138
154
switch ( Tools .expr (e ) ) {
139
- case EFunction (_ ,_ ,name ,_ ): locals . set (name , null );
155
+ case EFunction (_ ,_ ,name ,_ ): declLocal (name );
140
156
default :
141
157
}
142
158
var buf = new StringBuf ();
@@ -146,7 +162,7 @@ class JsInterp extends Interp {
146
162
buf .add (" ;" );
147
163
}
148
164
buf .add (' }' );
149
- locals = old ;
165
+ localNames = old ;
150
166
return buf .toString ();
151
167
case EField (e ,f ) if ( ! isProperty (f ) ):
152
168
return exprValue (e )+ " ." + f ;
@@ -160,8 +176,8 @@ class JsInterp extends Interp {
160
176
return ' ( ${exprCond (e1 )} $op ${exprCond (e2 )})' ;
161
177
case " =" :
162
178
switch ( Tools .expr (e1 ) ) {
163
- case EIdent (id ) if ( locals .exists (id ) ):
164
- return id + " = " + exprValue (e2 );
179
+ case EIdent (id ) if ( localNames .exists (id ) ):
180
+ return localNames . get ( id ) + " = " + exprValue (e2 );
165
181
case EIdent (id ) if ( isContext (id ) ):
166
182
return ' $$ i.ctx. $id = ${exprValue (e2 )}' ;
167
183
case EIdent (id ):
@@ -176,8 +192,8 @@ class JsInterp extends Interp {
176
192
case " +=" ," -=" ," *=" ," /=" ," %=" ," |=" ," &=" ," ^=" ," <<=" ," >>=" ," >>>=" :
177
193
var aop = op .substr (0 , op .length - 1 );
178
194
switch ( Tools .expr (e1 ) ) {
179
- case EIdent (id ) if ( locals .exists (id ) ):
180
- return id + " " + op + " " + exprValue (e2 );
195
+ case EIdent (id ) if ( localNames .exists (id ) ):
196
+ return localNames . get ( id ) + " " + op + " " + exprValue (e2 );
181
197
case EIdent (id ) if ( isContext (id ) ):
182
198
return ' $$ i.ctx. $id $op ${exprValue (e2 )}' ;
183
199
case EIdent (id ):
@@ -204,7 +220,8 @@ class JsInterp extends Interp {
204
220
return op + exprOp (e );
205
221
case " ++" , " --" :
206
222
switch ( Tools .expr (e ) ) {
207
- case EIdent (id ) if ( locals .exists (id ) ):
223
+ case EIdent (id ) if ( localNames .exists (id ) ):
224
+ id = localNames .get (id );
208
225
return prefix ? op + id : id + op ;
209
226
case EIdent (id ) if ( isContext (id ) ):
210
227
return prefix ? op + " $i.ctx." + id : " $i.ctx." + id + op ;
@@ -216,9 +233,15 @@ class JsInterp extends Interp {
216
233
return ' (($$ v) => ($$ i.setVar(" $id ",$$ v $op 1),$$ v))($$ i.resolve(" $id "))' ;
217
234
case EArray (e , index ):
218
235
var op = op .charAt (0 );
219
- return ' (($$ a,$$ idx) => { var $$ v = $$ i.getArray($$ a,$$ idx); $$ i.setArray($$ a,$$ idx,$$ v $op 1); return $$ v; })( ${exprValue (e )}, ${exprValue (index )})' ;
236
+ var v = declLocal (" $v" );
237
+ var str = ' (($$ a,$$ idx) => { let $v = $$ i.getArray($$ a,$$ idx); $$ i.setArray($$ a,$$ idx, $v $op 1); return $v ; })( ${exprValue (e )}, ${exprValue (index )})' ;
238
+ localNames .remove (v );
239
+ return str ;
220
240
case EField (e , f ):
221
- return ' (($$ o) => { var $$ v = $$ i.get($$ o," $f "); $$ i.set($$ o," $f ",$$ v $op 1); return $$ v; })( ${exprValue (e )})' ;
241
+ var v = declLocal (" $v" );
242
+ var str = ' (($$ o) => { let $v = $$ i.get($$ o," $f "); $$ i.set($$ o," $f ",$$ v $op 1); return $v ; })( ${exprValue (e )})' ;
243
+ localNames .remove (v );
244
+ return str ;
222
245
default :
223
246
error (EInvalidOp (op ));
224
247
}
@@ -241,7 +264,8 @@ class JsInterp extends Interp {
241
264
if ( isCtx )
242
265
return ' ${exprValue (e )}( ${args .join (' ,' )})' ;
243
266
return addPos (' $$ i.fcall2( ${exprValue (eobj )}," $f ",[ ${args .join (' ,' )}])' );
244
- case EIdent (id ) if ( locals .exists (id ) ):
267
+ case EIdent (id ) if ( localNames .exists (id ) ):
268
+ id = localNames .get (id );
245
269
return ' $id ( ${args .join (' ,' )})' ;
246
270
case EIdent (id ) if ( isContext (id ) ):
247
271
return ' $$ i.ctx. $id ( ${args .join (' ,' )})' ;
@@ -255,12 +279,14 @@ class JsInterp extends Interp {
255
279
case EWhile (cond , e ):
256
280
return ' while( ${exprValue (cond )} ) ${exprJS (e )}' ;
257
281
case EFor (v , it , e ):
258
- var prev = locals .exists (v );
259
- locals .set (v , null );
282
+ v = declLocal (v );
260
283
var block = exprJS (e );
261
- if ( ! prev ) locals .remove (v );
284
+ localNames .remove (v );
262
285
var iter = ' $$ i.makeIterator( ${exprValue (it )})' ;
263
- return ' { var $$ it = ${addPos (iter )}; while( $$ it.hasNext() ) { var $v = $$ it.next(); $block ; } }' ;
286
+ var it = declLocal (" $it" );
287
+ var str = ' { let $it = ${addPos (iter )}; while( $it .hasNext() ) { let $v = $it .next(); $block ; } }' ;
288
+ localNames .remove (it );
289
+ return str ;
264
290
case EBreak :
265
291
return ' break' ;
266
292
case EContinue :
@@ -295,10 +321,9 @@ class JsInterp extends Interp {
295
321
case EThrow (e ):
296
322
return " throw " + exprValue (e );
297
323
case ETry (e , v , t , ecatch ):
298
- var prev = locals .exists (v );
299
- locals .set (v , null );
324
+ v = declLocal (v );
300
325
var ec = exprBlock (ecatch );
301
- if ( ! prev ) locals .remove (v );
326
+ localNames .remove (v );
302
327
return ' try ${exprBlock (e )} catch( $v ) $ec ' ;
303
328
case EObject (fl ):
304
329
var fields = [for ( f in fl ) f .name + " :" + exprValue (f .e )];
@@ -308,16 +333,16 @@ class JsInterp extends Interp {
308
333
case EMeta (_ , _ , e ), ECheckType (e ,_ ):
309
334
return exprJS (e );
310
335
case EFunction (args , e , name , ret ):
336
+ var prev = localNames .copy ();
311
337
if ( name != null )
312
- locals .set (name , null );
313
- var prev = locals .copy ();
338
+ declLocal (name );
314
339
for ( a in args )
315
- locals .set (a .name , null );
340
+ localNames .set (a .name , a . name );
316
341
var bl = exprBlock (e );
317
- locals = prev ;
342
+ localNames = prev ;
318
343
var fstr = ' function( ${[for ( a in args ) a .name ].join (" ," )}) $bl ' ;
319
344
if ( name != null )
320
- fstr = ' var $name = $$ i.setVar(" $name ", $fstr )' ;
345
+ fstr = ' let $name = $$ i.setVar(" $name ", $fstr )' ;
321
346
return fstr ;
322
347
case ESwitch (e , cases , defaultExpr ):
323
348
var checks = [for ( c in cases ) ' if( ${[for ( v in c .values ) ' $$ v == ${exprValue (v )}' ].join (" || " )} ) return ${exprValue (handleRBC (c .expr ))};' ];
0 commit comments