bobe 0.0.16 → 0.0.18
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 +119 -151
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +121 -153
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +10 -22
- package/dist/index.umd.js +119 -151
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -35,20 +35,16 @@ var NodeSort = /* @__PURE__ */ ((NodeSort2) => {
|
|
|
35
35
|
NodeSort2[NodeSort2["TokenizerSwitcher"] = 16] = "TokenizerSwitcher";
|
|
36
36
|
return NodeSort2;
|
|
37
37
|
})(NodeSort || {});
|
|
38
|
-
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
39
|
-
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
40
|
-
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
41
|
-
return TerpEvt2;
|
|
42
|
-
})(TerpEvt || {});
|
|
43
38
|
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
44
39
|
|
|
45
40
|
class MultiTypeStack {
|
|
46
41
|
constructor() {
|
|
47
42
|
// 记录全局栈顶
|
|
48
|
-
|
|
43
|
+
// private top: StackNode<T> | null = null;
|
|
49
44
|
// 记录每个类别的当前最新节点(各分类的“栈顶”)
|
|
50
45
|
this.typeTops = {};
|
|
51
46
|
this.length = 0;
|
|
47
|
+
this.stack = [];
|
|
52
48
|
}
|
|
53
49
|
/**
|
|
54
50
|
* 入栈操作
|
|
@@ -59,7 +55,6 @@ class MultiTypeStack {
|
|
|
59
55
|
const newNode = {
|
|
60
56
|
value,
|
|
61
57
|
types: bits,
|
|
62
|
-
prevGlobal: this.top,
|
|
63
58
|
prevByType: {}
|
|
64
59
|
};
|
|
65
60
|
let bit;
|
|
@@ -70,15 +65,15 @@ class MultiTypeStack {
|
|
|
70
65
|
newNode.prevByType[bit] = this.typeTops[bit] || void 0;
|
|
71
66
|
this.typeTops[bit] = newNode;
|
|
72
67
|
}
|
|
73
|
-
this.
|
|
74
|
-
this.length++;
|
|
68
|
+
this.stack[this.length++] = newNode;
|
|
75
69
|
}
|
|
76
70
|
/**
|
|
77
71
|
* 出栈操作
|
|
78
72
|
*/
|
|
79
73
|
pop() {
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
const poppedNode = this.stack[this.length - 1];
|
|
75
|
+
this.stack[--this.length] = null;
|
|
76
|
+
if (!poppedNode) return void 0;
|
|
82
77
|
let { types: bits } = poppedNode;
|
|
83
78
|
let bit;
|
|
84
79
|
while (1) {
|
|
@@ -87,8 +82,6 @@ class MultiTypeStack {
|
|
|
87
82
|
bits &= ~bit;
|
|
88
83
|
this.typeTops[bit] = poppedNode.prevByType[bit];
|
|
89
84
|
}
|
|
90
|
-
this.top = poppedNode.prevGlobal;
|
|
91
|
-
this.length--;
|
|
92
85
|
return [poppedNode.value, poppedNode.types];
|
|
93
86
|
}
|
|
94
87
|
/**
|
|
@@ -99,47 +92,50 @@ class MultiTypeStack {
|
|
|
99
92
|
return (_a = this.typeTops[cat]) == null ? void 0 : _a.value;
|
|
100
93
|
}
|
|
101
94
|
peekType() {
|
|
102
|
-
|
|
103
|
-
return (_a = this.top) == null ? void 0 : _a.types;
|
|
95
|
+
return this.stack.at(-1).types;
|
|
104
96
|
}
|
|
105
97
|
/**
|
|
106
98
|
* 获取全局栈顶
|
|
107
99
|
*/
|
|
108
100
|
peek() {
|
|
109
|
-
|
|
110
|
-
return (_a = this.top) == null ? void 0 : _a.value;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* 1. 全局向前遍历 (不分类)
|
|
114
|
-
* 从栈顶开始,沿着全局链条向栈底遍历
|
|
115
|
-
*/
|
|
116
|
-
forEach(callback) {
|
|
117
|
-
let current = this.top;
|
|
118
|
-
while (current !== null) {
|
|
119
|
-
const shouldBreak = callback(current.value, current.types);
|
|
120
|
-
if (shouldBreak) break;
|
|
121
|
-
current = current.prevGlobal;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* 2. 按类别向前遍历
|
|
126
|
-
* 仅遍历属于指定类别 cat 的节点
|
|
127
|
-
*/
|
|
128
|
-
forEachByType(cat, callback) {
|
|
129
|
-
let current = this.typeTops[cat];
|
|
130
|
-
while (current) {
|
|
131
|
-
const shouldBreak = callback(current.value);
|
|
132
|
-
if (shouldBreak) break;
|
|
133
|
-
current = current.prevByType[cat];
|
|
134
|
-
}
|
|
101
|
+
return this.stack.at(-1).value;
|
|
135
102
|
}
|
|
103
|
+
// /**
|
|
104
|
+
// * 1. 全局向前遍历 (不分类)
|
|
105
|
+
// * 从栈顶开始,沿着全局链条向栈底遍历
|
|
106
|
+
// */
|
|
107
|
+
// forEach(callback: (value: T, types: number) => any): void {
|
|
108
|
+
// let current = this.top;
|
|
109
|
+
// while (current !== null) {
|
|
110
|
+
// // 执行回调,如果返回 false 则立即停止
|
|
111
|
+
// const shouldBreak = callback(current.value, current.types);
|
|
112
|
+
// if (shouldBreak) break;
|
|
113
|
+
// current = current.prevGlobal;
|
|
114
|
+
// }
|
|
115
|
+
// }
|
|
116
|
+
// /**
|
|
117
|
+
// * 2. 按类别向前遍历
|
|
118
|
+
// * 仅遍历属于指定类别 cat 的节点
|
|
119
|
+
// */
|
|
120
|
+
// forEachByType(cat: number, callback: (value: T) => any): void {
|
|
121
|
+
// // 从该类别的当前“顶端”节点开始
|
|
122
|
+
// let current = this.typeTops[cat];
|
|
123
|
+
// while (current) {
|
|
124
|
+
// const shouldBreak = callback(current.value);
|
|
125
|
+
// if (shouldBreak) break;
|
|
126
|
+
// // 关键点:直接跳向该节点记录的“上一个同类节点”
|
|
127
|
+
// // 这比遍历全局栈再筛选类别要快得多 (O(m) vs O(n))
|
|
128
|
+
// current = current.prevByType[cat];
|
|
129
|
+
// }
|
|
130
|
+
// }
|
|
136
131
|
}
|
|
137
132
|
|
|
138
|
-
|
|
133
|
+
new bobeShared.BaseEvent();
|
|
139
134
|
class Interpreter {
|
|
140
135
|
constructor(tokenizer) {
|
|
141
136
|
this.tokenizer = tokenizer;
|
|
142
137
|
this.rootComponent = null;
|
|
138
|
+
this.oneRealPropParsed = this.onePropParsed.bind(this);
|
|
143
139
|
}
|
|
144
140
|
isLogicNode(node) {
|
|
145
141
|
return node && node.__logicType & LogicalBit;
|
|
@@ -147,7 +143,7 @@ class Interpreter {
|
|
|
147
143
|
program(root, componentNode, before) {
|
|
148
144
|
var _a, _b;
|
|
149
145
|
this.rootComponent = componentNode;
|
|
150
|
-
this.tokenizer.
|
|
146
|
+
this.tokenizer.nextToken();
|
|
151
147
|
const stack = new MultiTypeStack();
|
|
152
148
|
stack.push({ node: root, prev: null }, NodeSort.Real);
|
|
153
149
|
stack.push(
|
|
@@ -170,7 +166,7 @@ class Interpreter {
|
|
|
170
166
|
}
|
|
171
167
|
const token = this.tokenizer.token;
|
|
172
168
|
if (token.type & TokenType.Indent) {
|
|
173
|
-
this.tokenizer.
|
|
169
|
+
this.tokenizer.nextToken();
|
|
174
170
|
const isLogicNode = this.isLogicNode(ctx.current);
|
|
175
171
|
stack.push(
|
|
176
172
|
{
|
|
@@ -199,7 +195,7 @@ class Interpreter {
|
|
|
199
195
|
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
200
196
|
}
|
|
201
197
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
202
|
-
this.tokenizer.
|
|
198
|
+
this.tokenizer.nextToken();
|
|
203
199
|
const [{ node: parent, prev }, sort] = stack.pop();
|
|
204
200
|
if (!parent.__logicType) {
|
|
205
201
|
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
@@ -288,28 +284,23 @@ class Interpreter {
|
|
|
288
284
|
return this.condDeclaration(ctx);
|
|
289
285
|
} else if (hookType) {
|
|
290
286
|
if (hookType === "static") {
|
|
291
|
-
if (typeof value === "function"
|
|
292
|
-
_node = this.
|
|
293
|
-
} else if (typeof value === "function") {
|
|
294
|
-
_node = this.fragmentDeclaration(value, ctx);
|
|
287
|
+
if (typeof value === "function") {
|
|
288
|
+
_node = this.componentOrFragmentDeclaration(value, ctx);
|
|
295
289
|
} else {
|
|
296
290
|
throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
|
|
297
291
|
}
|
|
298
292
|
} else {
|
|
299
|
-
|
|
300
|
-
Boolean(data[aoye.Keys.Raw][value]);
|
|
301
|
-
new Function("data", `let v;with(data){v=(${value})};return v`);
|
|
302
|
-
_node = this.createNode(value);
|
|
293
|
+
_node = this.componentOrFragmentDeclaration(value, ctx);
|
|
303
294
|
}
|
|
304
295
|
} else {
|
|
305
296
|
_node = this.createNode(value);
|
|
306
297
|
}
|
|
307
|
-
this.tokenizer.
|
|
298
|
+
this.tokenizer.nextToken();
|
|
308
299
|
this.headerLine(_node);
|
|
309
300
|
this.extensionLines(_node);
|
|
310
|
-
if (_node.__logicType
|
|
311
|
-
|
|
312
|
-
|
|
301
|
+
if (_node.__logicType & TokenizerSwitcherBit) {
|
|
302
|
+
this.onePropParsed = this.oneRealPropParsed;
|
|
303
|
+
this.tokenizer = _node.tokenizer;
|
|
313
304
|
}
|
|
314
305
|
return _node;
|
|
315
306
|
}
|
|
@@ -317,18 +308,6 @@ class Interpreter {
|
|
|
317
308
|
const { node } = this.ctx.stack.peekByType(NodeSort.CtxProvider);
|
|
318
309
|
return node.data || node.owner.data;
|
|
319
310
|
}
|
|
320
|
-
// TODO: 指定挂载位置
|
|
321
|
-
fragmentDeclaration(renderFragment, ctx) {
|
|
322
|
-
const data = this.getData();
|
|
323
|
-
const tokenizer = renderFragment.call(data, this.opt, { data, root: "", anchor: "" });
|
|
324
|
-
const fragmentNode = {
|
|
325
|
-
__logicType: FakeType.Fragment,
|
|
326
|
-
realParent: null,
|
|
327
|
-
tokenizer,
|
|
328
|
-
data: null
|
|
329
|
-
};
|
|
330
|
-
return fragmentNode;
|
|
331
|
-
}
|
|
332
311
|
/**
|
|
333
312
|
* key 元素,组件的 key
|
|
334
313
|
* value
|
|
@@ -354,20 +333,32 @@ class Interpreter {
|
|
|
354
333
|
this.setProp(node, key, value, hookI);
|
|
355
334
|
}
|
|
356
335
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const
|
|
360
|
-
|
|
336
|
+
componentOrFragmentDeclaration(ComponentOrRender, ctx) {
|
|
337
|
+
let Component, render, child;
|
|
338
|
+
const data = this.getData();
|
|
339
|
+
if (typeof ComponentOrRender === "string") {
|
|
340
|
+
ComponentOrRender = data[ComponentOrRender];
|
|
341
|
+
}
|
|
342
|
+
const isCC = ComponentOrRender.prototype instanceof aoye.Store;
|
|
343
|
+
if (isCC) {
|
|
344
|
+
Component = ComponentOrRender;
|
|
345
|
+
child = Component.new();
|
|
346
|
+
} else {
|
|
347
|
+
render = ComponentOrRender;
|
|
348
|
+
child = aoye.deepSignal({}, aoye.getPulling(), true);
|
|
349
|
+
Object.setPrototypeOf(child, data);
|
|
350
|
+
}
|
|
351
|
+
const node = {
|
|
352
|
+
__logicType: isCC ? FakeType.Component : FakeType.Fragment,
|
|
361
353
|
realParent: ctx.realParent,
|
|
362
354
|
data: child,
|
|
363
|
-
tokenizer:
|
|
355
|
+
tokenizer: render ? render(true) : child["ui"](true)
|
|
364
356
|
};
|
|
365
|
-
|
|
366
|
-
this.onePropParsed = (data, node, key, value, valueIsMapKey, isFn, hookI) => {
|
|
357
|
+
this.onePropParsed = (data2, _, key, value, valueIsMapKey, isFn, hookI) => {
|
|
367
358
|
if (isFn) {
|
|
368
359
|
child[aoye.Keys.Raw][key] = value;
|
|
369
360
|
} else if (valueIsMapKey) {
|
|
370
|
-
aoye.shareSignal(
|
|
361
|
+
aoye.shareSignal(data2, value, child, key);
|
|
371
362
|
} else if (typeof value === "function") {
|
|
372
363
|
const meta = child[aoye.Keys.Meta];
|
|
373
364
|
const cells = meta.cells;
|
|
@@ -377,23 +368,16 @@ class Interpreter {
|
|
|
377
368
|
child[aoye.Keys.Raw][key] = value;
|
|
378
369
|
}
|
|
379
370
|
};
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
tap.once(TerpEvt.AllAttrGot, () => {
|
|
383
|
-
this.onePropParsed = prevOnePropParsed;
|
|
384
|
-
const subTkr = child["ui"](true);
|
|
385
|
-
componentNode.tokenizer = subTkr;
|
|
386
|
-
this.tokenizer = subTkr;
|
|
387
|
-
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
388
|
-
});
|
|
389
|
-
return componentNode;
|
|
371
|
+
node.realAfter = this.insertAfterAnchor(ctx);
|
|
372
|
+
return node;
|
|
390
373
|
}
|
|
391
374
|
// TODO: 优化代码逻辑,拆分 if elseif else
|
|
392
375
|
condDeclaration(ctx) {
|
|
393
376
|
var _a;
|
|
394
377
|
const { prevSibling } = ctx;
|
|
395
378
|
const snapbackUp = this.tokenizer.snapshot();
|
|
396
|
-
const keyWord = this.tokenizer.
|
|
379
|
+
const keyWord = this.tokenizer.token;
|
|
380
|
+
this.tokenizer.nextToken();
|
|
397
381
|
const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
|
|
398
382
|
const [hookType, value] = this.tokenizer._hook({});
|
|
399
383
|
const isElse = keyWord.value === "else";
|
|
@@ -474,9 +458,9 @@ class Interpreter {
|
|
|
474
458
|
if (val) {
|
|
475
459
|
if (ifNode.isFirstRender) {
|
|
476
460
|
if (!noSelfCond) {
|
|
477
|
-
this.tokenizer.
|
|
461
|
+
this.tokenizer.nextToken();
|
|
478
462
|
}
|
|
479
|
-
this.tokenizer.
|
|
463
|
+
this.tokenizer.nextToken();
|
|
480
464
|
} else {
|
|
481
465
|
this.tokenizer = ifNode.owner.tokenizer;
|
|
482
466
|
this.tokenizer.resume(ifNode.snapshot);
|
|
@@ -511,15 +495,15 @@ class Interpreter {
|
|
|
511
495
|
*/
|
|
512
496
|
extensionLines(_node) {
|
|
513
497
|
while (1) {
|
|
514
|
-
if (
|
|
498
|
+
if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
515
499
|
return;
|
|
516
500
|
}
|
|
517
|
-
this.tokenizer.
|
|
501
|
+
this.tokenizer.nextToken();
|
|
518
502
|
this.attributeList(_node);
|
|
519
|
-
if (
|
|
503
|
+
if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
520
504
|
return;
|
|
521
505
|
}
|
|
522
|
-
this.tokenizer.
|
|
506
|
+
this.tokenizer.nextToken();
|
|
523
507
|
}
|
|
524
508
|
}
|
|
525
509
|
/**
|
|
@@ -529,7 +513,7 @@ class Interpreter {
|
|
|
529
513
|
*/
|
|
530
514
|
headerLine(_node) {
|
|
531
515
|
this.attributeList(_node);
|
|
532
|
-
this.tokenizer.
|
|
516
|
+
this.tokenizer.nextToken();
|
|
533
517
|
}
|
|
534
518
|
/**
|
|
535
519
|
* 属性列表:
|
|
@@ -539,19 +523,19 @@ class Interpreter {
|
|
|
539
523
|
*
|
|
540
524
|
* <attribute> ::= <key> = <value>
|
|
541
525
|
* 1. 普通节点 执行 setProps 🪝
|
|
542
|
-
* 2. 组件节点
|
|
526
|
+
* 2. 组件节点 收集映射关系,或 产生 computed
|
|
543
527
|
*/
|
|
544
528
|
attributeList(_node) {
|
|
545
529
|
let key, eq;
|
|
546
530
|
const data = this.getData();
|
|
547
|
-
while (
|
|
531
|
+
while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
548
532
|
if (key == null) {
|
|
549
533
|
key = this.tokenizer.token.value;
|
|
550
534
|
} else if (eq == null) {
|
|
551
535
|
eq = "=";
|
|
552
536
|
} else {
|
|
553
537
|
const [hookType, value, hookI] = this.tokenizer._hook({});
|
|
554
|
-
const rawVal =
|
|
538
|
+
const rawVal = data[aoye.Keys.Raw][value];
|
|
555
539
|
const isFn = typeof rawVal === "function";
|
|
556
540
|
if (hookType === "dynamic") {
|
|
557
541
|
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
@@ -565,7 +549,7 @@ class Interpreter {
|
|
|
565
549
|
key = null;
|
|
566
550
|
eq = null;
|
|
567
551
|
}
|
|
568
|
-
this.tokenizer.
|
|
552
|
+
this.tokenizer.nextToken();
|
|
569
553
|
}
|
|
570
554
|
}
|
|
571
555
|
config(opt) {
|
|
@@ -725,16 +709,16 @@ const _Tokenizer = class _Tokenizer {
|
|
|
725
709
|
let skipFragment = ``;
|
|
726
710
|
this.token = void 0;
|
|
727
711
|
while (1) {
|
|
728
|
-
const char = this.
|
|
712
|
+
const char = this.code[this.i];
|
|
729
713
|
if (char === "\n") {
|
|
730
714
|
needIndent = true;
|
|
731
715
|
skipFragment += char;
|
|
732
|
-
this.
|
|
716
|
+
this.i++;
|
|
733
717
|
continue;
|
|
734
718
|
}
|
|
735
719
|
if (!needIndent) {
|
|
736
720
|
skipFragment += char;
|
|
737
|
-
this.
|
|
721
|
+
this.i++;
|
|
738
722
|
continue;
|
|
739
723
|
}
|
|
740
724
|
needIndent = false;
|
|
@@ -787,21 +771,6 @@ ${_Tokenizer.EofId}`;
|
|
|
787
771
|
if (!this.token) return false;
|
|
788
772
|
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
789
773
|
}
|
|
790
|
-
get char() {
|
|
791
|
-
return this.code[this.i];
|
|
792
|
-
}
|
|
793
|
-
get prev() {
|
|
794
|
-
return this.code[this.i - 1];
|
|
795
|
-
}
|
|
796
|
-
get after() {
|
|
797
|
-
return this.code[this.i + 1];
|
|
798
|
-
}
|
|
799
|
-
next() {
|
|
800
|
-
const prev = this.code[this.i];
|
|
801
|
-
this.i++;
|
|
802
|
-
const curr = this.code[this.i];
|
|
803
|
-
return [prev, curr];
|
|
804
|
-
}
|
|
805
774
|
setToken(type, value) {
|
|
806
775
|
this.token = {
|
|
807
776
|
type,
|
|
@@ -810,10 +779,6 @@ ${_Tokenizer.EofId}`;
|
|
|
810
779
|
};
|
|
811
780
|
this.isFirstToken = false;
|
|
812
781
|
}
|
|
813
|
-
testId(value) {
|
|
814
|
-
if (typeof value !== "string") return false;
|
|
815
|
-
return _Tokenizer.IdExp.test(value);
|
|
816
|
-
}
|
|
817
782
|
nextToken() {
|
|
818
783
|
try {
|
|
819
784
|
if (this.isEof()) {
|
|
@@ -829,7 +794,7 @@ ${_Tokenizer.EofId}`;
|
|
|
829
794
|
if (this.needIndent) {
|
|
830
795
|
this.dent();
|
|
831
796
|
} else {
|
|
832
|
-
|
|
797
|
+
const char = this.code[this.i];
|
|
833
798
|
switch (char) {
|
|
834
799
|
case " ":
|
|
835
800
|
case " ":
|
|
@@ -860,12 +825,12 @@ ${_Tokenizer.EofId}`;
|
|
|
860
825
|
this.number(char);
|
|
861
826
|
break;
|
|
862
827
|
}
|
|
863
|
-
if (
|
|
828
|
+
if (typeof char === "string" && bobeShared.matchIdStart(char)) {
|
|
864
829
|
this.identifier(char);
|
|
865
830
|
}
|
|
866
831
|
break;
|
|
867
832
|
}
|
|
868
|
-
this.
|
|
833
|
+
this.i++;
|
|
869
834
|
}
|
|
870
835
|
if (this.token) {
|
|
871
836
|
break;
|
|
@@ -874,6 +839,7 @@ ${_Tokenizer.EofId}`;
|
|
|
874
839
|
return this.token;
|
|
875
840
|
} catch (error) {
|
|
876
841
|
console.error(error);
|
|
842
|
+
return this.token;
|
|
877
843
|
} finally {
|
|
878
844
|
this.handledTokens.push(this.token);
|
|
879
845
|
}
|
|
@@ -885,17 +851,17 @@ ${_Tokenizer.EofId}`;
|
|
|
885
851
|
this.setToken(TokenType.Pipe, "|");
|
|
886
852
|
}
|
|
887
853
|
dynamic(char) {
|
|
888
|
-
let nextC = this.
|
|
854
|
+
let nextC = this.code[this.i + 1];
|
|
889
855
|
if (nextC !== "{") {
|
|
890
856
|
return false;
|
|
891
857
|
}
|
|
892
|
-
this.
|
|
858
|
+
this.i++;
|
|
893
859
|
let value = "${";
|
|
894
860
|
let innerBrace = 0;
|
|
895
861
|
while (1) {
|
|
896
|
-
nextC = this.
|
|
862
|
+
nextC = this.code[this.i + 1];
|
|
897
863
|
value += nextC;
|
|
898
|
-
this.
|
|
864
|
+
this.i++;
|
|
899
865
|
if (nextC === "{") {
|
|
900
866
|
innerBrace++;
|
|
901
867
|
}
|
|
@@ -912,13 +878,14 @@ ${_Tokenizer.EofId}`;
|
|
|
912
878
|
brace() {
|
|
913
879
|
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
914
880
|
while (1) {
|
|
915
|
-
const char = this.
|
|
916
|
-
const nextChar = this.
|
|
881
|
+
const char = this.code[this.i];
|
|
882
|
+
const nextChar = this.code[this.i + 1];
|
|
917
883
|
if (inComment === "single" && char === "\n") {
|
|
918
884
|
inComment = null;
|
|
919
885
|
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
920
886
|
inComment = null;
|
|
921
|
-
value += this.
|
|
887
|
+
value += this.code[this.i];
|
|
888
|
+
this.i++;
|
|
922
889
|
} else if (inString) {
|
|
923
890
|
if (char === inString && backslashCount % 2 === 0) {
|
|
924
891
|
inString = null;
|
|
@@ -927,10 +894,12 @@ ${_Tokenizer.EofId}`;
|
|
|
927
894
|
} else {
|
|
928
895
|
if (char === "/" && nextChar === "/") {
|
|
929
896
|
inComment = "single";
|
|
930
|
-
value += this.
|
|
897
|
+
value += this.code[this.i];
|
|
898
|
+
this.i++;
|
|
931
899
|
} else if (char === "/" && nextChar === "*") {
|
|
932
900
|
inComment = "multi";
|
|
933
|
-
value += this.
|
|
901
|
+
value += this.code[this.i];
|
|
902
|
+
this.i++;
|
|
934
903
|
} else if (char === "'" || char === '"' || char === "`") {
|
|
935
904
|
inString = char;
|
|
936
905
|
} else if (char === "{") {
|
|
@@ -943,19 +912,20 @@ ${_Tokenizer.EofId}`;
|
|
|
943
912
|
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
944
913
|
return;
|
|
945
914
|
}
|
|
946
|
-
value += this.
|
|
915
|
+
value += this.code[this.i];
|
|
916
|
+
this.i++;
|
|
947
917
|
}
|
|
948
918
|
}
|
|
949
919
|
newLine() {
|
|
950
920
|
let value = "\n";
|
|
951
921
|
let nextC;
|
|
952
922
|
while (1) {
|
|
953
|
-
nextC = this.
|
|
923
|
+
nextC = this.code[this.i + 1];
|
|
954
924
|
if (nextC !== "\n") {
|
|
955
925
|
break;
|
|
956
926
|
}
|
|
957
927
|
value += nextC;
|
|
958
|
-
this.
|
|
928
|
+
this.i++;
|
|
959
929
|
}
|
|
960
930
|
if (this.isFirstToken) {
|
|
961
931
|
return;
|
|
@@ -967,7 +937,7 @@ ${_Tokenizer.EofId}`;
|
|
|
967
937
|
let nextC;
|
|
968
938
|
let isEmptyLine = false;
|
|
969
939
|
while (1) {
|
|
970
|
-
const nextChar = this.
|
|
940
|
+
const nextChar = this.code[this.i];
|
|
971
941
|
switch (nextChar) {
|
|
972
942
|
case " ":
|
|
973
943
|
nextC = this.Tab;
|
|
@@ -990,7 +960,7 @@ ${_Tokenizer.EofId}`;
|
|
|
990
960
|
break;
|
|
991
961
|
}
|
|
992
962
|
value += nextC;
|
|
993
|
-
this.
|
|
963
|
+
this.i++;
|
|
994
964
|
}
|
|
995
965
|
return {
|
|
996
966
|
value,
|
|
@@ -1013,7 +983,7 @@ ${_Tokenizer.EofId}`;
|
|
|
1013
983
|
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
1014
984
|
if (currLen > prevLen) {
|
|
1015
985
|
this.dentStack.push(currLen);
|
|
1016
|
-
this.setToken(TokenType.Indent,
|
|
986
|
+
this.setToken(TokenType.Indent, currLen);
|
|
1017
987
|
return indentHasLen;
|
|
1018
988
|
}
|
|
1019
989
|
if (currLen < prevLen) {
|
|
@@ -1072,12 +1042,12 @@ ${_Tokenizer.EofId}`;
|
|
|
1072
1042
|
let value = char;
|
|
1073
1043
|
let nextC;
|
|
1074
1044
|
while (1) {
|
|
1075
|
-
nextC = this.
|
|
1076
|
-
if (!
|
|
1045
|
+
nextC = this.code[this.i + 1];
|
|
1046
|
+
if (typeof nextC !== "string" || !bobeShared.matchIdStart(nextC)) {
|
|
1077
1047
|
break;
|
|
1078
1048
|
}
|
|
1079
1049
|
value += nextC;
|
|
1080
|
-
this.
|
|
1050
|
+
this.i++;
|
|
1081
1051
|
}
|
|
1082
1052
|
if (value === _Tokenizer.EofId && this.isSubToken) {
|
|
1083
1053
|
this.setToken(TokenType.Dedent, "");
|
|
@@ -1087,35 +1057,35 @@ ${_Tokenizer.EofId}`;
|
|
|
1087
1057
|
this.setToken(TokenType.Identifier, realValue);
|
|
1088
1058
|
}
|
|
1089
1059
|
str(char) {
|
|
1090
|
-
let value =
|
|
1060
|
+
let value = "";
|
|
1091
1061
|
let nextC;
|
|
1092
1062
|
let continuousBackslashCount = 0;
|
|
1093
1063
|
while (1) {
|
|
1094
|
-
nextC = this.
|
|
1095
|
-
value += nextC;
|
|
1064
|
+
nextC = this.code[this.i + 1];
|
|
1096
1065
|
const memoCount = continuousBackslashCount;
|
|
1097
1066
|
if (nextC === "\\") {
|
|
1098
1067
|
continuousBackslashCount++;
|
|
1099
1068
|
} else {
|
|
1100
1069
|
continuousBackslashCount = 0;
|
|
1101
1070
|
}
|
|
1102
|
-
this.
|
|
1071
|
+
this.i++;
|
|
1103
1072
|
if (nextC === char && memoCount % 2 === 0) {
|
|
1104
1073
|
break;
|
|
1105
1074
|
}
|
|
1075
|
+
value += nextC;
|
|
1106
1076
|
}
|
|
1107
|
-
this.setToken(TokenType.Identifier,
|
|
1077
|
+
this.setToken(TokenType.Identifier, value);
|
|
1108
1078
|
}
|
|
1109
1079
|
number(char) {
|
|
1110
1080
|
let value = char;
|
|
1111
1081
|
let nextC;
|
|
1112
1082
|
while (1) {
|
|
1113
|
-
nextC = this.
|
|
1083
|
+
nextC = this.code[this.i + 1];
|
|
1114
1084
|
if (!bobeShared.isNum(nextC)) {
|
|
1115
1085
|
break;
|
|
1116
1086
|
}
|
|
1117
1087
|
value += nextC;
|
|
1118
|
-
this.
|
|
1088
|
+
this.i++;
|
|
1119
1089
|
}
|
|
1120
1090
|
this.setToken(TokenType.Identifier, Number(value));
|
|
1121
1091
|
}
|
|
@@ -1135,8 +1105,6 @@ ${_Tokenizer.EofId}`;
|
|
|
1135
1105
|
}
|
|
1136
1106
|
}
|
|
1137
1107
|
};
|
|
1138
|
-
/** 匹配标识符 */
|
|
1139
|
-
_Tokenizer.IdExp = /[\d\w\/]/;
|
|
1140
1108
|
/** Eof 标识符的值 */
|
|
1141
1109
|
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
1142
1110
|
_Tokenizer.DedentId = `__DEDENT__${Date.now()}`;
|