bobe 0.0.26 → 0.0.28
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.
- package/dist/bobe.cjs.js +271 -88
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +272 -89
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.umd.js +271 -88
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -157,6 +157,47 @@ class MultiTypeStack {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
function macInc(arr) {
|
|
161
|
+
const len = arr.length;
|
|
162
|
+
let candyLast = [],
|
|
163
|
+
i = 0;
|
|
164
|
+
while (i < len) {
|
|
165
|
+
const it = arr[i];
|
|
166
|
+
if (it !== -1) {
|
|
167
|
+
candyLast = [i];
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
i++;
|
|
171
|
+
}
|
|
172
|
+
if (i + 1 >= len) return candyLast;
|
|
173
|
+
const toPrev = new Int32Array(len);
|
|
174
|
+
while (i < len) {
|
|
175
|
+
const target = arr[i];
|
|
176
|
+
if (target === -1) continue;
|
|
177
|
+
let start = -1,
|
|
178
|
+
end = candyLast.length;
|
|
179
|
+
while (start + 1 < end) {
|
|
180
|
+
const mid = start + end >> 1;
|
|
181
|
+
if (arr[candyLast[mid]] < target) {
|
|
182
|
+
start = mid;
|
|
183
|
+
} else {
|
|
184
|
+
end = mid;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
candyLast[end] = i;
|
|
188
|
+
toPrev[i] = candyLast[start];
|
|
189
|
+
i++;
|
|
190
|
+
}
|
|
191
|
+
let length = candyLast.length;
|
|
192
|
+
for (let j = length - 1; j > 0; j--) {
|
|
193
|
+
const prev = toPrev[candyLast[j]];
|
|
194
|
+
candyLast[j - 1] = prev;
|
|
195
|
+
}
|
|
196
|
+
return candyLast;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const KEY_INDEX = '__BOBE_KEY_INDEX';
|
|
200
|
+
|
|
160
201
|
const _excluded = ["dentStack", "isFirstToken"];
|
|
161
202
|
class Interpreter {
|
|
162
203
|
constructor(tokenizer) {
|
|
@@ -209,6 +250,9 @@ class Interpreter {
|
|
|
209
250
|
if (ctx.current.__logicType) {
|
|
210
251
|
if (isLogicNode) {
|
|
211
252
|
aoye.setPulling(ctx.current.effect);
|
|
253
|
+
if (ctx.current.__logicType & FakeType.ForItem) {
|
|
254
|
+
ctx.prevSibling = ctx.current.realBefore;
|
|
255
|
+
}
|
|
212
256
|
}
|
|
213
257
|
} else {
|
|
214
258
|
if (ctx.current) {
|
|
@@ -259,8 +303,8 @@ class Interpreter {
|
|
|
259
303
|
this.tokenizer.resume(snapshot);
|
|
260
304
|
this.tokenizer.nextToken();
|
|
261
305
|
this.tokenizer.nextToken();
|
|
262
|
-
ctx.prevSibling = parent;
|
|
263
306
|
ctx.current = forNode.children[++forNode.i];
|
|
307
|
+
ctx.prevSibling = ctx.current.realBefore;
|
|
264
308
|
continue;
|
|
265
309
|
}
|
|
266
310
|
ctx.prevSibling = forNode.prevSibling;
|
|
@@ -364,21 +408,25 @@ class Interpreter {
|
|
|
364
408
|
this.tokenizer.nextToken();
|
|
365
409
|
const itemToken = this.tokenizer.nextToken();
|
|
366
410
|
const isDestruct = itemToken.type === TokenType.InsertionExp;
|
|
367
|
-
let itemExp = itemToken.value
|
|
411
|
+
let itemExp = itemToken.value,
|
|
412
|
+
vars;
|
|
368
413
|
if (isDestruct) {
|
|
369
414
|
itemExp = '{' + itemExp + '}';
|
|
370
|
-
|
|
371
|
-
|
|
415
|
+
vars = itemExp.match(bobeShared.jsVarRegexp);
|
|
416
|
+
const varStr = vars.join(',');
|
|
417
|
+
itemExp = new Function(itemExp, `return {${varStr}};`);
|
|
372
418
|
}
|
|
373
|
-
let indexName,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
419
|
+
let indexName,
|
|
420
|
+
keyExp,
|
|
421
|
+
char = this.tokenizer.peekChar();
|
|
422
|
+
if (char === ';') {
|
|
423
|
+
this.tokenizer.nextToken();
|
|
424
|
+
if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
|
|
425
|
+
} else if (char === '\n') ; else {
|
|
426
|
+
indexName = this.tokenizer.nextToken().value;
|
|
427
|
+
if (this.tokenizer.peekChar() === ';') {
|
|
428
|
+
this.tokenizer.nextToken();
|
|
429
|
+
if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
|
|
382
430
|
}
|
|
383
431
|
}
|
|
384
432
|
const owner = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
|
|
@@ -391,12 +439,14 @@ class Interpreter {
|
|
|
391
439
|
realBefore: prevSibling?.realAfter || prevSibling,
|
|
392
440
|
realAfter: null,
|
|
393
441
|
arr: null,
|
|
442
|
+
arrSignal: null,
|
|
394
443
|
itemExp,
|
|
395
444
|
indexName,
|
|
396
445
|
getKey: null,
|
|
397
446
|
children: [],
|
|
398
447
|
effect: null,
|
|
399
448
|
owner,
|
|
449
|
+
vars,
|
|
400
450
|
i: 0
|
|
401
451
|
};
|
|
402
452
|
if (keyExp) {
|
|
@@ -407,6 +457,7 @@ class Interpreter {
|
|
|
407
457
|
const cells = data[aoye.Keys.Meta].cells;
|
|
408
458
|
const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
|
|
409
459
|
const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new aoye.Computed(this.getFn(data, arrExp));
|
|
460
|
+
forNode.arrSignal = arrSignal;
|
|
410
461
|
forNode.realAfter = this.insertAfterAnchor('for-after');
|
|
411
462
|
const _forNode$snapshot = forNode.snapshot;
|
|
412
463
|
_forNode$snapshot.dentStack;
|
|
@@ -414,26 +465,23 @@ class Interpreter {
|
|
|
414
465
|
const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
|
|
415
466
|
let isFirstRender = true;
|
|
416
467
|
forNode.effect = new aoye.Effect(() => {
|
|
417
|
-
let arr =
|
|
468
|
+
let arr = arrSignal.get();
|
|
418
469
|
arr[aoye.Keys.Iterator];
|
|
419
|
-
|
|
470
|
+
const prevCtx = aoye.getPulling();
|
|
471
|
+
aoye.setPulling(null);
|
|
472
|
+
forNode.arr = arr = aoye.toRaw(arr);
|
|
420
473
|
const children = forNode.children;
|
|
421
474
|
if (isFirstRender) {
|
|
422
475
|
const len = arr.length;
|
|
423
476
|
for (let i = len; i--;) {
|
|
424
|
-
const nextItem = children[i + 1];
|
|
425
477
|
const item = this.createForItem(forNode, i, data);
|
|
426
|
-
|
|
427
|
-
item.
|
|
428
|
-
if (nextItem) {
|
|
429
|
-
nextItem.realBefore = anchor;
|
|
430
|
-
}
|
|
478
|
+
item.realAfter = this.insertAfterAnchor('for-item-after');
|
|
479
|
+
item.realBefore = this.insertAfterAnchor('for-item-before');
|
|
431
480
|
item.realParent = forNode.realParent;
|
|
432
481
|
children[i] = item;
|
|
433
482
|
}
|
|
434
483
|
const firstInsert = children[0];
|
|
435
484
|
if (firstInsert) {
|
|
436
|
-
firstInsert.realBefore = forNode.realBefore;
|
|
437
485
|
this.tokenizer.nextToken();
|
|
438
486
|
this.tokenizer.nextToken();
|
|
439
487
|
} else {
|
|
@@ -447,65 +495,214 @@ class Interpreter {
|
|
|
447
495
|
if (!forNode.getKey) {
|
|
448
496
|
if (newLen < oldLen) {
|
|
449
497
|
for (let i = oldLen - 1; i >= newLen; i--) {
|
|
450
|
-
|
|
451
|
-
this.removeLogicNode(child);
|
|
452
|
-
this.remove(child.realAfter);
|
|
453
|
-
child.effect.dispose();
|
|
498
|
+
this.removeForItem(children, i);
|
|
454
499
|
}
|
|
455
500
|
}
|
|
456
501
|
if (oldLen < newLen) {
|
|
457
502
|
const lastAfter = children.at(-1)?.realAfter || forNode.realBefore;
|
|
458
503
|
for (let i = newLen - 1; i >= oldLen; i--) {
|
|
459
|
-
|
|
460
|
-
newChildren[i] = item;
|
|
461
|
-
const nextItem = newChildren[i + 1];
|
|
462
|
-
const anchor = this.createAnchor('for-item-after');
|
|
463
|
-
this.insertAfter(forNode.realParent, anchor, lastAfter);
|
|
464
|
-
item.realAfter = anchor;
|
|
465
|
-
if (nextItem) {
|
|
466
|
-
nextItem.realBefore = anchor;
|
|
467
|
-
}
|
|
468
|
-
item.realParent = forNode.realParent;
|
|
469
|
-
this.tokenizer = owner.tokenizer;
|
|
470
|
-
this.tokenizer.resume(snapshotForUpdate);
|
|
471
|
-
this.tokenizer.useDedentAsEof = false;
|
|
472
|
-
aoye.runWithPulling(() => {
|
|
473
|
-
this.program(forNode.realParent, forNode.owner, lastAfter, item);
|
|
474
|
-
}, item.effect);
|
|
475
|
-
}
|
|
476
|
-
const firstInsert = newChildren[oldLen];
|
|
477
|
-
if (firstInsert) {
|
|
478
|
-
firstInsert.realBefore = lastAfter;
|
|
504
|
+
this.insertForItem(forNode, i, data, newChildren, lastAfter, snapshotForUpdate);
|
|
479
505
|
}
|
|
480
506
|
}
|
|
481
507
|
for (let i = minLen; i--;) {
|
|
482
508
|
const child = children[i];
|
|
483
509
|
newChildren[i] = child;
|
|
484
|
-
|
|
485
|
-
|
|
510
|
+
this.reuseForItem(child, arr[i], itemExp, i, indexName);
|
|
511
|
+
}
|
|
512
|
+
} else {
|
|
513
|
+
let s = 0,
|
|
514
|
+
e1 = oldLen - 1,
|
|
515
|
+
e2 = newLen - 1;
|
|
516
|
+
while (s <= e1 && s <= e2) {
|
|
517
|
+
const child = children[s];
|
|
518
|
+
const old = child.key;
|
|
519
|
+
const itemData = this.getItemData(forNode, s, data);
|
|
520
|
+
const key = forNode.getKey(itemData);
|
|
521
|
+
if (old === key) {
|
|
522
|
+
newChildren[s] = child;
|
|
523
|
+
this.reuseForItem(child, arr[s], itemExp, s, indexName);
|
|
524
|
+
s++;
|
|
525
|
+
} else {
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
while (s <= e1 && s <= e2) {
|
|
530
|
+
const child = children[e1];
|
|
531
|
+
const old = child.key;
|
|
532
|
+
const itemData = this.getItemData(forNode, e2, data);
|
|
533
|
+
const key = forNode.getKey(itemData);
|
|
534
|
+
if (old === key) {
|
|
535
|
+
newChildren[e2] = child;
|
|
536
|
+
this.reuseForItem(child, arr[e2], itemExp, e2, indexName);
|
|
537
|
+
e1--;
|
|
538
|
+
e2--;
|
|
486
539
|
} else {
|
|
487
|
-
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
if (s > e1) {
|
|
544
|
+
if (s <= e2) {
|
|
545
|
+
const firstBefore = s > 0 ? children.at(-1)?.realAfter || forNode.realBefore : forNode.realBefore;
|
|
546
|
+
for (let i = e2; i >= s; i--) {
|
|
547
|
+
this.insertForItem(forNode, i, data, newChildren, firstBefore, snapshotForUpdate);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
} else if (s > e2) {
|
|
551
|
+
if (s <= e1) {
|
|
552
|
+
for (let i = e1; i >= s; i--) {
|
|
553
|
+
this.removeForItem(children, i);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
} else {
|
|
557
|
+
let s1 = s,
|
|
558
|
+
s2 = s;
|
|
559
|
+
const mixLen = e2 - s2 + 1;
|
|
560
|
+
const key2new = new Map();
|
|
561
|
+
for (let i = s2; i <= e2; i++) {
|
|
562
|
+
const itemData = this.getItemData(forNode, i, data);
|
|
563
|
+
const key = forNode.getKey(itemData);
|
|
564
|
+
key2new.set(key, i);
|
|
565
|
+
}
|
|
566
|
+
let maxIncNewI = -1;
|
|
567
|
+
let hasMove = false;
|
|
568
|
+
const new2oldI = new Array(mixLen).fill(-1);
|
|
569
|
+
for (let i = s1; i <= e1; i++) {
|
|
570
|
+
const key = children[i].key;
|
|
571
|
+
const newI = key2new.get(key);
|
|
572
|
+
if (newI == null) {
|
|
573
|
+
this.removeForItem(children, i);
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const child = children[i];
|
|
577
|
+
newChildren[newI] = child;
|
|
578
|
+
this.reuseForItem(child, arr[newI], itemExp, newI, indexName);
|
|
579
|
+
new2oldI[newI - s2] = i;
|
|
580
|
+
key2new.delete(key);
|
|
581
|
+
if (newI < maxIncNewI) {
|
|
582
|
+
hasMove = true;
|
|
583
|
+
} else {
|
|
584
|
+
maxIncNewI = newI;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (!hasMove) {
|
|
588
|
+
key2new.forEach((i, key) => {
|
|
589
|
+
const before = i === 0 ? forNode.realBefore : newChildren[i - 1].realAfter;
|
|
590
|
+
this.insertForItem(forNode, i, data, newChildren, before, snapshotForUpdate);
|
|
591
|
+
});
|
|
592
|
+
} else {
|
|
593
|
+
const incI = macInc(new2oldI),
|
|
594
|
+
incLen = incI.length;
|
|
595
|
+
let p1, p2;
|
|
596
|
+
for (p1 = s2, p2 = 0; p1 <= e2; p1++) {
|
|
597
|
+
const oldI = new2oldI[p1];
|
|
598
|
+
if (oldI === -1) {
|
|
599
|
+
const before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
|
|
600
|
+
this.insertForItem(forNode, p1, data, newChildren, before, snapshotForUpdate);
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
const staticIdx = incI[p2] + s2;
|
|
604
|
+
if (p1 === staticIdx) {
|
|
605
|
+
p2 <= incLen && p2++;
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
let before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
|
|
609
|
+
const child = newChildren[p1];
|
|
610
|
+
const realBefore = child.realBefore,
|
|
611
|
+
realAfter = child.realAfter,
|
|
612
|
+
realParent = child.realParent;
|
|
613
|
+
let point = realBefore,
|
|
614
|
+
next;
|
|
615
|
+
do {
|
|
616
|
+
next = this.nextSib(point);
|
|
617
|
+
this.insertAfter(realParent, point, before);
|
|
618
|
+
before = point;
|
|
619
|
+
if (point === realAfter) break;
|
|
620
|
+
point = next;
|
|
621
|
+
} while (true);
|
|
622
|
+
}
|
|
488
623
|
}
|
|
489
624
|
}
|
|
490
|
-
forNode.children = newChildren;
|
|
491
625
|
}
|
|
626
|
+
forNode.children = newChildren;
|
|
492
627
|
}
|
|
493
628
|
isFirstRender = false;
|
|
629
|
+
aoye.setPulling(prevCtx);
|
|
630
|
+
return isDestroy => {
|
|
631
|
+
if (isDestroy) {
|
|
632
|
+
for (let i = 0; i < forNode.children.length; i++) {
|
|
633
|
+
const item = forNode.children[i];
|
|
634
|
+
item.effect.dispose();
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
};
|
|
494
638
|
});
|
|
495
639
|
return forNode.children[0] || forNode;
|
|
496
640
|
}
|
|
641
|
+
insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
|
|
642
|
+
const item = this.createForItem(forNode, i, parentData);
|
|
643
|
+
newChildren[i] = item;
|
|
644
|
+
let realAfter = this.createAnchor('for-item-after');
|
|
645
|
+
this.handleInsert(forNode.realParent, realAfter, before);
|
|
646
|
+
let realBefore = this.createAnchor('for-item-before');
|
|
647
|
+
this.handleInsert(forNode.realParent, realBefore, before);
|
|
648
|
+
item.realBefore = realBefore;
|
|
649
|
+
item.realAfter = realAfter;
|
|
650
|
+
this.tokenizer = forNode.owner.tokenizer;
|
|
651
|
+
this.tokenizer.resume(snapshotForUpdate);
|
|
652
|
+
this.tokenizer.useDedentAsEof = false;
|
|
653
|
+
aoye.runWithPulling(() => {
|
|
654
|
+
this.program(forNode.realParent, forNode.owner, realBefore, item);
|
|
655
|
+
}, item.effect);
|
|
656
|
+
}
|
|
657
|
+
removeForItem(children, i) {
|
|
658
|
+
const child = children[i];
|
|
659
|
+
this.removeLogicNode(child);
|
|
660
|
+
this.remove(child.realBefore);
|
|
661
|
+
this.remove(child.realAfter);
|
|
662
|
+
child.effect.dispose();
|
|
663
|
+
}
|
|
664
|
+
reuseForItem(child, data, itemExp, i, indexName) {
|
|
665
|
+
if (typeof itemExp === 'string') {
|
|
666
|
+
child.data[itemExp] = data;
|
|
667
|
+
if (indexName) {
|
|
668
|
+
child.data[indexName] = i;
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
indexName = indexName || KEY_INDEX;
|
|
672
|
+
child.data[indexName] = i;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
497
675
|
forItemId = 0;
|
|
498
676
|
createForItem(forNode, i, parentData) {
|
|
499
677
|
let forItemNode;
|
|
678
|
+
let data;
|
|
500
679
|
const scope = new aoye.Scope(() => {});
|
|
501
680
|
scope.scope = null;
|
|
502
681
|
aoye.runWithPulling(() => {
|
|
503
682
|
scope.get();
|
|
504
683
|
}, null);
|
|
684
|
+
data = this.getItemData(forNode, i, parentData);
|
|
685
|
+
forItemNode = {
|
|
686
|
+
id: this.forItemId++,
|
|
687
|
+
__logicType: FakeType.ForItem,
|
|
688
|
+
realParent: null,
|
|
689
|
+
realBefore: null,
|
|
690
|
+
realAfter: null,
|
|
691
|
+
forNode,
|
|
692
|
+
key: forNode.getKey?.(data),
|
|
693
|
+
effect: null,
|
|
694
|
+
data
|
|
695
|
+
};
|
|
696
|
+
forItemNode.effect = scope;
|
|
697
|
+
return forItemNode;
|
|
698
|
+
}
|
|
699
|
+
getItemData(forNode, i, parentData) {
|
|
505
700
|
const arr = forNode.arr,
|
|
506
701
|
itemExp = forNode.itemExp,
|
|
507
|
-
|
|
702
|
+
vars = forNode.vars,
|
|
703
|
+
arrSignal = forNode.arrSignal,
|
|
508
704
|
getKey = forNode.getKey;
|
|
705
|
+
let indexName = forNode.indexName;
|
|
509
706
|
let data;
|
|
510
707
|
if (typeof itemExp === 'string') {
|
|
511
708
|
data = aoye.deepSignal(indexName ? {
|
|
@@ -515,26 +712,21 @@ class Interpreter {
|
|
|
515
712
|
[itemExp]: arr[i]
|
|
516
713
|
}, aoye.getPulling());
|
|
517
714
|
} else {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
715
|
+
indexName = indexName ?? KEY_INDEX;
|
|
716
|
+
const rawData = {
|
|
717
|
+
[indexName]: i
|
|
718
|
+
};
|
|
522
719
|
data = aoye.deepSignal(rawData, aoye.getPulling());
|
|
720
|
+
const computedData = new aoye.Computed(() => itemExp(arrSignal.get()[getKey ? data[indexName] : i]));
|
|
721
|
+
const cells = data[aoye.Keys.Meta].cells;
|
|
722
|
+
for (let i = 0; i < vars.length; i++) {
|
|
723
|
+
const name = vars[i];
|
|
724
|
+
rawData[name] = undefined;
|
|
725
|
+
cells.set(name, new aoye.Computed(() => computedData.get()[name]));
|
|
726
|
+
}
|
|
523
727
|
}
|
|
524
728
|
Object.setPrototypeOf(data, parentData);
|
|
525
|
-
|
|
526
|
-
id: this.forItemId++,
|
|
527
|
-
__logicType: FakeType.ForItem,
|
|
528
|
-
realParent: null,
|
|
529
|
-
realBefore: null,
|
|
530
|
-
realAfter: null,
|
|
531
|
-
forNode,
|
|
532
|
-
key: getKey?.(data),
|
|
533
|
-
effect: null,
|
|
534
|
-
data
|
|
535
|
-
};
|
|
536
|
-
forItemNode.effect = scope;
|
|
537
|
-
return forItemNode;
|
|
729
|
+
return data;
|
|
538
730
|
}
|
|
539
731
|
getData() {
|
|
540
732
|
const _this$ctx$stack$peekB = this.ctx.stack.peekByType(NodeSort.CtxProvider),
|
|
@@ -1033,36 +1225,27 @@ class Tokenizer {
|
|
|
1033
1225
|
this.setToken(TokenType.Identifier, value || true);
|
|
1034
1226
|
return this.token;
|
|
1035
1227
|
}
|
|
1036
|
-
|
|
1228
|
+
jsExp() {
|
|
1037
1229
|
this.token = null;
|
|
1038
1230
|
let value = '';
|
|
1039
|
-
let count = 0;
|
|
1040
1231
|
while (1) {
|
|
1041
1232
|
const char = this.code[this.i];
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
if (!this.token) {
|
|
1046
|
-
this.setToken(TokenType.Identifier, value);
|
|
1047
|
-
} else {
|
|
1048
|
-
this.waitingTokens.push({
|
|
1049
|
-
type: TokenType.Identifier,
|
|
1050
|
-
typeName: TokenType[TokenType.Identifier],
|
|
1051
|
-
value
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
value = '';
|
|
1055
|
-
count++;
|
|
1056
|
-
if (count > 3) {
|
|
1057
|
-
throw SyntaxError(`for 循环最多可包含三个表达式, 分别为 arr ; item index [; key]`);
|
|
1058
|
-
}
|
|
1059
|
-
if (!isSemicolon) return count === 3;
|
|
1233
|
+
if (char === ';' || char === '\n') {
|
|
1234
|
+
this.setToken(TokenType.Identifier, value.trim());
|
|
1235
|
+
return this.token;
|
|
1060
1236
|
} else {
|
|
1061
1237
|
value += char;
|
|
1062
1238
|
}
|
|
1063
1239
|
this.i++;
|
|
1064
1240
|
}
|
|
1065
1241
|
}
|
|
1242
|
+
peekChar() {
|
|
1243
|
+
let i = this.i;
|
|
1244
|
+
while (this.code[i] === ' ' || this.code[i] === '\t') {
|
|
1245
|
+
i++;
|
|
1246
|
+
}
|
|
1247
|
+
return this.code[i];
|
|
1248
|
+
}
|
|
1066
1249
|
assignment() {
|
|
1067
1250
|
this.setToken(TokenType.Assign, '=');
|
|
1068
1251
|
}
|