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