efront 3.37.0 → 3.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,14 @@
1
- var { SPACE, COMMENT, EXPRESS, STRAP, QUOTED, STAMP, SCOPED, VALUE, LABEL, createString, skipAssignment, relink } = require("./common");
1
+ var { SPACE, COMMENT, EXPRESS, STRAP, QUOTED, STAMP, SCOPED, VALUE, LABEL, createString, skipAssignment, splice, relink, createExpressList, snapExpressHead, snapExpressFoot } = require("./common");
2
2
  var scanner2 = require("./scanner2");
3
3
  var RE = { type: STRAP, text: "@re" };// if (_) return
4
4
  var RZ = { type: STRAP, text: "@rz" };// if (!_) return
5
5
  var RD = { type: STRAP, text: "@rd" };// if (_) return
6
6
  var RETURN = { type: STRAP, text: "@ret" };// return;
7
+ var THROW = { type: STRAP, text: "@throw" };// return;
7
8
  var YIELD = { type: STRAP, text: "@yield" };// return;
8
9
  var NEXT = { type: STRAP, text: "@next" };// return;
9
10
  var _break = function (body, cx, result, iscontinue) {
11
+ if (!result.length || result[result.length - 1].ret_) return;
10
12
  var label;
11
13
  do {
12
14
  var o = body[++cx];
@@ -20,10 +22,11 @@ var _break = function (body, cx, result, iscontinue) {
20
22
  var b = labels[cx];
21
23
  if (b.type === LABEL && b.text === label) {
22
24
  if (!b.breaks) b.breaks = [];
23
- var _b = scanner2(`return[]`);
24
- if (iscontinue) _b.continue = s, s.continue = true;
25
- addresult(result, _b);
26
- b.breaks.push(_b);
25
+ var _b = scanner2('return []');
26
+ _b.ret_ = true;
27
+ if (iscontinue) _b[1].continue = s, s.continue = true;
28
+ b.breaks.push(_b[1]);
29
+ pushstep(result, _b);
27
30
  break;
28
31
  }
29
32
  else {
@@ -36,10 +39,11 @@ var _break = function (body, cx, result, iscontinue) {
36
39
  var b = labels[cx];
37
40
  if (b.type !== LABEL) {
38
41
  if (!b.breaks) b.breaks = [];
39
- var _b = scanner2(`return[]`);
40
- if (iscontinue) _b.continue = b, b.continue = true;
41
- addresult(result, _b);
42
- b.breaks.push(_b);
42
+ var _b = scanner2("return []");
43
+ _b.ret_ = true;
44
+ if (iscontinue) _b[1].continue = b, b.continue = true;
45
+ b.breaks.push(_b[1]);
46
+ pushstep(result, _b);
43
47
  break;
44
48
  }
45
49
  }
@@ -50,13 +54,13 @@ var _try = function (body, cx, unblock, result, getname) {
50
54
  var o = body[cx];
51
55
  o = o.next;
52
56
  while (body[cx++] !== o);
53
- var trystart = scanner2(`return [,7]`);
54
- addresult(result, trystart);
57
+ var trystart = stepReturn(0, 7);
58
+ var tse = trystart[trystart.length - 1];
59
+ pushstep(result, trystart);
55
60
  var tryoffset = result.length;
56
61
  unblock(o);
57
- var final = scanner2(`return [0,9]`);
58
-
59
- addresult(result, final);
62
+ var final = stepReturn(0, 9);
63
+ pushstep(result, final);
60
64
  o = o.next;
61
65
  if (o.type !== STRAP || o.text !== 'catch') throw `缺少catch语句`;
62
66
  o = o.next;
@@ -65,27 +69,27 @@ var _try = function (body, cx, unblock, result, getname) {
65
69
  if (o.type === SCOPED && o.entry === "(") {
66
70
  var e = o.first;
67
71
  if (e) {
68
- arg = scanner2(`${e.text}=${ret_ || "@"}`);
69
- addresult(result, arg);
72
+ arg = scanner2(`${e.text}=${ret_ || "@"};`);
70
73
  }
71
74
  o = o.next;
72
75
  }
76
+ var ai = result.length;
73
77
  unblock(o);
78
+ if (ai < result.length) {
79
+ if (arg.length) result[ai].unshift(...arg), result[ai].awaited = true, relink(result[ai]);
80
+ if (!result[result.length - 1].ret_) pushstep(result, stepReturn(0, 9));
81
+ }
74
82
  o = o.next;
83
+ var finishoffset = result.length;
75
84
  if (o && o.type === STRAP && o.text === 'finally') {
76
85
  o = o.next;
77
- var finishoffset = result.length;
78
86
  unblock(o);
79
87
  }
80
- var tse = trystart[trystart.length - 1];
81
- tse.unshift({
82
- text: String(catchoffset - tryoffset << 16 | finishoffset - catchoffset),
83
- type: VALUE,
84
- });
85
- relink(tse);
86
-
87
- var finalend = scanner2(`return [1,9]`);
88
- addresult(result, finalend);
88
+ tse[0].text = String(catchoffset - tryoffset | finishoffset - catchoffset << 16);
89
+ var finalend = stepReturn(1, 9);
90
+ pushstep(result, finalend);
91
+ while (cx < body.length && body[cx] !== o) cx++;
92
+ return cx;
89
93
  };
90
94
  var evals = [];
91
95
 
@@ -93,8 +97,9 @@ var _with = function (body, cx, unblock, result, getname) {
93
97
  var o = body[cx];
94
98
  var c = o.next;
95
99
  while (body[cx] !== c) cx++;
96
- unblock(c);
97
- evals.push(getname(0));
100
+ var qs = ternary(c, getname, true);
101
+ for (var q of qs) if (q.length) pushstep(result, q);
102
+ evals.push(q.name);
98
103
  var block = getblock(body, ++cx);
99
104
  cx += block.length;
100
105
  unblock(block);
@@ -118,7 +123,10 @@ var _switch = function (body, cx, unblock, result, getname) {
118
123
  var o = body[cx];
119
124
  o = o.next;
120
125
  if (!o) return;
121
- unblock(o);
126
+ var qt = _express(o, getname, true);
127
+ for (var q of qt) if (q.length) pushstep(result, q);
128
+ var q = qt[qt.length - 1];
129
+ var qn = q.name;
122
130
  o = o.next;
123
131
  while (body[cx++] !== o);
124
132
  if (!o) return;
@@ -128,38 +136,40 @@ var _switch = function (body, cx, unblock, result, getname) {
128
136
  while (o[cy] !== m) cy++;
129
137
  while (cy < o.length) {
130
138
  var block = getblock(o, ++cy);
131
- cy += block.length + 1;
139
+ cy += block.length;
140
+ while (cy < o.length && o[cy].type & (SPACE | COMMENT)) cy++;
141
+ cy++;
132
142
  var getnextname = function (deep) {
133
143
  return getname(deep + 1);
134
144
  };
135
145
  var q = _express(block, getnextname, true);
136
- for (var q of q) addresult(result, q);
137
- var case_ = scanner2(`if(${getname(0)}===${getname(1)})return[]`)
138
- addresult(result, case_);
146
+ for (var q of q) if (q.length) pushstep(result, q);
147
+ var qe = q;
148
+ if (qe.name) var case_ = scanner2(`if(${qn}===${qe.name})return[]`);
149
+ else case_ = scanner2(`return[]`), case_.ret_ = true;
150
+ pushstep(result, case_);
139
151
  var by = cy;
140
152
  m = o[cy];
141
- while (m && (m.type !== STRAP || m.text !== 'case')) m = o[++cy];
142
- tmp.push(result.length - 1, case_, o.slice(by, cy));
153
+ while (m && (m.type !== STRAP || !/^(default|case)$/i.test(m.text))) m = o[++cy];
154
+ tmp.push(result.length - 1, case_[case_.length - 1], o.slice(by, cy));
155
+ }
156
+ if (!result[result.length - 1].ret_) {
157
+ case_ = scanner2(`return[]`), case_.ret_ = true;
158
+ pushstep(result, case_);
159
+ tmp.push(result.length - 1, case_[case_.length - 1], []);
143
160
  }
144
161
  while (tmp.length) {
145
162
  cy = tmp.shift();
146
- case_ = tmp.shift();
163
+ q = tmp.shift();
147
164
  block = tmp.shift();
148
- var q = case_[case_.length - 1];
149
165
  q.push({ type: VALUE, text: String(result.length - cy) }, { type: STAMP, text: "," }, { type: VALUE, text: '0' });
150
166
  relink(q);
151
- for (var cy = 0, dy = block.length; cy < dy; cy++) {
152
- var b = getblock(block, cy);
153
- cy += b.length;
154
- var r = toqueue(b, getnextname, true);
155
- for (var r of r) {
156
- result.push(r);
157
- }
158
- }
167
+ unblock(block);
168
+ ifpatch(result);
159
169
  }
160
170
  return cx;
161
171
  };
162
- var _for = function (body, cx, unblock, result, tmpname) {
172
+ var _for = function (body, cx, unblock, result) {
163
173
  var o = body[cx];
164
174
  var label = o;
165
175
  o = o.next;
@@ -172,40 +182,61 @@ var _for = function (body, cx, unblock, result, tmpname) {
172
182
  // 含有高级语法的 for in 语句在 ./downLevel.js 中预处理
173
183
  var dx = cx;
174
184
  var n = o.next;
185
+ if (n && n.type === SCOPED && n.entry === '(') n = n.next;
175
186
  while (body[dx] !== n) dx++;
176
- addresult(result, body.slice(cx, dx));
177
- return dx;
187
+ var forin = body.slice(cx, dx);
188
+ var block = getblock(body, dx);
189
+ forin.push(...block);
190
+ pushstep(result, forin);
191
+ return dx + block.length + 1;
178
192
  }
179
193
  var cy = 0;
180
194
  while (o[cy] !== m) cy++;
181
195
  var block = getblock(o, cy);// init
182
196
  cy += block.length + 1;
183
- unblock(block, ...scanner2(`;return [1,0]`));
197
+ unblock(block);
198
+ if (result.length) pushstep(result, stepReturn(1, 0));
184
199
  var block1 = getblock(o, cy);// condition
185
200
  cy += block1.length + 1;
186
201
  var block2 = getblock(o, cy);// next
187
202
  while (body[cx] !== o) cx++;
188
203
  var block_ = getblock(body, ++cx);// body
189
204
  cx += block_.length;
190
- unblock(block1);
191
- relink(result[result.length - 1]);
192
- var b = scanner2(`;if(!${tmpname})return []`)
193
- result[result.length - 1].push(...b);
194
- relink(result[result.length - 1]);
205
+ var c = result.length;
206
+ if (block1.length) {
207
+ var t = unblock(block1);
208
+ if (t) {
209
+ t = t && !t.await_ ? t.name : ret_;
210
+ var b = scanner2(`if(!${t})return []`);
211
+ var be = b[b.length - 1];
212
+ pushstep(result, b);
213
+ }
214
+ }
195
215
  var i = result.length;
196
216
  unblock(block_);
197
- if (label.continue) label.continue = result.length, result[result.length - 1].cont = true, label.contat = result.length;
217
+ if (label.continue) ifpatch(result), label.contat = result.length;
198
218
  unblock(block2);
199
- result[result.length - 1].push(...scanner2(`;return [${i - result.length},0]`));
200
- b[b.length - 1].push(...scanner2(`${result.length - i + 1},0`));
201
- relink(result[result.length - 1]);
219
+ var loopback = stepReturn(0, 0);
220
+ var le = loopback[loopback.length - 1];
221
+ pushstep(result, loopback);
222
+ if (be) be.push(...scanner2(`${result.length - i + 1},0`)), relink(be);
223
+ le[0].text = String(c - result.length + 1);
202
224
  return cx;
203
225
  };
226
+ var isunary = function (o) {
227
+ var f = o.first;
228
+ if (!f) return false;
229
+ while (f) {
230
+ if (f.type & (STAMP | STRAP) && powermap[f.text] < powermap.new) return false;
231
+ f = f.next;
232
+ }
233
+ return true;
234
+ }
204
235
  var getCondition = function (o, unblock, not_) {
205
236
  var n = '';
206
237
  var f = o.first;
207
- var not = f.type === STAMP && f.text === "!";
208
- if (not) f = f.next;
238
+ var not = isunary(o) && f.type === STAMP && f.text === "!";
239
+ if (not) f = f.next, o.shift();
209
240
  if (not_) not = !not;
210
241
  if (f && f === o.last) {
211
242
  if (f.type & (EXPRESS | VALUE)) {
@@ -220,25 +251,36 @@ var getCondition = function (o, unblock, not_) {
220
251
  }
221
252
  if (!n) {
222
253
  n = unblock(o);
223
- n = n.await ? ret_ : n.name;
254
+ if (n.await_) {
255
+ n.ret_ = true;
256
+ delete n.await_;
257
+ n.await__ = true;
258
+ n = ret_;
259
+ }
260
+ else n = n.name;
224
261
  if (not) n = "!" + n;
225
262
  }
226
263
  return n;
227
264
  }
228
- var _while = function (body, cx, unblock, result, tmpname) {
265
+ var _while = function (body, cx, unblock, result) {
229
266
  var o = body[cx];
267
+ ifpatch(result);
230
268
  o.contat = result.length;
231
269
  o = o.next;
232
270
  while (body[cx] !== o) cx++;
233
- var b = scanner2(`if(${getCondition(o, unblock, true)})return []`)
234
- result.push(b);
271
+ var i = result.length;
272
+ var b = scanner2(`if(${getCondition(o, unblock, true)})return []`);
273
+ var be = b[b.length - 1];
274
+ pushstep(result, b);
235
275
  relink(result[result.length - 1]);
236
276
  var block = getblock(body, ++cx);
237
- var i = result.length;
238
277
  cx += block.length;
239
278
  unblock(block);
240
- result.push(scanner2(`return [${i - result.length - 1},0]`));
241
- b[b.length - 1].push(...scanner2(`${result.length - i + 1},0`));
279
+ var wend = stepReturn(0, 0);
280
+ var we = wend[wend.length - 1];
281
+ pushstep(result, wend);
282
+ we[0].text = String(1 + i - result.length);
283
+ be.push(...scanner2(`${result.length - i},0`));
242
284
  return cx;
243
285
  };
244
286
  var pushstep = function (result, step) {
@@ -247,17 +289,23 @@ var pushstep = function (result, step) {
247
289
  if (!q) {
248
290
  result.push(step);
249
291
  }
250
- else if (q.await) {
251
- if (!step.awaited) step.unshift(...scanner2(`${q.name}=${ret_};`));
292
+ else if (q.await_) {
293
+ if (!step.awaited) step.unshift(...scanner2(`${q.name}=${ret_};`)), relink(step);
252
294
  step.awaited = true;
253
- relink(step);
254
295
  result.push(step);
255
296
  }
256
- else if (q.ifrt || q.cont) {
297
+ else if (q.ret_) {
298
+ if (q.await__) step.awaited = true;
257
299
  result.push(step);
258
300
  }
259
301
  else {
260
- q.push({ type: STAMP, text: ";" }, ...step);
302
+ if (needcomma(q)) q.push({ type: STAMP, text: ';' });
303
+ if (!ishalf(q)) {
304
+ q.ret_ = step.ret_;
305
+ }
306
+ q.push(...step);
307
+ q.await_ = step.await_;
308
+ q.name = step.name;
261
309
  step = q;
262
310
  relink(q);
263
311
  }
@@ -298,63 +346,83 @@ var patchstep = function (r, nextindex, h) {
298
346
  relink(r);
299
347
  }
300
348
  };
301
- var addresult = function (result, step) {
302
- if (!step.length) return;
349
+ var flusqueue = function (result, queue) {
303
350
  var savedLength = result.length;
304
- var prev = result[savedLength - 1];
351
+ var savedIndex = savedLength - 1;
352
+ var prev = result[savedIndex];
305
353
  if (prev) var patch = prev.length;
354
+ for (var q of queue) pushstep(result, q);
355
+ queue = [];
356
+ if (ret_) {
357
+ if (prev) patchstep(prev, result.length - savedIndex, patch || 0);
358
+ result.slice(savedLength).forEach((a, i) => patchstep(a, result.length - savedLength - i, 0));
359
+ }
360
+ };
361
+
362
+ var addresult = function (result, step) {
363
+ if (!step.length) return;
306
364
  var cx, mx = 0, n;
307
365
  var awaited = step.awaited;
366
+ var queue = [];
308
367
  do {
368
+ while (step[mx] && step[mx].type === STAMP && /^[,;]$/.test(step[mx].text)) mx++;
309
369
  cx = step.indexOf(NEXT, mx);
310
370
  n = step.slice(mx, mx = cx < 0 ? step.length : cx + 1);
311
371
  if (awaited) n.awaited = awaited, awaited = false;
312
372
  n.name = step.name;
313
- pushstep(result, n);
373
+ queue.push(n);
314
374
  } while (mx < step.length);
315
- if (ret_) {
316
- if (prev) patchstep(prev, result.length - savedLength - 1, patch || 0);
317
- result.slice(savedLength).forEach((a, i) => patchstep(a, result.length - i - savedLength, 0));
318
- }
375
+ flusqueue(result, queue);
319
376
  };
320
- var _do = function (body, cx, unblock, result, tmpname) {
377
+ var _do = function (body, cx, unblock, result) {
321
378
  var o = body[cx];
322
379
  var label = o;
323
380
  o = o.next;
381
+ ifpatch(result);
324
382
  var i = result.length;
325
383
  unblock(o);
326
384
  o = o.next.next;
327
- if (label.continue) result[result.length - 1].cont = true, label.contat = result.length;
328
- var b = scanner2(`if(${getCondition(o, unblock)})return [${i - result.length},0];return [1,0]`);
329
- addresult(result, b);
385
+
386
+ if (label.continue) ifpatch(result), label.contat = result.length;
387
+ var b = scanner2(`if(${getCondition(o, unblock)})return [${i - result.length},0]`);
388
+ pushstep(result, b);
330
389
  while (body[cx] !== o) cx++;
331
- return cx;
390
+ return cx + 1;
332
391
  };
333
-
392
+ var stepReturn = function (value, type, q) {
393
+ var r = scanner2(`return [${value},${type}]`);
394
+ r.ret_ = true;
395
+ if (q && q.length) r.name = q[q.length - 1].name;
396
+ return r;
397
+ }
334
398
  var needbreak = function (o) {
335
- return o === RE || o === RZ || o === RD || o === RETURN || o === NEXT || o === YIELD;
399
+ return o && o.type === STAMP && /^[,;]$/.test(o.text) || o === RD || o == RE || o === RZ || isretn(o);
336
400
  };
401
+ var isretn = function (o) {
402
+ return o === RETURN || o === NEXT || o === YIELD || o === THROW;
403
+ }
337
404
  var _return = function (r, nextindex) {
338
405
  var name = r.name;
339
406
  var e = r[r.length - 1];
340
- if (!needbreak(e)) return;
341
- r.ifrt = true;
407
+ if (!isretn(e)) return;
342
408
  r.pop();
343
- var semicolon = r[r.length - 1];
344
- semicolon = semicolon && semicolon.type === STAMP && /^[,;]$/.test(semicolon.text);
409
+ r.ret_ = !ishalf(r);
345
410
  var x;
346
411
  if (e === RETURN) {
347
- x = scanner2(`return [${name},2]`);
412
+ x = stepReturn(name, 2);
348
413
  }
349
414
  else if (e === YIELD) {
350
- x = scanner2(`return [${name},3]`);
415
+ x = stepReturn(name, 3);
416
+ }
417
+ else if (e === THROW) {
418
+ x = scanner2(`throw ${name}`);
351
419
  }
352
420
  else if (e === NEXT) {
353
- x = scanner2(`return [${name},1]`);
354
- r.await = true;
421
+ x = stepReturn(name, 1);
422
+ r.await_ = true;
355
423
  }
356
- if (semicolon) r.pop();
357
- r.push({ type: STAMP, text: ';' });
424
+ if (needcomma(r)) r.push({ type: STAMP, text: ';' });
425
+ else if (r.length) r[r.length - 1].text = ';';
358
426
  r.push(...x);
359
427
  relink(r);
360
428
  };
@@ -362,7 +430,7 @@ var remove_end_comma = function (o) {
362
430
  if (!o.length || o.type !== SCOPED || o.entry === '[') return;
363
431
  for (var cx = o.length - 1; cx >= 0; cx--) {
364
432
  var m = o[cx];
365
- if (m.type !== SPACE && m.type !== COMMENT) {
433
+ if (!(m.type & (SPACE | COMMENT))) {
366
434
  break;
367
435
  }
368
436
  }
@@ -379,55 +447,72 @@ var _invoke = function (t, getname) {
379
447
  var cache = [];
380
448
  var queue = [];
381
449
  queue.name = t.name;
450
+ var qname = t.name;
382
451
  var bx = 0;
383
452
  for (var cx = 0; cx < t.length; cx++) {
384
453
  var o = t[cx];
385
- if (o.type === STAMP && /^[,;]$/.test(o.text)) {
386
- if (queue.length) queue.push({ type: STAMP, text: ',' });
387
- queue.push(...t.splice(bx, cx + 1));
388
- cx += bx - cx - 1;
389
- queue.pop();
454
+ if (needbreak(o)) {
455
+ if (needcomma(queue)) queue.push({ type: STAMP, text: ',' });
456
+ var s = splice(t, bx, cx + 1 - bx);
457
+ if (cx > 0) s.name = s[0].text;
458
+ else s.name = qname;
459
+ queue.push(s);
460
+ cx = bx - 1;
390
461
  bx = cx + 1;
391
462
  continue;
392
463
  }
393
464
  if (o.type === SCOPED && (o.entry === '[' || o.entry === "(")) {
394
465
  var _nameindex = nameindex;
395
466
  remove_end_comma(o);
396
- var cy = 0;
397
467
  for (var cy = 0; cy < o.length; cy++) {
468
+ if (o[cy].type & (SPACE | COMMENT)) continue;
398
469
  var by = cy;
470
+ var c = o[cy];
471
+ if (c.type & STAMP && /^[,;]$/.test(c.text)) continue;
399
472
  cy = skipAssignment(o, cy);
400
473
  if (by === cy) continue;
401
474
  var m = o.slice(by, cy);
402
- if (m.length === 1 && (m[0].type === EXPRESS && !/\./.test(m[0].text) || m[0].type === VALUE || m[0].type === QUOTED)) {
475
+ if (m.length === 1 && (m[0].type === EXPRESS && !/\./.test(m[0].text) || m[0].type === VALUE || m[0].type === QUOTED && !m[0].length)) {
403
476
  continue;
404
477
  }
405
478
  var q = toqueue(m, getdeepname, true);
406
- o.splice(by, cy, { text: getdeepname(0), type: EXPRESS });
479
+ var qe = q[q.length - 1];
480
+ o.splice(by, cy - by, { text: qe.name, type: EXPRESS });
407
481
  cy -= cy - by - 1;
408
482
  nameindex++;
409
483
  cache.push(...q);
410
484
  }
411
- if (!cache.length) continue;
412
485
  nameindex = _nameindex;
413
- if (queue.length) addresult(result, queue), queue = [], queue.name = getdeepname(nameindex);
414
- result.push(...cache);
486
+ if (!cache.length) continue;
487
+ if (queue.length) flusqueue(result, queue), queue = [];
488
+ for (var c of cache) pushstep(result, c);
415
489
  cache = [];
416
- var m = t.splice(bx, cx + 1);
417
- m.name = queue.name;
418
- cx -= m.length;
419
- if (bx + 1 < t.length && (t[bx].type & (SCOPED | EXPRESS))) t.splice(bx, 0, ...scanner2(`${getname(0)}=${getname(nameindex)}`)), t.name = getname(0);
420
- relink(m);
421
- addresult(result, m);
422
- nameindex++;
423
- bx = cx + 1;
490
+ var n = o.next;
491
+ if (n && !needbreak(n)) {
492
+ var h = snapExpressHead(o);
493
+ var hx = t.lastIndexOf(h, cx);
494
+ var fs = splice(t, hx, cx + 1 - hx, { type: EXPRESS, text: getname(nameindex) });
495
+ fs.unshift(...scanner2(`${getname(nameindex)}=`));
496
+ relink(fs);
497
+ fs.name = getname(nameindex);
498
+ pushstep(result, fs);
499
+ nameindex++;
500
+ cx = hx - 1;
501
+ }
424
502
  }
425
503
  }
426
504
  if (queue.length) {
427
- if (t.length) queue.push({ type: STAMP, text: ',' }, ...t), queue.name = t.name;
428
- addresult(result, queue);
505
+ queue.push(t);
506
+ flusqueue(result, queue);
507
+ }
508
+ else if (t.length) {
509
+ var t0 = t[0];
510
+ if (t0.type === EXPRESS && /^\./.test(t0.text) || t0.type & (STAMP | STRAP) && powermap[t0.text] < powermap.new) {
511
+ t.unshift(...scanner2(`${qname}=${qname}`));
512
+ relink(t);
513
+ }
514
+ addresult(result, t);
429
515
  }
430
- else if (t.length) addresult(result, t);
431
516
  return result;
432
517
  };
433
518
 
@@ -438,40 +523,196 @@ var _await = function (t) {
438
523
  }
439
524
  return false;
440
525
  };
526
+ var ishalf = function (q) {
527
+ var i = q.length - 1;
528
+ var e = q[i];
529
+ while (i > 0 && e.type & (SPACE | COMMENT)) e = q[--i];
530
+ if (!e) return false;
531
+ return e.type === SCOPED && e.entry === '(' && e.prev && e.prev.type === STRAP && /^if$/.test(e.prev.text) || e.type === STRAP && /^else$/.test(e.text);
532
+ }
441
533
  var needcomma = function (q) {
442
534
  if (!q.length) return false;
443
535
  var e = q[q.length - 1];
536
+ if (ishalf(q)) return false;
444
537
  return !needbreak(e);
445
538
  };
539
+ var patchname = function (d, getname) {
540
+ var de = d[d.length - 1];
541
+ if (de && !de.name) {
542
+ splice(de, 0, 0, { type: EXPRESS, text: getname(0) }, { type: STAMP, text: "=" });
543
+ de.name = getname(0);
544
+ }
545
+ }
446
546
  var ternary = function (body, getname, ret) {
547
+ var getnextname = function (i) {
548
+ return getname(i + 1);
549
+ };
447
550
  var question = [];
448
551
  var res = [];
552
+ var equalsend = 0;
553
+ var skip = 0;
554
+ var equcount = 0;
449
555
  for (var cx = 0, dx = body.length; cx < dx; cx++) {
450
556
  var o = body[cx];
451
- if (o.type == STAMP && o.text === '?') {
557
+ if (o.type === STRAP && /^(var|let|const)$/.test(o.text)) {
558
+ skip = cx + 1;
559
+ equalsend = skip;
560
+ continue;
561
+ }
562
+ if (o.type !== STAMP) continue;
563
+ if (o.text === '?') {
452
564
  question.push(cx);
453
565
  }
454
- else if (o.type === STAMP && o.text === ":") {
566
+ else if (o.text === ":") {
455
567
  var bx = question.pop();
456
568
  if (!question.length) {
457
- var b = body.slice(0, bx);
569
+ var b = body.slice(equalsend, bx);
458
570
  relink(b);
459
- var c = ternary(body.slice(bx + 1, cx), getname, true);
460
- var d = ternary(body.slice(cx + 1), getname, true);
461
- addresult(c, scanner2(`return [${d.length + 1},0]`));
571
+ var c = toqueue(body.slice(bx + 1, cx), getname, true);
572
+ var d = toqueue(body.slice(cx + 1), getname, true);
573
+ patchname(c, getname);
574
+ patchname(d, getname);
575
+ pushstep(d, stepReturn(1, 0, d));
576
+ pushstep(c, stepReturn(d.length + 1, 0, c));
462
577
  addresult(res, scanner2(`if(${getCondition(b, function (b) {
463
- addresult(res, _express(b));
464
- return res[res.length - 1];
465
- })})return [1,0]`));
466
- res.push(...c);
578
+ b = ternary(b, getname, true);
579
+ for (var b of b) addresult(res, b);
580
+ return b;
581
+ }, true)})return [1,0]`));
582
+ var q = res[res.length - 1];
583
+ var qi = res.length - 1;
584
+ var qe = q[q.length - 1];
585
+ if (c.length) {
586
+ pushstep(res, c[0]);
587
+ res.push(...c.slice(1));
588
+ }
589
+ qe.text = String(res.length - qi);
467
590
  res.push(...d);
468
591
  }
469
592
  }
593
+ else if (powermap[o.text] === powermap["="]) {
594
+ if (!question.length) equalsend = cx + 1, equcount += o.text.length;
595
+ }
470
596
  }
471
- if (!res.length) return _express(body, getname, ret);
472
- return res;
597
+ if (!res.length) {
598
+ var bd = equalsend ? body.slice(equalsend) : body;
599
+ if (!ret && equcount === 1 && canbeOnce(bd)) {
600
+ res = [bd];
601
+ }
602
+ else {
603
+ res = _express(bd, getname, equalsend > skip || ret);
604
+ }
605
+ }
606
+ if (equalsend === skip) {
607
+ return res;
608
+ }
609
+ var equals = body.slice(skip, equalsend);
610
+ var explist = res;
611
+ var q = explist[explist.length - 1];
612
+ // if (!q) throw `语法错误: <red>${createString(body)}</red> \r\n行列位置: ${equals[0].row}:${equals[0].col}`
613
+ var n = q.name;
614
+ var i = equals.length - 1;
615
+ while (i >= 0) {
616
+ var p = equals[i];
617
+ while (p && p.type & (SPACE | COMMENT)) p = equals[--i];
618
+ if (!p) break;
619
+ var a = p.prev;
620
+ var b = snapExpressHead(a);
621
+ if (b) {
622
+ var ai = equals.lastIndexOf(b, i);
623
+ }
624
+ else {
625
+ var ai = equals.lastIndexOf(a, i);
626
+ }
627
+ if (ai < 0) ai = 0;
628
+ var ass = equals.slice(ai, i);
629
+ if (n) var asn = [{ type: EXPRESS, text: n }];
630
+ else asn = explist.pop();
631
+ for (var a of ass) {
632
+ if (a.type === SCOPED) {
633
+ if (a.entry === '[') {
634
+ var q = _express(a, getnextname, true);
635
+ for (var q of q) {
636
+ if (q.length) pushstep(explist, q);
637
+ }
638
+ splice(a, 0, a.length, { type: EXPRESS, text: q.name });
639
+ }
640
+ else if (a.entry === '(') {
641
+ _invoke(a);
642
+ }
643
+ }
644
+ }
645
+ var an = '';
646
+ var eq = equals[i];
647
+ if (eq.text.length > 1) {
648
+ var punc = eq.text.slice(0, eq.text.length - 1);
649
+ var bdtmp = ass.concat({ type: STAMP, text: punc }, ...asn);
650
+ var explist2 = _express(bdtmp, getname, true);
651
+ for (var e of explist2) pushstep(explist, e);
652
+ eq.text = "=";
653
+ var q2 = explist2[explist2.length - 1];
654
+ an = q2.name;
655
+ }
656
+ else an = n;
657
+ ass.push(equals[i], ...asn);
658
+ relink(ass);
659
+ if (evals.length) ass[0].set = getname(0);
660
+ ass.name = an;
661
+ patchstep(ass, ass.length, 0);
662
+ pushstep(explist, ass);
663
+ i = ai - 1;
664
+ n = an;
665
+ }
666
+ return explist;
667
+ };
668
+ var canbeOnce = function (body) {
669
+ for (var cx = 0, dx = body.length; cx < dx; cx++) {
670
+ if (body[cx].type & (SPACE | COMMENT)) continue;
671
+ break;
672
+ }
673
+ var o = body[cx];
674
+ var n = snapExpressFoot(o);
675
+ var bx = cx;
676
+ cx = n ? body.lastIndexOf(n) + 1 : body.length;
677
+ if (cx < 0) return false;
678
+ for (; cx < dx; cx++) {
679
+ if (body[cx].type & (SPACE | COMMENT)) continue;
680
+ return false;
681
+ }
682
+ for (cx = bx; cx < dx; cx++) {
683
+ var o = body[cx];
684
+ if (o.type & (SPACE | COMMENT)) continue;
685
+ if (o.type & (EXPRESS | VALUE) || o.type === QUOTED && !o.length || o.type === SCOPED && o.entry === "[" && canbeTemp(o)) {
686
+ continue;
687
+ }
688
+ return false;
689
+ }
690
+ return true;
691
+ };
692
+ var canbeTemp = function (body) {
693
+ var cx = 0, dx = body.length - 1;
694
+ while (cx < dx) {
695
+ if (body[cx].type & (SPACE | COMMENT)) {
696
+ cx++;
697
+ continue;
698
+ }
699
+ if (body[dx].type & (SPACE | COMMENT)) {
700
+ dx--;
701
+ continue;
702
+ }
703
+ break;
704
+ }
705
+ if (body[cx] !== body[dx]) return false;
706
+ var o = body[cx];
707
+ if (!o) return false;
708
+ return o.type === EXPRESS && !/[\.\[]/.test(o.text) || o.type === VALUE || o.type === QUOTED && !o.length;
473
709
  };
474
710
  var _express = function (body, getname, ret) {
711
+ if (canbeTemp(body)) {
712
+ var q = [];
713
+ q.name = createString(body);
714
+ return [q];
715
+ }
475
716
  var result = [];
476
717
  var q = [];
477
718
  var needpunc = false;
@@ -480,25 +721,23 @@ var _express = function (body, getname, ret) {
480
721
  var n = null;
481
722
  var nameindex = 0;
482
723
  var maxindex = 0;
724
+ var hasor = false;
483
725
  var getdeepname = function (deep = 0) {
484
726
  return getname(maxindex + deep);
485
727
  };
486
- var ax = 0;
487
728
  var exps = [];
488
729
  for (var cx = 0, dx = body.length; cx < dx; cx++) {
730
+ if (!(body[cx].type & (COMMENT | SPACE))) { bx = cx; break; }
731
+ }
732
+ for (; cx < dx; cx++) {
489
733
  var o = body[cx];
490
734
  if (o.type & (COMMENT | SPACE)) continue;
491
- if (o.type === STRAP && /^(var|let|const)/.test(o.text)) {
492
- bx = cx + 1;
735
+ if (o.type === STRAP && o.text === 'function') {
736
+ while (o && (o.type !== SCOPED || o.entry !== '{')) o = body[++cx];
493
737
  continue;
494
738
  }
495
739
  if (o.type & (STRAP | STAMP)) {
496
740
  var p = 0;
497
- if (o.text === '=') {
498
- ax = exps.length;
499
- bx = cx + 1;
500
- continue;
501
- }
502
741
  if (/[!~]|\+\-|\-\+/.test(o.text)) p = powermap["!"];
503
742
  if (!p && /[\+\-]/.test(o.text)) p = needpunc ? powermap["+"] : powermap["!"];
504
743
  if (!p) p = powermap[o.text];
@@ -506,7 +745,8 @@ var _express = function (body, getname, ret) {
506
745
  var b = body.slice(bx, cx + 1);
507
746
  bx = cx + 1;
508
747
  b.index = nameindex;
509
- if (!cache.length || p > cache[cache.length - 1]) {
748
+ var isor = p === powermap["||"];
749
+ if (!isor) if (!cache.length || p > cache[cache.length - 1] || p >= powermap.new) {
510
750
  cache.push(b, p);
511
751
  continue;
512
752
  }
@@ -514,8 +754,11 @@ var _express = function (body, getname, ret) {
514
754
  var n = scanner2(name);
515
755
  q.name = name;
516
756
  n.index = nameindex;
517
- nameindex = cache[cache.length - 2].index;
518
757
  n.push(b.pop());
758
+
759
+ if (cache.length) nameindex = cache[cache.length - 2].index;
760
+ else if (isor) n.pop(), q.push(...scanner2(`${getname(nameindex)}=`), ...b);
761
+
519
762
  while (cache.length && cache[cache.length - 1] >= p) {
520
763
  if (needcomma(q)) q.push({ type: STAMP, text: ',' });
521
764
  var p0 = cache.pop();
@@ -528,7 +771,7 @@ var _express = function (body, getname, ret) {
528
771
  }
529
772
  nameindex++;
530
773
  if (maxindex < nameindex) maxindex = nameindex;
531
- if (p == powermap["||"]) {
774
+ if (isor) {
532
775
  if (o.text === '||') {
533
776
  q.push(RE);
534
777
  }
@@ -538,6 +781,7 @@ var _express = function (body, getname, ret) {
538
781
  else if (o.text === '??') {
539
782
  q.push(RD);
540
783
  }
784
+ hasor = true;
541
785
  nameindex = 0;
542
786
  } else {
543
787
  cache.push(n, p);
@@ -558,15 +802,19 @@ var _express = function (body, getname, ret) {
558
802
  nameindex = cache[cache.length - 1].index;
559
803
  var t = cache.pop();
560
804
  var isawait = _await(t, nameindex);
561
- if (p > powermap["="] && (ret || ax >= 1 || cache.length > 0 || isawait)) q.push(...scanner2(`${getname(nameindex)}=`));
562
- q.push.apply(q, t);
563
- q.push.apply(q, b);
805
+ if (!t.length && canbeTemp(b) && b[0].text === getname(nameindex)) {
806
+ }
807
+ else {
808
+ if (p > powermap["="] && (ret || cache.length > 0 || isawait)) q.push(...scanner2(`${getname(nameindex)}=`));
809
+ q.push.apply(q, t);
810
+ q.push.apply(q, b);
811
+ }
564
812
  if (isawait) q.push(NEXT);
565
813
  needname = true;
566
814
  b = [{ type: EXPRESS, text: getname(nameindex) }];
567
815
  }
568
- else if (ax !== 1) {
569
- if (ret && b.length || ax > 1) {
816
+ else {
817
+ if (ret && b.length) {
570
818
  q.push(...scanner2(`${getname(nameindex)}=`));
571
819
  q.push(...b);
572
820
  needname = true;
@@ -576,133 +824,103 @@ var _express = function (body, getname, ret) {
576
824
  }
577
825
  }
578
826
  if (needname) q.name = getname(nameindex);
579
- if (ax === 1) {
580
- if (q.length) q.push({ type: STAMP, text: ';' });
581
- q.push(exps[0], { type: STAMP, text: "=" });
582
- q.push(...b);
583
- q.name = exps[0].text;
584
- if (evals.length) exps[0].set = getname(nameindex);
585
- exps.shift();
586
- }
587
- if (ax > 1) {
588
- while (ax > 0) {
589
- q.push({ type: STAMP, text: ';' });
590
- var [e] = exps.splice(ax - 1, 1);
591
- if (evals.length) e.set = getname(nameindex + 1);
592
- q.push(e);
593
- q.push(...scanner2(`=${getname(nameindex)}`))
594
- ax--;
595
- }
596
- }
597
- if (evals.length && exps.length) for (var cx = q.length - 1; cx >= 0; cx--) {
598
- var o = q[cx];
599
- if (o.type !== EXPRESS) continue;
600
- if (o === exps[exps.length - 1]) {
601
- exps.pop();
602
- o.get = true;
603
- if (!exps.length) {
604
- break;
605
- }
606
- }
607
- }
608
827
  relink(q);
609
- return _invoke(q, getdeepname);
828
+ result = _invoke(q, getdeepname);
829
+ if (hasor) result[result.length - 1].ret_ = true;
830
+ return result;
610
831
  };
611
832
 
612
833
  var getblock = function (body, cx) {
613
834
  var o = body[cx];
614
- if (o.type === SCOPED && o.entry === '{') return [o];
835
+ if (o && o.type === SCOPED && o.entry === '{') return [o];
836
+ if (!o || o.type === STAMP && /^[;:]$/.test(o.text)) return [];
615
837
  var ax = cx;
616
- do {
838
+ while (o) {
617
839
  cx = skipAssignment(body, cx);
618
840
  var o = body[cx];
619
841
  if (!o || o.type !== STAMP || o.text !== ',') break;
620
842
  cx++;
621
- } while (o);
622
- return body.slice(ax, cx);
843
+ }
844
+ var b = body.slice(ax, cx);
845
+ b.next = o;
846
+ return b;
623
847
  };
624
848
  var labels = [];
625
849
  var scopes = [];
626
850
  var isbreak = function (o) {
627
- return o.type === STRAP && /^(break|return|continue|yield)$/.test(o.text);
851
+ if (o.type !== STRAP) return false;
852
+ return /^(break|continue)$/.test(o.text) ||
853
+ /^(yield|return)$/.test(o.text) && (o.isend || skipAssignment(o.next) === o.next.next && canbeTemp([o.next]));
628
854
  };
629
855
 
630
- function toqueue(body, getname, ret = false) {
631
- var retn = false;
632
- var ifpatch = function () {
633
- var re = scanner2(`return [1,0]`);
634
- re.awaited = true;
635
- addresult(result, re);
856
+ var ifpatch = function (result, autoskip) {
857
+ if (!result.length) return;
858
+ if (autoskip !== false) {
859
+ var rs = result[result.length - 1];
860
+ if (rs.ret_ && !rs.await_) return;
636
861
  }
862
+ var re = stepReturn(1, 0);
863
+ pushstep(result, re);
864
+ };
865
+ function toqueue(body, getname, ret = false, result = []) {
866
+ var retn = false;
637
867
  var uniftop = function () {
638
- for (var cx = 3, dx = iftop.length; cx < dx; cx += 3) {
639
- var findex = iftop[cx];
640
- var r = iftop[cx + 1];
641
- var p = result[findex - 1];
642
- if (!r) {
643
- p.pop();
644
- p.push(...scanner2(`[${result.length + 1 - findex},0]`));
645
- relink(p);
646
- }
868
+ for (var cx = 4, dx = iftop.length; cx < dx; cx += 4) {
869
+ var isbr = iftop[cx - 3];
870
+ if (isbr) continue;
871
+ var findex = iftop[cx] - 1;
872
+ var p = result[findex];
873
+ p.pop();
874
+ p.push(scanner2(`[${result.length - findex},0]`)[0]);
875
+ relink(p);
647
876
  }
648
- for (var cx = 0, dx = iftop.length - 2; cx < dx;) {
649
- var findex = iftop[cx++];
650
- var f = result[findex];
651
- var r = iftop[cx++];
652
- var n = iftop[cx++];
653
- if (r) {
654
- var c = scanner2(`if(${n})`);
655
- f.unshift.apply(f, c);
656
- relink(f);
657
- }
658
- else if (f) {
659
- var c = scanner2(`if(${n})return [${iftop.length > cx ? iftop[cx] - findex : result.length - findex},0];`);
660
- f.unshift.apply(f, c);
661
- relink(f);
877
+ for (var cx = 1, dx = iftop.length - 2; cx < dx; cx++) {
878
+ var isbr = iftop[cx++];
879
+ var ce = iftop[cx++];
880
+ var cindex = iftop[cx++];
881
+ var findex = iftop[cx] ? iftop[cx] : result.length;
882
+ if (!isbr) {
883
+ ce[0].text = findex - cindex;
884
+ relink(ce);
662
885
  }
663
886
  };
664
887
  };
665
- var unblock = function (block, ...end) {
666
- var c = toqueue(block, getname, true);
667
- bx = cx + 1;
668
- if (c.length > 0) {
669
- c.forEach(q => {
670
- if (q.length) result.push(q);
671
- });
672
- if (end.length) {
673
- var q = c[c.length - 1];
674
- q.push(...end);
675
- relink(q);
676
- }
677
- }
888
+ var unblock = function (block) {
889
+ toqueue(block, getname, true, result);
678
890
  return result[result.length - 1];
679
891
  };
680
892
  var poplabel = function () {
893
+ if (!labels.length) return;
681
894
  var e = labels.pop();
682
895
  if (e.breaks) {
683
896
  while (e.breaks.length) {
684
897
  var b = e.breaks.pop();
685
- var end = b[b.length - 1];
898
+ var end = b;
686
899
  for (var cx = result.length - 1; cx >= 0; cx--) {
687
900
  var r = result[cx];
688
- if (r[r.length - 1] === end) { break }
901
+ if (r.indexOf(b) >= 0) { break }
689
902
  }
690
- end.push({ type: VALUE, text: b.contat - cx ? b.continue : result.length - cx }, { type: STAMP, text: "," }, { type: VALUE, text: "0" });
903
+ end.push({ type: VALUE, text: b.continue ? b.continue.contat - cx : result.length - cx }, { type: STAMP, text: "," }, { type: VALUE, text: "0" });
691
904
  relink(end);
692
905
  }
693
906
  }
694
907
  };
695
-
696
- var result = [];
697
908
  var cx = 0, bx = 0;
698
909
  var iftop = null;
910
+ var brk = function (text, YIELD) {
911
+ if (o.text !== text) return;
912
+ retn = [YIELD];
913
+ ret = true;
914
+ bx = ++cx;
915
+ return retn;
916
+ };
699
917
  do {
700
- while (cx < body.length && (body[cx].type === SPACE || body[cx].type === COMMENT)) cx++;
701
918
  var o = body[cx];
919
+ while (o && (o.type & (SPACE | COMMENT) || o.type === STAMP && /^[,;]$/.test(o.text))) o = body[++cx];
702
920
  if (!o) break;
703
921
  while (labels.length) {
704
922
  var e = labels[labels.length - 1];
705
- if (e.type !== LABEL && !iftop) break;
923
+ if (e.type !== LABEL) break;
706
924
  if (scopes.lastIndexOf(e.scope) >= 0) break;
707
925
  poplabel();
708
926
  }
@@ -710,106 +928,103 @@ function toqueue(body, getname, ret = false) {
710
928
  if (o.type === LABEL) {
711
929
  o.scope = scopes[scopes.length - 1];
712
930
  labels.push(o);
931
+ bx = ++cx;
713
932
  continue;
714
933
  }
715
- if (o.type === SCOPED && o.entry === '{' && !o.isExpress) {
934
+ if (o.type === SCOPED && o.entry === '{' && !o.isObject) {
716
935
  scopes.push(o);
717
- var b = toqueue(o, getname, false);
936
+ toqueue(o, getname, false, result);
718
937
  scopes.pop();
719
- // addresult(result, b);
720
- result.push.apply(result, b);
721
- cx++;
722
- bx = cx;
938
+ bx = ++cx;
723
939
  continue;
724
940
  }
725
941
  a: if (o.type === STRAP) {
726
- if (/^(new|typeof|await)$/.test(o.text)) {
727
- break a;
728
- }
729
- if (o.text === 'yield') {
730
- retn = [YIELD];
731
- ret = true;
732
- bx = cx + 1;
733
- cx++;
942
+ if (/^(new|typeof|await|delete|void|debugger)$/.test(o.text)) {
734
943
  break a;
735
944
  }
736
- if (o.text === 'return') {
737
- retn = [RETURN];
738
- ret = true;
739
- bx = cx + 1;
740
- cx++;
741
- break a;
742
- }
743
- if (/^(async|function)$/.test(o.text)) {
744
- cx = skipAssignment(body, cx);
745
- addresult(result, body.slice(bx, cx));
746
- bx = cx + 1;
945
+ if (brk("yield", YIELD)) break a;
946
+ if (brk("return", RETURN)) break a;
947
+ if (brk("throw", THROW)) break a;
948
+ if (/^(async|function|class)$/.test(o.text)) {
949
+ // cx = skipAssignment(body, cx);
950
+ // var f = body.slice(bx, cx);
951
+
952
+ // addresult(result, f);
953
+ // bx = cx + 1;
747
954
  break a;
748
955
  }
749
956
  if (/^(break|continue)$/.test(o.text)) {
750
957
  cx = _break(body, cx, result, o.text === 'continue');
751
- bx = cx + 1;
958
+ bx = cx;
752
959
  continue;
753
960
  };
754
961
  if (o.text === 'with') {
755
962
  cx = _with(body, cx, unblock, result, getname);
756
- bx = cx + 1;
963
+ bx = cx;
757
964
  continue;
758
965
  }
759
966
  if (o.text === 'try') {
760
967
  cx = _try(body, cx, unblock, result, getname);
761
- bx = cx + 1;
968
+ bx = cx;
762
969
  continue;
763
970
  }
764
971
  if (o.text === 'for') {
765
972
  labels.push(o);
766
- cx = _for(body, cx, unblock, result, getname(0));
973
+ cx = _for(body, cx, unblock, result);
767
974
  poplabel();
768
- bx = cx + 1;
975
+ bx = cx;
769
976
  continue;
770
977
  }
771
978
  if (o.text === 'while') {
772
979
  labels.push(o);
773
- cx = _while(body, cx, unblock, result, getname(0));
980
+ cx = _while(body, cx, unblock, result);
774
981
  poplabel();
775
- bx = cx + 1;
982
+ bx = cx;
776
983
  continue;
777
984
  }
778
985
  if (o.text === 'do') {
779
986
  labels.push(o);
780
- cx = _do(body, cx, unblock, result, getname(0));
987
+ cx = _do(body, cx, unblock, result);
781
988
  poplabel();
782
- bx = cx + 1;
989
+ bx = cx;
783
990
  continue;
784
991
  }
785
992
  if (o.text === 'switch') {
786
993
  labels.push(o);
787
994
  cx = _switch(body, cx, unblock, result, getname);
788
995
  poplabel();
789
- bx = cx + 1;
996
+ bx = cx;
790
997
  continue;
791
998
  }
792
- var elseif = false;
999
+ var elseif = false, isbr = false;
793
1000
  if (o.text === 'else') {
794
- ifpatch();
795
1001
  while (body[cx] !== o.next) cx++;
796
1002
  o = o.next;
797
- var isbr = isbreak(o);
798
- iftop.push(result.length, isbr);
1003
+ isbr = isbreak(o);
1004
+ if (!isbr) ifpatch(result);
1005
+ iftop.push(result.length);
799
1006
  elseif = true;
800
1007
  }
801
1008
  if (o.text === 'if') {
802
1009
  while (body[cx] !== o.next) cx++;
803
1010
  o = o.next;
804
1011
  var isbr = isbreak(o.next);
1012
+ var i = result.length;
805
1013
  var n = getCondition(o, unblock, !isbr);
806
1014
  o = o.next;
1015
+ if (isbr) {
1016
+ var c = scanner2(`if(${n})`);
1017
+ }
1018
+ else {
1019
+ var c = scanner2(`if(${n})return [0,0]`);
1020
+ }
1021
+ var ce = c[3];
1022
+ pushstep(result, c);
807
1023
  if (!elseif) {
808
- if (iftop) uniftop();
809
- iftop = [result.length, isbr, n];
1024
+ iftop = [i, isbr, ce, result.length - 1];
810
1025
  }
811
1026
  else {
812
- iftop.push(n);
1027
+ iftop.push(isbr, ce, result.length - 1);
813
1028
  }
814
1029
  elseif = true;
815
1030
  }
@@ -818,28 +1033,39 @@ function toqueue(body, getname, ret = false) {
818
1033
  var block = getblock(body, cx);
819
1034
  cx += block.length;
820
1035
  o = body[cx];
1036
+ while (o && o.type & (SPACE | COMMENT)) o = body[++cx];
821
1037
  unblock(block);
822
1038
  if (o && o.type === STAMP && o.text === ';') o = o.next;
823
- while (body[cx] !== o) cx++;
1039
+ while (cx < body.length && body[cx] !== o) cx++;
824
1040
  if (!o || o.type !== STRAP || o.text !== 'else') {
1041
+ var bn = body.next;
1042
+ if (bn && bn.type === STAMP && bn.text === ';') bn = bn.next;
1043
+ var inif = bn && bn.type === STRAP && bn.text === 'else';
1044
+ if (inif) ifpatch(result);
1045
+ else if (!isbr) ifpatch(result);
825
1046
  uniftop();
1047
+ if (inif) ifpatch(result, false);
826
1048
  iftop = null;
827
1049
  }
828
1050
  }
829
1051
  else {
830
1052
  cx++;
831
1053
  }
1054
+ bx = cx;
832
1055
  continue;
833
1056
  }
834
1057
  cx = skipAssignment(body, cx);
835
1058
  var b = body.slice(bx, cx);
836
- cx++;
837
- bx = cx;
1059
+ bx = ++cx;
838
1060
  b = ternary(b, getname, ret);
839
- result.push(...b);
1061
+ for (var a of b) pushstep(result, a);
840
1062
  if (retn) {
841
- retn.name = b[b.length - 1].name;
842
- addresult(result, retn);
1063
+ if (b.length) retn.name = b[b.length - 1].name;
1064
+ pushstep(result, retn);
1065
+ }
1066
+ else {
1067
+ var q = b[b.length - 1];
1068
+ if (q && !q.length && q.name) pushstep(result, scanner2(q.name));
843
1069
  }
844
1070
  retn = false;
845
1071
  } while (cx < body.length);