bobe 0.0.31 → 0.0.33

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 CHANGED
@@ -1,76 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var aoye = require('aoye');
4
3
  var bobeShared = require('bobe-shared');
5
-
6
- function _arrayLikeToArray(r, a) {
7
- (null == a || a > r.length) && (a = r.length);
8
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
9
- return n;
10
- }
11
- function _arrayWithHoles(r) {
12
- if (Array.isArray(r)) return r;
13
- }
14
- function _iterableToArrayLimit(r, l) {
15
- var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
16
- if (null != t) {
17
- var e,
18
- n,
19
- i,
20
- u,
21
- a = [],
22
- f = true,
23
- o = false;
24
- try {
25
- if (i = (t = t.call(r)).next, 0 === l) {
26
- if (Object(t) !== t) return;
27
- f = !1;
28
- } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
29
- } catch (r) {
30
- o = true, n = r;
31
- } finally {
32
- try {
33
- if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
34
- } finally {
35
- if (o) throw n;
36
- }
37
- }
38
- return a;
39
- }
40
- }
41
- function _nonIterableRest() {
42
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
43
- }
44
- function _objectWithoutProperties(e, t) {
45
- if (null == e) return {};
46
- var o,
47
- r,
48
- i = _objectWithoutPropertiesLoose(e, t);
49
- if (Object.getOwnPropertySymbols) {
50
- var n = Object.getOwnPropertySymbols(e);
51
- for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
52
- }
53
- return i;
54
- }
55
- function _objectWithoutPropertiesLoose(r, e) {
56
- if (null == r) return {};
57
- var t = {};
58
- for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
59
- if (-1 !== e.indexOf(n)) continue;
60
- t[n] = r[n];
61
- }
62
- return t;
63
- }
64
- function _slicedToArray(r, e) {
65
- return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
66
- }
67
- function _unsupportedIterableToArray(r, a) {
68
- if (r) {
69
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
70
- var t = {}.toString.call(r).slice(8, -1);
71
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
72
- }
73
- }
4
+ var aoye = require('aoye');
74
5
 
75
6
  let TokenType = function (TokenType) {
76
7
  TokenType[TokenType["NewLine"] = 1] = "NewLine";
@@ -82,6 +13,7 @@ let TokenType = function (TokenType) {
82
13
  TokenType[TokenType["Eof"] = 64] = "Eof";
83
14
  TokenType[TokenType["InsertionExp"] = 128] = "InsertionExp";
84
15
  TokenType[TokenType["Semicolon"] = 256] = "Semicolon";
16
+ TokenType[TokenType["StaticInsExp"] = 512] = "StaticInsExp";
85
17
  return TokenType;
86
18
  }({});
87
19
  let FakeType = function (FakeType) {
@@ -112,1427 +44,1922 @@ let NodeSort = function (NodeSort) {
112
44
  return TerpEvt;
113
45
  })({});
114
46
 
115
- class MultiTypeStack {
116
- typeTops = {};
117
- length = 0;
118
- stack = [];
119
- push(value, bits) {
120
- const newNode = {
121
- value,
122
- types: bits,
123
- prevByType: {}
124
- };
125
- let bit;
126
- while (1) {
127
- bit = bits & ~bits + 1;
128
- if (!bit) break;
129
- bits &= ~bit;
130
- newNode.prevByType[bit] = this.typeTops[bit] || undefined;
131
- this.typeTops[bit] = newNode;
132
- }
133
- this.stack[this.length++] = newNode;
134
- }
135
- pop() {
136
- const poppedNode = this.stack[this.length - 1];
137
- this.stack[--this.length] = null;
138
- if (!poppedNode) return undefined;
139
- let bits = poppedNode.types;
140
- let bit;
141
- while (1) {
142
- bit = bits & ~bits + 1;
143
- if (!bit) break;
144
- bits &= ~bit;
145
- this.typeTops[bit] = poppedNode.prevByType[bit];
47
+ class Tokenizer {
48
+ TabSize = 2;
49
+ Tab = Array.from({
50
+ length: this.TabSize
51
+ }, () => ' ').join('');
52
+ static EofId = `__EOF__${Date.now()}`;
53
+ static DedentId = `__DEDENT__${Date.now()}`;
54
+ needIndent = false;
55
+ isFirstToken = true;
56
+ dentStack = [0];
57
+ i = 0;
58
+ line = 0;
59
+ column = 0;
60
+ preCol = 0;
61
+ preI = 0;
62
+ needLoc = false;
63
+ handledTokens = [];
64
+ waitingTokens = new bobeShared.Queue();
65
+ source = '';
66
+ constructor(hook, useDedentAsEof) {
67
+ this.hook = hook;
68
+ this.useDedentAsEof = useDedentAsEof;
69
+ if (useDedentAsEof) {
70
+ this.setToken(TokenType.Indent, '');
71
+ this.isFirstToken = true;
146
72
  }
147
- return [poppedNode.value, poppedNode.types];
148
73
  }
149
- peekByType(cat) {
150
- return this.typeTops[cat]?.value;
74
+ next() {
75
+ this.i++;
151
76
  }
152
- peekType() {
153
- return this.stack.at(-1).types;
77
+ getCurrentPos() {
78
+ return {
79
+ offset: this.i,
80
+ line: this.line,
81
+ column: this.column
82
+ };
154
83
  }
155
- peek() {
156
- return this.stack.at(-1).value;
84
+ resume(_snapshot) {
85
+ this.token = undefined;
86
+ this.needIndent = false;
87
+ this.isFirstToken = true;
88
+ this.dentStack = [0];
89
+ Object.assign(this, _snapshot);
157
90
  }
158
- }
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;
91
+ snapshot(keys) {
92
+ const snap = {
93
+ i: this.i,
94
+ waitingTokens: this.waitingTokens.clone()
95
+ };
96
+ if (keys) {
97
+ for (const k of keys) {
98
+ snap[k] = this[k];
99
+ if (k === 'dentStack') {
100
+ snap[k] = this[k].slice();
101
+ }
102
+ }
169
103
  }
170
- i++;
104
+ return snap;
171
105
  }
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;
106
+ skip() {
107
+ const logicDentLen = this.dentStack[this.dentStack.length - 1];
108
+ let needIndent = false;
109
+ let skipFragment = ``;
110
+ this.token = undefined;
111
+ while (1) {
112
+ const char = this.code[this.i];
113
+ if (char === '\n') {
114
+ needIndent = true;
115
+ skipFragment += char;
116
+ this.next();
117
+ continue;
118
+ }
119
+ if (!needIndent) {
120
+ skipFragment += char;
121
+ this.next();
122
+ continue;
123
+ }
124
+ needIndent = false;
125
+ const _this$getDentValue = this.getDentValue(),
126
+ value = _this$getDentValue.value,
127
+ isEmptyLine = _this$getDentValue.isEmptyLine;
128
+ const currLen = value.length;
129
+ if (isEmptyLine) continue;
130
+ if (currLen > logicDentLen) {
131
+ skipFragment += value;
183
132
  } else {
184
- end = mid;
133
+ for (let i = this.dentStack.length - 1; i >= 0; i--) {
134
+ const expLen = this.dentStack[i];
135
+ if (currLen === expLen) break;
136
+ if (currLen > expLen) {
137
+ throw SyntaxError(`缩进错误,缩进长度不匹配`);
138
+ }
139
+ if (this.shorterThanBaseDentEof()) {
140
+ break;
141
+ }
142
+ this.dentStack.pop();
143
+ if (!this.token) {
144
+ this.setToken(TokenType.Dedent, String(expLen));
145
+ } else {
146
+ this.waitingTokens.push({
147
+ type: TokenType.Dedent,
148
+ typeName: TokenType[TokenType.Dedent],
149
+ value: String(expLen),
150
+ loc: null
151
+ });
152
+ }
153
+ }
154
+ break;
185
155
  }
186
156
  }
187
- candyLast[end] = i;
188
- toPrev[i] = candyLast[start];
189
- i++;
157
+ if (!this.token) {
158
+ this.nextToken();
159
+ }
160
+ return skipFragment;
190
161
  }
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;
162
+ setCode(code) {
163
+ this.code = '\n' + code.trimEnd() + `\n${Tokenizer.EofId}`;
195
164
  }
196
- return candyLast;
197
- }
198
-
199
- const KEY_INDEX = '__BOBE_KEY_INDEX';
200
-
201
- const _excluded = ["dentStack", "isFirstToken"];
202
- class Interpreter {
203
- constructor(tokenizer) {
204
- this.tokenizer = tokenizer;
165
+ tokenize() {
166
+ do {
167
+ this.nextToken();
168
+ console.log('token:', TokenType[this.token?.type], JSON.stringify(this.token?.value || ''));
169
+ } while (!this.isEof());
205
170
  }
206
- isLogicNode(node) {
207
- return node && node.__logicType & LogicalBit;
171
+ isEof() {
172
+ if (!this.token) return false;
173
+ return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
208
174
  }
209
- rootComponent = null;
210
- program(root, componentNode, before, ctxProvider) {
211
- this.rootComponent = componentNode;
212
- this.tokenizer.nextToken();
213
- const stack = new MultiTypeStack();
214
- stack.push({
215
- node: root,
216
- prev: null
217
- }, NodeSort.Real);
218
- stack.push({
219
- node: componentNode,
220
- prev: null
221
- }, NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher);
222
- if (ctxProvider) {
223
- stack.push({
224
- node: ctxProvider,
225
- prev: null
226
- }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
227
- }
228
- const rootLen = stack.length;
229
- const ctx = this.ctx = {
230
- realParent: root,
231
- prevSibling: before,
232
- current: null,
233
- stack,
234
- before
175
+ setToken(type, value) {
176
+ this.token = {
177
+ type,
178
+ typeName: TokenType[type],
179
+ value,
180
+ loc: null
235
181
  };
236
- const rootPulling = aoye.getPulling();
237
- while (1) {
238
- if (this.tokenizer.isEof()) {
239
- if (!ctx.prevSibling) ctx.prevSibling = before;
240
- this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
241
- break;
242
- }
243
- const token = this.tokenizer.token;
244
- if (token.type & TokenType.Indent) {
245
- this.tokenizer.nextToken();
246
- const isLogicNode = this.isLogicNode(ctx.current);
247
- stack.push({
248
- node: ctx.current,
249
- prev: ctx.prevSibling
250
- }, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider);
251
- if (ctx.current.__logicType) {
252
- if (isLogicNode) {
253
- aoye.setPulling(ctx.current.effect);
254
- if (ctx.current.__logicType & FakeType.ForItem) {
255
- ctx.prevSibling = ctx.current.realBefore;
256
- }
257
- }
258
- } else {
259
- if (ctx.current) {
260
- ctx.realParent = ctx.current;
261
- }
262
- ctx.prevSibling = null;
263
- }
264
- ctx.current = this.declaration(ctx);
265
- continue;
182
+ this.isFirstToken = false;
183
+ }
184
+ nextToken() {
185
+ try {
186
+ if (this.isEof()) {
187
+ return this.token;
266
188
  }
267
- if (ctx.current) {
268
- if (stack.length === rootLen && !ctx.prevSibling) {
269
- ctx.prevSibling = before;
270
- }
271
- this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
189
+ this.token = undefined;
190
+ if (this.waitingTokens.len) {
191
+ const item = this.waitingTokens.shift();
192
+ this.setToken(item.type, item.value);
193
+ return this.token;
272
194
  }
273
- if (this.tokenizer.token.type & TokenType.Dedent) {
274
- this.tokenizer.nextToken();
275
- const _stack$pop = stack.pop(),
276
- _stack$pop2 = _slicedToArray(_stack$pop, 2),
277
- _stack$pop2$ = _stack$pop2[0],
278
- parent = _stack$pop2$.node,
279
- prev = _stack$pop2$.prev,
280
- sort = _stack$pop2[1];
281
- if (!parent.__logicType) {
282
- const prevSameType = stack.peekByType(NodeSort.Real);
283
- ctx.realParent = prevSameType?.node || root;
195
+ outer: while (1) {
196
+ if (this.needIndent) {
197
+ this.dent();
284
198
  } else {
285
- if (sort & NodeSort.Logic) {
286
- const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
287
- if (parentLogic) {
288
- aoye.setPulling(parentLogic.effect);
289
- } else {
290
- aoye.setPulling(rootPulling);
291
- }
292
- }
293
- if (sort & NodeSort.TokenizerSwitcher) {
294
- const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
295
- this.tokenizer = switcher.tokenizer;
296
- }
297
- if (parent.__logicType === FakeType.ForItem) {
298
- const _ref = parent,
299
- forNode = _ref.forNode;
300
- const i = forNode.i,
301
- arr = forNode.arr,
302
- snapshot = forNode.snapshot;
303
- if (i + 1 < arr.length) {
304
- this.tokenizer.resume(snapshot);
305
- this.tokenizer.nextToken();
306
- this.tokenizer.nextToken();
307
- ctx.current = forNode.children[++forNode.i];
308
- ctx.prevSibling = ctx.current.realBefore;
309
- continue;
310
- }
311
- ctx.prevSibling = forNode.prevSibling;
312
- ctx.current = forNode;
313
- continue;
199
+ const char = this.code[this.i];
200
+ switch (char) {
201
+ case '\t':
202
+ case ' ':
203
+ break;
204
+ case '\n':
205
+ this.newLine();
206
+ this.needIndent = true;
207
+ break;
208
+ case '=':
209
+ this.assignment();
210
+ break;
211
+ case '|':
212
+ this.pipe();
213
+ break;
214
+ case ';':
215
+ this.setToken(TokenType.Semicolon, ';');
216
+ break;
217
+ default:
218
+ if (false) ;
219
+ switch (char) {
220
+ case "'":
221
+ case '"':
222
+ this.str(char);
223
+ break;
224
+ case '{':
225
+ const braceToken = this.brace();
226
+ this.setToken(TokenType.InsertionExp, braceToken);
227
+ break;
228
+ case '$':
229
+ const handled = this.staticIns();
230
+ if (handled) break;
231
+ default:
232
+ if (bobeShared.isNum(char)) {
233
+ this.number(char);
234
+ break;
235
+ }
236
+ if (typeof char === 'string' && bobeShared.matchIdStart2(char, 0)) {
237
+ this.identifier(char);
238
+ }
239
+ break;
240
+ }
241
+ if (false) ;
242
+ break;
314
243
  }
244
+ this.next();
245
+ }
246
+ if (this.token) {
247
+ break;
315
248
  }
316
- ctx.prevSibling = prev;
317
- ctx.current = parent;
318
- } else {
319
- ctx.prevSibling = ctx.current || ctx.prevSibling;
320
- ctx.current = this.declaration(ctx);
321
249
  }
250
+ return this.token;
251
+ } catch (error) {
252
+ console.error(error);
253
+ return this.token;
254
+ } finally {
255
+ this.handledTokens.push(this.token);
322
256
  }
323
- return componentNode;
324
- }
325
- insertAfterAnchor(name = 'anchor') {
326
- const _this$ctx = this.ctx,
327
- realParent = _this$ctx.realParent,
328
- prevSibling = _this$ctx.prevSibling,
329
- stack = _this$ctx.stack,
330
- before = _this$ctx.before;
331
- const afterAnchor = this.createAnchor(name);
332
- this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
333
- this.handleInsert(realParent, afterAnchor, prevSibling);
334
- return afterAnchor;
335
257
  }
336
- handleInsert(parent, child, prev, parentComponent) {
337
- if (!child.__logicType) {
338
- if (!prev || !prev.__logicType) {
339
- this.insertAfter(parent, child, prev);
340
- } else {
341
- const before = prev.realAfter;
342
- this.insertAfter(parent, child, before);
258
+ condExp() {
259
+ let value = '';
260
+ this.token = null;
261
+ try {
262
+ if (this.code[this.i] === '\n') {
263
+ this.setToken(TokenType.Identifier, true);
264
+ return this.token;
343
265
  }
344
- } else {
345
- const childCmp = child;
346
- childCmp.realParent = parent;
347
- if (prev?.__logicType) {
348
- childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
349
- } else {
350
- childCmp.realBefore = prev;
266
+ while (this.code[this.i + 1] !== '\n') {
267
+ value += this.code[this.i];
268
+ this.next();
351
269
  }
270
+ value += this.code[this.i];
271
+ const trimmed = value.trim();
272
+ this.setToken(TokenType.Identifier, trimmed ? value : true);
273
+ return this.token;
274
+ } finally {
275
+ this.next();
276
+ this.handledTokens.push(this.token);
352
277
  }
353
278
  }
354
- getPrevRealSibling(prevSibling) {
355
- if (!prevSibling || !prevSibling.__logicType) {
356
- return prevSibling;
357
- }
358
- let point = prevSibling;
359
- while (point != null) {
360
- if (point.lastChild) {
361
- return point.lastChild.value;
279
+ jsExp() {
280
+ this.token = null;
281
+ let value = '';
282
+ try {
283
+ const char = this.code[this.i];
284
+ if (char === ';' || char === '\n') {
285
+ this.setToken(TokenType.Identifier, value);
286
+ return this.token;
362
287
  }
363
- point = point.anchor;
364
- }
365
- }
366
- declaration(ctx) {
367
- const _this$tokenizer$_hook = this.tokenizer._hook({}),
368
- _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
369
- hookType = _this$tokenizer$_hook2[0],
370
- value = _this$tokenizer$_hook2[1];
371
- let _node;
372
- if (value === 'if' || value === 'else' || value === 'fail') {
373
- return this.condDeclaration(ctx);
374
- } else if (value === 'for') {
375
- return this.forDeclaration();
376
- } else if (hookType) {
377
- const data = this.getData();
378
- if (hookType === 'static') {
379
- if (typeof value === 'function') {
380
- _node = this.componentOrFragmentDeclaration(value, ctx);
381
- } else {
382
- throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
383
- }
384
- } else {
385
- const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
386
- const val = data[aoye.Keys.Raw][value];
387
- if (typeof val === 'function') {
388
- _node = this.componentOrFragmentDeclaration(val, ctx);
389
- } else {
390
- const str = valueIsMapKey ? value : this.getFn(data, value);
391
- _node = this.createNode('text');
392
- this.onePropParsed(data, _node, 'text', str, valueIsMapKey, false);
393
- }
288
+ let nextC = this.code[this.i + 1];
289
+ while (nextC !== ';' && nextC !== '\n') {
290
+ value += this.code[this.i];
291
+ this.next();
292
+ nextC = this.code[this.i + 1];
394
293
  }
395
- } else {
396
- _node = this.createNode(value);
294
+ value += this.code[this.i];
295
+ this.setToken(TokenType.Identifier, value);
296
+ return this.token;
297
+ } finally {
298
+ this.next();
299
+ this.handledTokens.push(this.token);
397
300
  }
398
- this.tokenizer.nextToken();
399
- this.headerLine(_node);
400
- this.extensionLines(_node);
401
- if (_node.__logicType & TokenizerSwitcherBit) {
402
- this.onePropParsed = this.oneRealPropParsed;
403
- this.tokenizer = _node.tokenizer;
301
+ }
302
+ peekChar() {
303
+ let i = this.i;
304
+ while (this.code[i] === ' ' || this.code[i] === '\t') {
305
+ i++;
404
306
  }
405
- return _node;
307
+ return this.code[i];
406
308
  }
407
- forDeclaration() {
408
- const arrExp = this.tokenizer.nextToken().value;
409
- this.tokenizer.nextToken();
410
- const itemToken = this.tokenizer.nextToken();
411
- const isDestruct = itemToken.type === TokenType.InsertionExp;
412
- let itemExp = itemToken.value,
413
- vars;
414
- if (isDestruct) {
415
- itemExp = '{' + itemExp + '}';
416
- vars = itemExp.match(bobeShared.jsVarRegexp);
417
- const varStr = vars.join(',');
418
- itemExp = new Function(itemExp, `return {${varStr}};`);
309
+ assignment() {
310
+ this.setToken(TokenType.Assign, '=');
311
+ }
312
+ pipe() {
313
+ this.setToken(TokenType.Pipe, '|');
314
+ }
315
+ staticIns() {
316
+ let nextC = this.code[this.i + 1];
317
+ if (nextC !== '{') {
318
+ return false;
419
319
  }
420
- let indexName,
421
- keyExp,
422
- char = this.tokenizer.peekChar();
423
- if (char === ';') {
424
- this.tokenizer.nextToken();
425
- if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
426
- } else if (char === '\n') ; else {
427
- indexName = this.tokenizer.nextToken().value;
428
- if (this.tokenizer.peekChar() === ';') {
429
- this.tokenizer.nextToken();
430
- if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
320
+ this.next();
321
+ let value = '';
322
+ let innerBrace = 0;
323
+ while (1) {
324
+ nextC = this.code[this.i + 1];
325
+ value += nextC;
326
+ this.next();
327
+ if (nextC === '{') {
328
+ innerBrace++;
329
+ }
330
+ if (nextC === '}') {
331
+ if (!innerBrace) {
332
+ break;
333
+ }
334
+ innerBrace--;
431
335
  }
432
336
  }
433
- const owner = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
434
- const prevSibling = this.ctx.prevSibling;
435
- const forNode = {
436
- __logicType: FakeType.For,
437
- snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
438
- realParent: this.ctx.realParent,
439
- prevSibling,
440
- realBefore: prevSibling?.realAfter || prevSibling,
441
- realAfter: null,
442
- arr: null,
443
- arrSignal: null,
444
- itemExp,
445
- indexName,
446
- getKey: null,
447
- children: [],
448
- effect: null,
449
- owner,
450
- vars,
451
- i: 0
337
+ this.setToken(TokenType.StaticInsExp, value.slice(0, -1));
338
+ return true;
339
+ }
340
+ brace() {
341
+ let inComment,
342
+ inString,
343
+ count = 0,
344
+ value = '',
345
+ backslashCount = 0;
346
+ while (1) {
347
+ const char = this.code[this.i];
348
+ const nextChar = this.code[this.i + 1];
349
+ if (inComment === 'single' && char === '\n') {
350
+ inComment = null;
351
+ } else if (inComment === 'multi' && char === '*' && nextChar === '/') {
352
+ inComment = null;
353
+ value += this.code[this.i];
354
+ this.next();
355
+ } else if (inString) {
356
+ if (char === inString && backslashCount % 2 === 0) {
357
+ inString = null;
358
+ }
359
+ backslashCount = char === '\\' ? backslashCount + 1 : 0;
360
+ } else {
361
+ if (char === '/' && nextChar === '/') {
362
+ inComment = 'single';
363
+ value += this.code[this.i];
364
+ this.next();
365
+ } else if (char === '/' && nextChar === '*') {
366
+ inComment = 'multi';
367
+ value += this.code[this.i];
368
+ this.next();
369
+ } else if (char === "'" || char === '"' || char === '`') {
370
+ inString = char;
371
+ } else if (char === '{') {
372
+ count++;
373
+ } else if (char === '}') {
374
+ count--;
375
+ }
376
+ }
377
+ if (count === 0 && inString == null && inComment == null) {
378
+ return value.slice(1);
379
+ }
380
+ value += this.code[this.i];
381
+ this.next();
382
+ }
383
+ }
384
+ newLine() {
385
+ let value = '\n';
386
+ let nextC;
387
+ while (1) {
388
+ nextC = this.code[this.i + 1];
389
+ if (nextC !== '\n') {
390
+ break;
391
+ }
392
+ value += nextC;
393
+ this.next();
394
+ }
395
+ if (this.isFirstToken) {
396
+ return;
397
+ }
398
+ this.setToken(TokenType.NewLine, value);
399
+ }
400
+ getDentValue() {
401
+ let value = '';
402
+ let nextC;
403
+ let isEmptyLine = false;
404
+ while (1) {
405
+ const nextChar = this.code[this.i];
406
+ switch (nextChar) {
407
+ case '\t':
408
+ nextC = this.Tab;
409
+ break;
410
+ case ' ':
411
+ nextC = ' ';
412
+ break;
413
+ case '\n':
414
+ nextC = '\n';
415
+ break;
416
+ default:
417
+ nextC = '';
418
+ break;
419
+ }
420
+ if (nextC === '\n') {
421
+ isEmptyLine = true;
422
+ break;
423
+ }
424
+ if (!nextC) {
425
+ break;
426
+ }
427
+ value += nextC;
428
+ this.next();
429
+ }
430
+ return {
431
+ value,
432
+ isEmptyLine
452
433
  };
453
- if (keyExp) {
454
- forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}};return v;`);
434
+ }
435
+ dent() {
436
+ const _this$getDentValue2 = this.getDentValue(),
437
+ value = _this$getDentValue2.value,
438
+ isEmptyLine = _this$getDentValue2.isEmptyLine;
439
+ if (isEmptyLine) {
440
+ this.needIndent = true;
441
+ return;
455
442
  }
456
- window['for1'] = forNode;
457
- const data = this.getData();
458
- const cells = data[aoye.Keys.Meta].cells;
459
- const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
460
- const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new aoye.Computed(this.getFn(data, arrExp));
461
- forNode.arrSignal = arrSignal;
462
- forNode.realAfter = this.insertAfterAnchor('for-after');
463
- const _forNode$snapshot = forNode.snapshot;
464
- _forNode$snapshot.dentStack;
465
- _forNode$snapshot.isFirstToken;
466
- const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
467
- let isFirstRender = true;
468
- forNode.effect = new aoye.Effect(() => {
469
- let arr = arrSignal.get();
470
- arr[aoye.Keys.Iterator];
471
- const prevCtx = aoye.getPulling();
472
- aoye.setPulling(null);
473
- forNode.arr = arr = aoye.toRaw(arr);
474
- const children = forNode.children;
475
- if (isFirstRender) {
476
- const len = arr.length;
477
- for (let i = len; i--;) {
478
- const item = this.createForItem(forNode, i, data);
479
- item.realAfter = this.insertAfterAnchor('for-item-after');
480
- item.realBefore = this.insertAfterAnchor('for-item-before');
481
- item.realParent = forNode.realParent;
482
- children[i] = item;
443
+ this.needIndent = false;
444
+ if (this.isFirstToken) {
445
+ this.dentStack[0] = value.length;
446
+ return;
447
+ }
448
+ let currLen = value.length;
449
+ const indentHasLen = currLen > 0;
450
+ const prevLen = this.dentStack[this.dentStack.length - 1];
451
+ if (currLen > prevLen) {
452
+ this.dentStack.push(currLen);
453
+ this.setToken(TokenType.Indent, currLen);
454
+ return indentHasLen;
455
+ }
456
+ if (currLen < prevLen) {
457
+ for (let i = this.dentStack.length; i--;) {
458
+ const expLen = this.dentStack[i];
459
+ if (currLen === expLen) break;
460
+ if (currLen > expLen) {
461
+ throw SyntaxError('缩进大小不统一');
483
462
  }
484
- const firstInsert = children[0];
485
- if (firstInsert) {
486
- this.tokenizer.nextToken();
487
- this.tokenizer.nextToken();
488
- } else {
489
- this.tokenizer.skip();
463
+ if (this.shorterThanBaseDentEof()) {
464
+ return;
490
465
  }
491
- } else {
492
- const oldLen = children.length;
493
- const newLen = arr.length;
494
- const minLen = Math.min(oldLen, newLen);
495
- const newChildren = [];
496
- if (!forNode.getKey) {
497
- if (newLen < oldLen) {
498
- for (let i = oldLen - 1; i >= newLen; i--) {
499
- this.removeForItem(children, i);
500
- }
501
- }
502
- if (oldLen < newLen) {
503
- const lastAfter = children.at(-1)?.realAfter || forNode.realBefore;
504
- for (let i = newLen - 1; i >= oldLen; i--) {
505
- this.insertForItem(forNode, i, data, newChildren, lastAfter, snapshotForUpdate);
506
- }
507
- }
508
- for (let i = minLen; i--;) {
509
- const child = children[i];
510
- newChildren[i] = child;
511
- this.reuseForItem(child, arr[i], itemExp, i, indexName);
512
- }
466
+ this.dentStack.pop();
467
+ if (!this.token) {
468
+ this.setToken(TokenType.Dedent, String(expLen));
513
469
  } else {
514
- let s = 0,
515
- e1 = oldLen - 1,
516
- e2 = newLen - 1;
517
- while (s <= e1 && s <= e2) {
518
- const child = children[s];
519
- const old = child.key;
520
- const itemData = this.getItemData(forNode, s, data);
521
- const key = forNode.getKey(itemData);
522
- if (old === key) {
523
- newChildren[s] = child;
524
- this.reuseForItem(child, arr[s], itemExp, s, indexName);
525
- s++;
526
- } else {
527
- break;
528
- }
529
- }
530
- while (s <= e1 && s <= e2) {
531
- const child = children[e1];
532
- const old = child.key;
533
- const itemData = this.getItemData(forNode, e2, data);
534
- const key = forNode.getKey(itemData);
535
- if (old === key) {
536
- newChildren[e2] = child;
537
- this.reuseForItem(child, arr[e2], itemExp, e2, indexName);
538
- e1--;
539
- e2--;
540
- } else {
541
- break;
542
- }
543
- }
544
- if (s > e1) {
545
- if (s <= e2) {
546
- const firstBefore = s > 0 ? children.at(-1)?.realAfter || forNode.realBefore : forNode.realBefore;
547
- for (let i = e2; i >= s; i--) {
548
- this.insertForItem(forNode, i, data, newChildren, firstBefore, snapshotForUpdate);
549
- }
550
- }
551
- } else if (s > e2) {
552
- if (s <= e1) {
553
- for (let i = e1; i >= s; i--) {
554
- this.removeForItem(children, i);
555
- }
556
- }
557
- } else {
558
- let s1 = s,
559
- s2 = s;
560
- const mixLen = e2 - s2 + 1;
561
- const key2new = new Map();
562
- for (let i = s2; i <= e2; i++) {
563
- const itemData = this.getItemData(forNode, i, data);
564
- const key = forNode.getKey(itemData);
565
- key2new.set(key, i);
566
- }
567
- let maxIncNewI = -1;
568
- let hasMove = false;
569
- const new2oldI = new Array(mixLen).fill(-1);
570
- for (let i = s1; i <= e1; i++) {
571
- const key = children[i].key;
572
- const newI = key2new.get(key);
573
- if (newI == null) {
574
- this.removeForItem(children, i);
575
- continue;
576
- }
577
- const child = children[i];
578
- newChildren[newI] = child;
579
- this.reuseForItem(child, arr[newI], itemExp, newI, indexName);
580
- new2oldI[newI - s2] = i;
581
- key2new.delete(key);
582
- if (newI < maxIncNewI) {
583
- hasMove = true;
584
- } else {
585
- maxIncNewI = newI;
586
- }
587
- }
588
- if (!hasMove) {
589
- key2new.forEach((i, key) => {
590
- const before = i === 0 ? forNode.realBefore : newChildren[i - 1].realAfter;
591
- this.insertForItem(forNode, i, data, newChildren, before, snapshotForUpdate);
592
- });
593
- } else {
594
- const incI = macInc(new2oldI),
595
- incLen = incI.length;
596
- let p1, p2;
597
- for (p1 = s2, p2 = 0; p1 <= e2; p1++) {
598
- const oldI = new2oldI[p1];
599
- if (oldI === -1) {
600
- const before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
601
- this.insertForItem(forNode, p1, data, newChildren, before, snapshotForUpdate);
602
- continue;
603
- }
604
- const staticIdx = incI[p2] + s2;
605
- if (p1 === staticIdx) {
606
- p2 <= incLen && p2++;
607
- continue;
608
- }
609
- let before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
610
- const child = newChildren[p1];
611
- const realBefore = child.realBefore,
612
- realAfter = child.realAfter,
613
- realParent = child.realParent;
614
- let point = realBefore,
615
- next;
616
- do {
617
- next = this.nextSib(point);
618
- this.insertAfter(realParent, point, before);
619
- before = point;
620
- if (point === realAfter) break;
621
- point = next;
622
- } while (true);
623
- }
624
- }
625
- }
470
+ this.waitingTokens.push({
471
+ type: TokenType.Dedent,
472
+ typeName: TokenType[TokenType.Dedent],
473
+ value: String(expLen),
474
+ loc: null
475
+ });
626
476
  }
627
- forNode.children = newChildren;
628
477
  }
629
- isFirstRender = false;
630
- aoye.setPulling(prevCtx);
631
- return isDestroy => {
632
- if (isDestroy) {
633
- for (let i = 0; i < forNode.children.length; i++) {
634
- const item = forNode.children[i];
635
- item.effect.dispose();
636
- }
478
+ return indentHasLen;
479
+ }
480
+ return indentHasLen;
481
+ }
482
+ shorterThanBaseDentEof() {
483
+ const yes = this.dentStack.length === 1;
484
+ if (yes) {
485
+ if (!this.token) {
486
+ if (this.useDedentAsEof) {
487
+ this.setToken(TokenType.Dedent, '');
488
+ } else {
489
+ this.setToken(TokenType.Identifier, Tokenizer.EofId);
637
490
  }
638
- };
639
- });
640
- return forNode.children[0] || forNode;
491
+ } else {
492
+ if (this.useDedentAsEof) {
493
+ this.waitingTokens.push({
494
+ type: TokenType.Dedent,
495
+ typeName: TokenType[TokenType.Dedent],
496
+ value: '',
497
+ loc: null
498
+ });
499
+ } else {
500
+ this.waitingTokens.push({
501
+ type: TokenType.Identifier,
502
+ typeName: TokenType[TokenType.Identifier],
503
+ value: Tokenizer.EofId,
504
+ loc: null
505
+ });
506
+ }
507
+ }
508
+ }
509
+ return yes;
641
510
  }
642
- insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
643
- const item = this.createForItem(forNode, i, parentData);
644
- newChildren[i] = item;
645
- let realAfter = this.createAnchor('for-item-after');
646
- this.handleInsert(forNode.realParent, realAfter, before);
647
- let realBefore = this.createAnchor('for-item-before');
648
- this.handleInsert(forNode.realParent, realBefore, before);
649
- item.realBefore = realBefore;
650
- item.realAfter = realAfter;
651
- this.tokenizer = forNode.owner.tokenizer;
652
- this.tokenizer.resume(snapshotForUpdate);
653
- this.tokenizer.useDedentAsEof = false;
654
- aoye.runWithPulling(() => {
655
- this.program(forNode.realParent, forNode.owner, realBefore, item);
656
- }, item.effect);
511
+ identifier(char) {
512
+ let value = char;
513
+ let nextC;
514
+ while (1) {
515
+ nextC = this.code[this.i + 1];
516
+ if (typeof nextC !== 'string' || !bobeShared.matchIdStart2(nextC, 0)) {
517
+ break;
518
+ }
519
+ value += nextC;
520
+ this.next();
521
+ }
522
+ if (value === Tokenizer.EofId && this.useDedentAsEof) {
523
+ this.setToken(TokenType.Dedent, '');
524
+ return;
525
+ }
526
+ let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
527
+ this.setToken(TokenType.Identifier, realValue);
657
528
  }
658
- removeForItem(children, i) {
659
- const child = children[i];
660
- this.removeLogicNode(child);
661
- this.remove(child.realBefore);
662
- this.remove(child.realAfter);
663
- child.effect.dispose();
529
+ str(char) {
530
+ let value = '';
531
+ let nextC;
532
+ let continuousBackslashCount = 0;
533
+ while (1) {
534
+ nextC = this.code[this.i + 1];
535
+ const memoCount = continuousBackslashCount;
536
+ if (nextC === '\\') {
537
+ continuousBackslashCount++;
538
+ } else {
539
+ continuousBackslashCount = 0;
540
+ }
541
+ this.next();
542
+ if (nextC === char && memoCount % 2 === 0) {
543
+ break;
544
+ }
545
+ value += nextC;
546
+ }
547
+ this.setToken(TokenType.Identifier, value);
664
548
  }
665
- reuseForItem(child, data, itemExp, i, indexName) {
666
- if (typeof itemExp === 'string') {
667
- child.data[itemExp] = data;
668
- if (indexName) {
669
- child.data[indexName] = i;
549
+ number(char) {
550
+ let value = char;
551
+ let nextC;
552
+ while (1) {
553
+ nextC = this.code[this.i + 1];
554
+ if (!bobeShared.isNum(nextC)) {
555
+ break;
670
556
  }
557
+ value += nextC;
558
+ this.next();
559
+ }
560
+ this.setToken(TokenType.Identifier, Number(value));
561
+ }
562
+ eof() {
563
+ this.setToken(TokenType.Eof, 'End Of File');
564
+ }
565
+ HookId = '_h_o_o_k_';
566
+ hookI = 0;
567
+ _hook = props => {
568
+ const value = this.token.value;
569
+ const isDynamicHook = this.token.type & TokenType.InsertionExp;
570
+ let isStaticHook;
571
+ {
572
+ isStaticHook = typeof value === 'string' && value.indexOf(this.HookId) === 0;
573
+ }
574
+ const hookType = isDynamicHook ? 'dynamic' : isStaticHook ? 'static' : undefined;
575
+ if (this.hook && isStaticHook) {
576
+ const hookI = Number(value.slice(this.HookId.length));
577
+ const res = this.hook({
578
+ ...props,
579
+ HookId: this.HookId,
580
+ i: hookI
581
+ });
582
+ return [hookType, res, hookI];
583
+ } else if (isDynamicHook) {
584
+ return [hookType, value];
585
+ }
586
+ return [hookType, value];
587
+ };
588
+ init(fragments) {
589
+ if (typeof fragments === 'string') {
590
+ this.setCode(fragments);
671
591
  } else {
672
- indexName = indexName || KEY_INDEX;
673
- child.data[indexName] = i;
592
+ let code = '';
593
+ for (let i = 0; i < fragments.length - 1; i++) {
594
+ const fragment = fragments[i];
595
+ code += fragment + `${this.HookId}${i}`;
596
+ }
597
+ this.setCode(code + fragments[fragments.length - 1]);
674
598
  }
675
599
  }
676
- forItemId = 0;
677
- createForItem(forNode, i, parentData) {
678
- let forItemNode;
679
- let data;
680
- const scope = new aoye.Scope(() => {});
681
- scope.scope = null;
682
- aoye.runWithPulling(() => {
683
- scope.get();
684
- }, null);
685
- data = this.getItemData(forNode, i, parentData);
686
- forItemNode = {
687
- id: this.forItemId++,
688
- __logicType: FakeType.ForItem,
689
- realParent: null,
690
- realBefore: null,
691
- realAfter: null,
692
- forNode,
693
- key: forNode.getKey?.(data),
694
- effect: null,
695
- data
600
+ }
601
+
602
+ var NodeType = function (NodeType) {
603
+ NodeType["Element"] = "Element";
604
+ NodeType["Text"] = "Text";
605
+ NodeType["Interpolation"] = "Interpolation";
606
+ NodeType["Property"] = "Property";
607
+ NodeType["PropertyKey"] = "PropertyKey";
608
+ NodeType["StaticValue"] = "StaticValue";
609
+ NodeType["DynamicValue"] = "DynamicValue";
610
+ NodeType["Program"] = "Program";
611
+ NodeType["If"] = "If";
612
+ NodeType["Else"] = "Else";
613
+ NodeType["Fail"] = "Fail";
614
+ NodeType["For"] = "For";
615
+ NodeType["Component"] = "Component";
616
+ NodeType["Fragment"] = "Fragment";
617
+ return NodeType;
618
+ }(NodeType || {});
619
+
620
+ function _applyDecs2311(e, t, n, r, o, i) {
621
+ var a,
622
+ c,
623
+ u,
624
+ s,
625
+ f,
626
+ l,
627
+ p,
628
+ d = Symbol.metadata || Symbol.for("Symbol.metadata"),
629
+ m = Object.defineProperty,
630
+ h = Object.create,
631
+ y = [h(null), h(null)],
632
+ v = t.length;
633
+ function g(t, n, r) {
634
+ return function (o, i) {
635
+ n && (i = o, o = e);
636
+ for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []);
637
+ return r ? i : o;
696
638
  };
697
- forItemNode.effect = scope;
698
- return forItemNode;
699
639
  }
700
- getItemData(forNode, i, parentData) {
701
- const arr = forNode.arr,
702
- itemExp = forNode.itemExp,
703
- vars = forNode.vars,
704
- arrSignal = forNode.arrSignal,
705
- getKey = forNode.getKey;
706
- let indexName = forNode.indexName;
707
- let data;
708
- if (typeof itemExp === 'string') {
709
- data = aoye.deepSignal(indexName ? {
710
- [itemExp]: arr[i],
711
- [indexName]: i
712
- } : {
713
- [itemExp]: arr[i]
714
- }, aoye.getPulling());
715
- } else {
716
- indexName = indexName ?? KEY_INDEX;
717
- const rawData = {
718
- [indexName]: i
640
+ function b(e, t, n, r) {
641
+ if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined"));
642
+ return e;
643
+ }
644
+ function applyDec(e, t, n, r, o, i, u, s, f, l, p) {
645
+ function d(e) {
646
+ if (!p(e)) throw new TypeError("Attempted to access private element on non-instance");
647
+ }
648
+ var h = [].concat(t[0]),
649
+ v = t[3],
650
+ w = !u,
651
+ D = 1 === o,
652
+ S = 3 === o,
653
+ j = 4 === o,
654
+ E = 2 === o;
655
+ function I(t, n, r) {
656
+ return function (o, i) {
657
+ return n && (i = o, o = e), r && r(o), P[t].call(o, i);
719
658
  };
720
- data = aoye.deepSignal(rawData, aoye.getPulling());
721
- const computedData = new aoye.Computed(() => itemExp(arrSignal.get()[getKey ? data[indexName] : i]));
722
- const cells = data[aoye.Keys.Meta].cells;
723
- for (let i = 0; i < vars.length; i++) {
724
- const name = vars[i];
725
- rawData[name] = undefined;
726
- cells.set(name, new aoye.Computed(() => computedData.get()[name]));
659
+ }
660
+ if (!w) {
661
+ var P = {},
662
+ k = [],
663
+ F = S ? "get" : j || D ? "set" : "value";
664
+ if (f ? (l || D ? P = {
665
+ get: _setFunctionName(function () {
666
+ return v(this);
667
+ }, r, "get"),
668
+ set: function (e) {
669
+ t[4](this, e);
670
+ }
671
+ } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) {
672
+ if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet");
673
+ y[+s][r] = o < 3 ? 1 : o;
727
674
  }
728
675
  }
729
- Object.setPrototypeOf(data, parentData);
730
- return data;
676
+ for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) {
677
+ var T = b(h[O], "A decorator", "be", true),
678
+ z = n ? h[O - 1] : void 0,
679
+ A = {},
680
+ H = {
681
+ kind: ["field", "accessor", "method", "getter", "setter", "class"][o],
682
+ name: r,
683
+ metadata: a,
684
+ addInitializer: function (e, t) {
685
+ if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished");
686
+ b(t, "An initializer", "be", true), i.push(t);
687
+ }.bind(null, A)
688
+ };
689
+ if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = {
690
+ has: f ? p.bind() : function (e) {
691
+ return r in e;
692
+ }
693
+ }, j || (c.get = f ? E ? function (e) {
694
+ return d(e), P.value;
695
+ } : I("get", 0, d) : function (e) {
696
+ return e[r];
697
+ }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) {
698
+ e[r] = t;
699
+ }), N = T.call(z, D ? {
700
+ get: P.get,
701
+ set: P.set
702
+ } : P[F], H), A.v = 1, D) {
703
+ if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined");
704
+ } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N);
705
+ }
706
+ return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N;
731
707
  }
732
- getData() {
733
- const _this$ctx$stack$peekB = this.ctx.stack.peekByType(NodeSort.CtxProvider),
734
- node = _this$ctx$stack$peekB.node;
735
- return node.data;
708
+ function w(e) {
709
+ return m(e, d, {
710
+ configurable: true,
711
+ enumerable: true,
712
+ value: a
713
+ });
736
714
  }
737
- onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
738
- if (isFn) {
739
- this.setProp(node, key, value, hookI);
740
- } else if (typeof value === 'function') {
741
- new aoye.Effect(() => {
742
- const res = value();
743
- this.setProp(node, key, res, hookI);
744
- });
745
- } else if (valueIsMapKey) {
746
- new aoye.Effect(() => {
747
- const res = data[value];
748
- this.setProp(node, key, res, hookI);
749
- });
750
- } else {
751
- this.setProp(node, key, value, hookI);
715
+ return a = h(null == a ? null : a), f = [], l = function (e) {
716
+ e && f.push(g(e));
717
+ }, p = function (t, r) {
718
+ for (var i = 0; i < n.length; i++) {
719
+ var a = n[i],
720
+ c = a[1],
721
+ l = 7 & c;
722
+ if ((8 & c) == t && !l == r) {
723
+ var p = a[2],
724
+ d = !!a[3],
725
+ m = 16 & c;
726
+ applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) {
727
+ return _checkInRHS(t) === e;
728
+ } : o);
729
+ }
730
+ }
731
+ }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), {
732
+ e: c,
733
+ get c() {
734
+ var n = [];
735
+ return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)];
736
+ }
737
+ };
738
+ }
739
+ function _arrayLikeToArray(r, a) {
740
+ (null == a || a > r.length) && (a = r.length);
741
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
742
+ return n;
743
+ }
744
+ function _arrayWithHoles(r) {
745
+ if (Array.isArray(r)) return r;
746
+ }
747
+ function _checkInRHS(e) {
748
+ if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
749
+ return e;
750
+ }
751
+ function _iterableToArrayLimit(r, l) {
752
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
753
+ if (null != t) {
754
+ var e,
755
+ n,
756
+ i,
757
+ u,
758
+ a = [],
759
+ f = true,
760
+ o = false;
761
+ try {
762
+ if (i = (t = t.call(r)).next, 0 === l) {
763
+ if (Object(t) !== t) return;
764
+ f = !1;
765
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
766
+ } catch (r) {
767
+ o = true, n = r;
768
+ } finally {
769
+ try {
770
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
771
+ } finally {
772
+ if (o) throw n;
773
+ }
752
774
  }
775
+ return a;
776
+ }
777
+ }
778
+ function _nonIterableRest() {
779
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
780
+ }
781
+ function _objectWithoutProperties(e, t) {
782
+ if (null == e) return {};
783
+ var o,
784
+ r,
785
+ i = _objectWithoutPropertiesLoose(e, t);
786
+ if (Object.getOwnPropertySymbols) {
787
+ var n = Object.getOwnPropertySymbols(e);
788
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
789
+ }
790
+ return i;
791
+ }
792
+ function _objectWithoutPropertiesLoose(r, e) {
793
+ if (null == r) return {};
794
+ var t = {};
795
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
796
+ if (-1 !== e.indexOf(n)) continue;
797
+ t[n] = r[n];
798
+ }
799
+ return t;
800
+ }
801
+ function _setFunctionName(e, t, n) {
802
+ "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
803
+ try {
804
+ Object.defineProperty(e, "name", {
805
+ configurable: !0,
806
+ value: n ? n + " " + t : t
807
+ });
808
+ } catch (e) {}
809
+ return e;
810
+ }
811
+ function _slicedToArray(r, e) {
812
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
813
+ }
814
+ function _toPrimitive(t, r) {
815
+ if ("object" != typeof t || !t) return t;
816
+ var e = t[Symbol.toPrimitive];
817
+ if (void 0 !== e) {
818
+ var i = e.call(t, r);
819
+ if ("object" != typeof i) return i;
820
+ throw new TypeError("@@toPrimitive must return a primitive value.");
821
+ }
822
+ return ("string" === r ? String : Number)(t);
823
+ }
824
+ function _toPropertyKey(t) {
825
+ var i = _toPrimitive(t, "string");
826
+ return "symbol" == typeof i ? i : i + "";
827
+ }
828
+ function _unsupportedIterableToArray(r, a) {
829
+ if (r) {
830
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
831
+ var t = {}.toString.call(r).slice(8, -1);
832
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
753
833
  }
754
- oneRealPropParsed = this.onePropParsed.bind(this);
755
- componentOrFragmentDeclaration(ComponentOrRender, ctx) {
756
- let Component, render, child;
757
- const isCC = ComponentOrRender.prototype instanceof aoye.Store;
758
- if (isCC) {
759
- Component = ComponentOrRender;
760
- child = Component.new();
761
- } else {
762
- render = ComponentOrRender;
763
- const boundStore = render.boundStore;
764
- child = aoye.deepSignal({}, aoye.getPulling(), true);
765
- Object.setPrototypeOf(child, boundStore);
834
+ }
835
+
836
+ let _initProto;
837
+ class Compiler {
838
+ static {
839
+ var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"]]).e, 1);
840
+ _initProto = _applyDecs$e[0];
841
+ }
842
+ constructor(tokenizer, hooks = {}) {
843
+ this.tokenizer = tokenizer;
844
+ this.hooks = hooks;
845
+ _initProto(this);
846
+ }
847
+ parseProgram() {
848
+ this.tokenizer.nextToken();
849
+ const body = [];
850
+ while (!this.tokenizer.isEof()) {
851
+ const node = this.templateNode();
852
+ if (node) {
853
+ body.push(node);
854
+ }
766
855
  }
767
- const node = {
768
- __logicType: isCC ? FakeType.Component : FakeType.Fragment,
769
- realParent: ctx.realParent,
770
- realBefore: null,
771
- realAfter: null,
772
- data: child,
773
- tokenizer: render ? render(true) : child['ui'](true)
774
- };
775
- this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
776
- if (isFn) {
777
- child[aoye.Keys.Raw][key] = value;
778
- } else if (valueIsMapKey) {
779
- aoye.shareSignal(data, value, child, key);
780
- } else {
781
- const meta = child[aoye.Keys.Meta];
782
- const cells = meta.cells;
783
- if (typeof value === 'function') {
784
- const computed = new aoye.Computed(value);
785
- cells.set(key, computed);
786
- child[aoye.Keys.Raw][key] = undefined;
787
- } else {
788
- cells.set(key, {
789
- get: () => value
790
- });
791
- child[aoye.Keys.Raw][key] = value;
792
- }
856
+ return {
857
+ type: NodeType.Program,
858
+ body,
859
+ loc: {
860
+ start: {
861
+ offset: 0,
862
+ line: 1,
863
+ column: 0
864
+ },
865
+ end: {
866
+ offset: this.tokenizer.preI,
867
+ line: this.tokenizer.line,
868
+ column: this.tokenizer.column
869
+ },
870
+ source: this.tokenizer.code
793
871
  }
794
872
  };
795
- node.realAfter = this.insertAfterAnchor('component-after');
796
- return node;
797
873
  }
798
- getFn(data, expression) {
799
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
800
- }
801
- condDeclaration(ctx) {
802
- const prevSibling = ctx.prevSibling;
803
- const keyWord = this.tokenizer.token;
804
- const expToken = this.tokenizer.condExp();
805
- const value = expToken.value;
806
- const isElse = keyWord.value === 'else';
807
- const isIf = keyWord.value === 'if';
808
- const preIsCond = prevSibling?.__logicType & CondBit;
809
- const data = this.getData();
810
- const noCond = value === true;
811
- const valueIsMapKey = !noCond && Reflect.has(data[aoye.Keys.Raw], value);
812
- const owner = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
813
- const ifNode = {
814
- __logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
815
- snapshot: this.tokenizer.snapshot(),
816
- realParent: null,
817
- realBefore: null,
818
- realAfter: null,
819
- condition: null,
820
- preCond: preIsCond ? prevSibling : null,
821
- isFirstRender: true,
822
- effect: null,
823
- owner,
824
- data
825
- };
826
- let signal;
827
- switch (keyWord.value) {
828
- case 'if':
829
- if (valueIsMapKey) {
830
- aoye.runWithPulling(() => data[value], null);
831
- const cells = data[aoye.Keys.Meta].cells;
832
- signal = cells.get(value);
833
- } else {
834
- const fn = this.getFn(data, value);
835
- signal = new aoye.Computed(fn);
836
- }
837
- break;
838
- case 'else':
839
- if (noCond) {
840
- signal = new aoye.Computed(() => {
841
- let point = ifNode.preCond;
842
- while (point) {
843
- if (point.condition.get()) {
844
- return false;
845
- }
846
- if (point.__logicType === FakeType.If) {
847
- break;
848
- }
849
- point = point.preCond;
850
- }
851
- return true;
852
- });
853
- } else {
854
- const fn = valueIsMapKey ? null : this.getFn(data, value);
855
- signal = new aoye.Computed(() => {
856
- let point = ifNode.preCond;
857
- while (point) {
858
- if (point.condition.get()) {
859
- return false;
860
- }
861
- if (point.__logicType === FakeType.If) {
862
- break;
863
- }
864
- point = point.preCond;
865
- }
866
- return valueIsMapKey ? data[value] : fn();
867
- });
868
- }
869
- break;
870
- case 'fail':
871
- signal = new aoye.Computed(() => {
872
- let point = ifNode.preCond;
873
- while (point) {
874
- if (point.condition.get()) {
875
- return false;
876
- }
877
- point = point.preCond;
878
- }
879
- return true;
880
- });
881
- break;
882
- }
883
- ifNode.condition = signal;
884
- ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
885
- const ef = aoye.effect(({
886
- val
887
- }) => {
888
- if (val) {
889
- if (ifNode.isFirstRender) {
890
- this.tokenizer.nextToken();
891
- this.tokenizer.nextToken();
892
- } else {
893
- this.tokenizer = ifNode.owner.tokenizer;
894
- this.tokenizer.resume(ifNode.snapshot);
895
- this.tokenizer.useDedentAsEof = false;
896
- this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
897
- }
898
- } else {
899
- if (ifNode.isFirstRender) {
900
- this.tokenizer.skip();
901
- } else {
902
- this.removeLogicNode(ifNode);
874
+ handleChildren() {
875
+ const children = [];
876
+ if (this.tokenizer.token.type & TokenType.Indent) {
877
+ this.tokenizer.nextToken();
878
+ while (!(this.tokenizer.token.type & TokenType.Dedent) && !this.tokenizer.isEof()) {
879
+ const child = this.templateNode();
880
+ if (child) {
881
+ children.push(child);
903
882
  }
904
883
  }
905
- ifNode.isFirstRender = false;
906
- }, [signal]);
907
- ifNode.effect = ef;
908
- return ifNode;
884
+ if (this.tokenizer.token.type & TokenType.Dedent) {
885
+ this.tokenizer.nextToken();
886
+ }
887
+ }
888
+ return children;
909
889
  }
910
- removeLogicNode(node) {
911
- const realBefore = node.realBefore,
912
- realAfter = node.realAfter,
913
- realParent = node.realParent;
914
- let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
915
- while (point !== realAfter) {
916
- const next = this.nextSib(point);
917
- this.remove(point, realParent, realBefore);
918
- point = next;
890
+ templateNode() {
891
+ this.tokenizer.token;
892
+ const _this$tokenizer$_hook = this.tokenizer._hook({}),
893
+ _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
894
+ hookType = _this$tokenizer$_hook2[0],
895
+ value = _this$tokenizer$_hook2[1];
896
+ if (value === 'if' || value === 'else' || value === 'fail') {
897
+ return this.parseConditionalNode();
919
898
  }
899
+ if (value === 'for') {
900
+ return this.parseLoopNode();
901
+ }
902
+ if (hookType) {
903
+ return this.parseComponentNode();
904
+ }
905
+ return this.parseElementNode();
920
906
  }
921
- extensionLines(_node) {
922
- while (1) {
923
- if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
924
- return;
925
- }
907
+ parseComponentNode(node) {
908
+ const tagToken = this.tokenizer.token;
909
+ const tagName = tagToken.value;
910
+ this.tokenizer.nextToken();
911
+ const props = this.headerLineAndExtensions();
912
+ node.type = NodeType.Component;
913
+ node.componentName = tagName;
914
+ node.props = props;
915
+ this.hooks.parseComponentNode?.propsAdded?.call(this, node);
916
+ const children = this.handleChildren();
917
+ node.children = children;
918
+ return node;
919
+ }
920
+ parseElementNode(node) {
921
+ const tagToken = this.tokenizer.token;
922
+ const tagName = tagToken.value;
923
+ this.tokenizer.nextToken();
924
+ const props = this.headerLineAndExtensions();
925
+ node.type = NodeType.Element;
926
+ node.tagName = tagName;
927
+ node.props = props;
928
+ this.hooks.parseElementNode?.propsAdded?.call(this, node);
929
+ const children = this.handleChildren();
930
+ node.children = children;
931
+ return node;
932
+ }
933
+ parseConditionalNode(node) {
934
+ const keyword = this.tokenizer.token.value;
935
+ const conditionToken = this.tokenizer.condExp();
936
+ const condition = conditionToken.value;
937
+ this.tokenizer.nextToken();
938
+ this.tokenizer.nextToken();
939
+ node.type = keyword === 'if' ? NodeType.If : keyword === 'else' ? NodeType.Else : NodeType.Fail;
940
+ node.condition = condition;
941
+ this.hooks.parseConditionalNode?.propsAdded?.call(this, node);
942
+ const children = this.handleChildren();
943
+ node.children = children;
944
+ return node;
945
+ }
946
+ parseLoopNode(node) {
947
+ const collection = this.tokenizer.nextToken().value;
948
+ this.tokenizer.nextToken();
949
+ const itemToken = this.tokenizer.nextToken();
950
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
951
+ let item = isDestruct ? `{${itemToken.value}}` : itemToken.value;
952
+ let char = this.tokenizer.peekChar(),
953
+ key,
954
+ index;
955
+ if (char === ';') {
926
956
  this.tokenizer.nextToken();
927
- this.attributeList(_node);
928
- if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
929
- return;
957
+ if (this.tokenizer.peekChar() !== '\n') key = this.tokenizer.jsExp().value;
958
+ } else if (char === '\n') ; else {
959
+ index = this.tokenizer.nextToken().value;
960
+ if (this.tokenizer.peekChar() === ';') {
961
+ this.tokenizer.nextToken();
962
+ if (this.tokenizer.peekChar() !== '\n') key = this.tokenizer.jsExp().value;
930
963
  }
931
- this.tokenizer.nextToken();
932
964
  }
933
- }
934
- headerLine(_node) {
935
- this.attributeList(_node);
936
965
  this.tokenizer.nextToken();
966
+ this.tokenizer.nextToken();
967
+ node.type = NodeType.For;
968
+ node.collection = collection;
969
+ node.item = item;
970
+ node.index = index;
971
+ node.key = key;
972
+ this.hooks.parseLoopNode?.propsAdded?.call(this, node);
973
+ const children = this.handleChildren();
974
+ node.children = children;
975
+ return node;
937
976
  }
938
- attributeList(_node) {
939
- let key, eq;
940
- const data = this.getData();
941
- while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
942
- if (key == null) {
943
- key = this.tokenizer.token.value;
944
- } else if (eq == null) {
945
- eq = '=';
946
- } else {
947
- const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
948
- _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 3),
949
- hookType = _this$tokenizer$_hook4[0],
950
- value = _this$tokenizer$_hook4[1],
951
- hookI = _this$tokenizer$_hook4[2];
952
- const rawVal = data[aoye.Keys.Raw][value];
953
- const isFn = typeof rawVal === 'function';
954
- if (hookType === 'dynamic') {
955
- const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
956
- const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
957
- this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
958
- } else if (hookType === 'static') {
959
- this.onePropParsed(data, _node, key, value, false, isFn, hookI);
960
- } else {
961
- this.onePropParsed(data, _node, key, value, false, isFn, hookI);
962
- }
963
- key = null;
964
- eq = null;
977
+ headerLineAndExtensions() {
978
+ const props = [];
979
+ props.push(...this.attributeList());
980
+ if (this.tokenizer.token.type & TokenType.NewLine) {
981
+ this.tokenizer.nextToken();
982
+ }
983
+ while (this.tokenizer.token.type & TokenType.Pipe) {
984
+ this.tokenizer.nextToken();
985
+ props.push(...this.attributeList());
986
+ if (this.tokenizer.token.type & TokenType.NewLine) {
987
+ this.tokenizer.nextToken();
965
988
  }
989
+ }
990
+ return props;
991
+ }
992
+ attributeList() {
993
+ const props = [];
994
+ while (!(this.tokenizer.token.type & TokenType.NewLine) && !(this.tokenizer.token.type & TokenType.Pipe) && !this.tokenizer.isEof()) {
995
+ props.push(this.parseProperty());
996
+ }
997
+ return props;
998
+ }
999
+ parseProperty(node) {
1000
+ node.type = NodeType.Property;
1001
+ node.key = this.parsePropertyKey();
1002
+ const token = this.tokenizer.nextToken();
1003
+ if (token.value === '=') {
1004
+ this.tokenizer.nextToken();
1005
+ node.value = this.parsePropertyValue();
966
1006
  this.tokenizer.nextToken();
967
1007
  }
1008
+ node.loc.start = node.key.loc.start;
1009
+ node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;
1010
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1011
+ return node;
1012
+ }
1013
+ parsePropertyKey(node) {
1014
+ node.type = NodeType.PropertyKey;
1015
+ node.key = this.tokenizer.token.value;
1016
+ return node;
968
1017
  }
969
- config(opt) {
970
- Object.assign(this, opt);
971
- this.opt = opt;
1018
+ parsePropertyValue(node) {
1019
+ const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1020
+ _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 2),
1021
+ hookType = _this$tokenizer$_hook4[0],
1022
+ value = _this$tokenizer$_hook4[1];
1023
+ node.type = hookType === 'dynamic' ? NodeType.DynamicValue : NodeType.StaticValue;
1024
+ node.value = value;
1025
+ return node;
972
1026
  }
973
- createNode(name) {
974
- return {
975
- name,
976
- props: {},
977
- nextSibling: null
1027
+ }
1028
+ function NodeLoc(target, context) {
1029
+ return function (_node) {
1030
+ _node.loc.start = this.tokenizer.token.loc.start;
1031
+ const result = target.call(this, _node);
1032
+ _node.loc.end = this.tokenizer.token.loc ? this.tokenizer.token.loc.start : this.tokenizer.getCurrentPos();
1033
+ _node.loc.source = this.tokenizer.code.slice(_node.loc.start.offset, _node.loc.end.offset);
1034
+ return result;
1035
+ };
1036
+ }
1037
+ function TokenLoc(target, context) {
1038
+ return function (_node) {
1039
+ const result = target.call(this, _node);
1040
+ _node.loc = this.tokenizer.token.loc;
1041
+ return result;
1042
+ };
1043
+ }
1044
+ function NodeHook(target, context) {
1045
+ return function (_node) {
1046
+ const hook = this.hooks[context.name];
1047
+ const node = {
1048
+ loc: {}
1049
+ };
1050
+ hook?.enter?.call(this, node);
1051
+ const result = target.call(this, node);
1052
+ hook?.leave?.call(this, node);
1053
+ return result;
1054
+ };
1055
+ }
1056
+
1057
+ class MultiTypeStack {
1058
+ typeTops = {};
1059
+ length = 0;
1060
+ stack = [];
1061
+ push(value, bits) {
1062
+ const newNode = {
1063
+ value,
1064
+ types: bits,
1065
+ prevByType: {}
978
1066
  };
1067
+ let bit;
1068
+ while (1) {
1069
+ bit = bits & ~bits + 1;
1070
+ if (!bit) break;
1071
+ bits &= ~bit;
1072
+ newNode.prevByType[bit] = this.typeTops[bit] || undefined;
1073
+ this.typeTops[bit] = newNode;
1074
+ }
1075
+ this.stack[this.length++] = newNode;
979
1076
  }
980
- nextSib(node) {
981
- return node.nextSibling;
1077
+ pop() {
1078
+ const poppedNode = this.stack[this.length - 1];
1079
+ this.stack[--this.length] = null;
1080
+ if (!poppedNode) return undefined;
1081
+ let bits = poppedNode.types;
1082
+ let bit;
1083
+ while (1) {
1084
+ bit = bits & ~bits + 1;
1085
+ if (!bit) break;
1086
+ bits &= ~bit;
1087
+ this.typeTops[bit] = poppedNode.prevByType[bit];
1088
+ }
1089
+ return [poppedNode.value, poppedNode.types];
982
1090
  }
983
- firstChild(node) {
984
- return node.firstChild;
1091
+ peekByType(cat) {
1092
+ return this.typeTops[cat]?.value;
985
1093
  }
986
- createAnchor(name) {
987
- return {
988
- name,
989
- nextSibling: null
990
- };
1094
+ peekType() {
1095
+ return this.stack.at(-1).types;
991
1096
  }
992
- insertAfter(parent, node, prev) {
993
- return this.defaultInsert(parent, node, prev);
1097
+ peek() {
1098
+ return this.stack.at(-1).value;
994
1099
  }
995
- defaultInsert(parent, node, prev) {
996
- if (prev) {
997
- const next = prev.nextSibling;
998
- prev.nextSibling = node;
999
- node.nextSibling = next;
1000
- } else {
1001
- const next = parent.firstChild;
1002
- parent.firstChild = node;
1003
- node.nextSibling = next;
1100
+ }
1101
+
1102
+ function macInc(arr) {
1103
+ const len = arr.length;
1104
+ let candyLast = [],
1105
+ i = 0;
1106
+ while (i < len) {
1107
+ const it = arr[i];
1108
+ if (it !== -1) {
1109
+ candyLast = [i];
1110
+ break;
1004
1111
  }
1112
+ i++;
1005
1113
  }
1006
- remove(node, parent, prev) {
1007
- return this.defaultRemove(node, parent, prev);
1008
- }
1009
- defaultRemove(node, parent, prevSibling) {
1010
- const next = node.nextSibling;
1011
- if (prevSibling) {
1012
- prevSibling.nextSibling = next;
1013
- }
1014
- if (parent.firstChild === node) {
1015
- parent.firstChild = next;
1114
+ if (i + 1 >= len) return candyLast;
1115
+ const toPrev = new Int32Array(len);
1116
+ while (i < len) {
1117
+ const target = arr[i];
1118
+ if (target === -1) continue;
1119
+ let start = -1,
1120
+ end = candyLast.length;
1121
+ while (start + 1 < end) {
1122
+ const mid = start + end >> 1;
1123
+ if (arr[candyLast[mid]] < target) {
1124
+ start = mid;
1125
+ } else {
1126
+ end = mid;
1127
+ }
1016
1128
  }
1129
+ candyLast[end] = i;
1130
+ toPrev[i] = candyLast[start];
1131
+ i++;
1017
1132
  }
1018
- setProp(node, key, value, hookI) {
1019
- node.props[key] = value;
1133
+ let length = candyLast.length;
1134
+ for (let j = length - 1; j > 0; j--) {
1135
+ const prev = toPrev[candyLast[j]];
1136
+ candyLast[j - 1] = prev;
1020
1137
  }
1138
+ return candyLast;
1021
1139
  }
1022
1140
 
1023
- class Tokenizer {
1024
- TabSize = 2;
1025
- Tab = Array.from({
1026
- length: this.TabSize
1027
- }, () => ' ').join('');
1028
- static EofId = `__EOF__${Date.now()}`;
1029
- static DedentId = `__DEDENT__${Date.now()}`;
1030
- needIndent = false;
1031
- isFirstToken = true;
1032
- dentStack = [0];
1033
- i = 0;
1034
- handledTokens = [];
1035
- waitingTokens = new bobeShared.Queue();
1036
- constructor(hook, useDedentAsEof) {
1037
- this.hook = hook;
1038
- this.useDedentAsEof = useDedentAsEof;
1039
- if (useDedentAsEof) {
1040
- this.setToken(TokenType.Indent, '');
1041
- this.isFirstToken = true;
1141
+ const KEY_INDEX = '__BOBE_KEY_INDEX';
1142
+
1143
+ const _excluded = ["dentStack", "isFirstToken"];
1144
+ class Interpreter {
1145
+ constructor(tokenizer) {
1146
+ this.tokenizer = tokenizer;
1147
+ }
1148
+ isLogicNode(node) {
1149
+ return node && node.__logicType & LogicalBit;
1150
+ }
1151
+ rootComponent = null;
1152
+ program(root, componentNode, before, ctxProvider) {
1153
+ this.rootComponent = componentNode;
1154
+ this.tokenizer.nextToken();
1155
+ const stack = new MultiTypeStack();
1156
+ stack.push({
1157
+ node: root,
1158
+ prev: null
1159
+ }, NodeSort.Real);
1160
+ stack.push({
1161
+ node: componentNode,
1162
+ prev: null
1163
+ }, NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher);
1164
+ if (ctxProvider) {
1165
+ stack.push({
1166
+ node: ctxProvider,
1167
+ prev: null
1168
+ }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
1169
+ }
1170
+ const rootLen = stack.length;
1171
+ const ctx = this.ctx = {
1172
+ realParent: root,
1173
+ prevSibling: before,
1174
+ current: null,
1175
+ stack,
1176
+ before
1177
+ };
1178
+ const rootPulling = aoye.getPulling();
1179
+ while (1) {
1180
+ if (this.tokenizer.isEof()) {
1181
+ if (!ctx.prevSibling) ctx.prevSibling = before;
1182
+ this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
1183
+ break;
1184
+ }
1185
+ const token = this.tokenizer.token;
1186
+ if (token.type & TokenType.Indent) {
1187
+ this.tokenizer.nextToken();
1188
+ const isLogicNode = this.isLogicNode(ctx.current);
1189
+ stack.push({
1190
+ node: ctx.current,
1191
+ prev: ctx.prevSibling
1192
+ }, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider);
1193
+ if (ctx.current.__logicType) {
1194
+ if (isLogicNode) {
1195
+ aoye.setPulling(ctx.current.effect);
1196
+ if (ctx.current.__logicType & FakeType.ForItem) {
1197
+ ctx.prevSibling = ctx.current.realBefore;
1198
+ }
1199
+ }
1200
+ } else {
1201
+ if (ctx.current) {
1202
+ ctx.realParent = ctx.current;
1203
+ }
1204
+ ctx.prevSibling = null;
1205
+ }
1206
+ ctx.current = this.declaration(ctx);
1207
+ continue;
1208
+ }
1209
+ if (ctx.current) {
1210
+ if (stack.length === rootLen && !ctx.prevSibling) {
1211
+ ctx.prevSibling = before;
1212
+ }
1213
+ this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
1214
+ }
1215
+ if (this.tokenizer.token.type & TokenType.Dedent) {
1216
+ this.tokenizer.nextToken();
1217
+ const _stack$pop = stack.pop(),
1218
+ _stack$pop2 = _slicedToArray(_stack$pop, 2),
1219
+ _stack$pop2$ = _stack$pop2[0],
1220
+ parent = _stack$pop2$.node,
1221
+ prev = _stack$pop2$.prev,
1222
+ sort = _stack$pop2[1];
1223
+ if (!parent.__logicType) {
1224
+ const prevSameType = stack.peekByType(NodeSort.Real);
1225
+ ctx.realParent = prevSameType?.node || root;
1226
+ } else {
1227
+ if (sort & NodeSort.Logic) {
1228
+ const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
1229
+ if (parentLogic) {
1230
+ aoye.setPulling(parentLogic.effect);
1231
+ } else {
1232
+ aoye.setPulling(rootPulling);
1233
+ }
1234
+ }
1235
+ if (sort & NodeSort.TokenizerSwitcher) {
1236
+ const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1237
+ this.tokenizer = switcher.tokenizer;
1238
+ }
1239
+ if (parent.__logicType === FakeType.ForItem) {
1240
+ const _ref = parent,
1241
+ forNode = _ref.forNode;
1242
+ const i = forNode.i,
1243
+ arr = forNode.arr,
1244
+ snapshot = forNode.snapshot;
1245
+ if (i + 1 < arr.length) {
1246
+ this.tokenizer.resume(snapshot);
1247
+ this.tokenizer.nextToken();
1248
+ this.tokenizer.nextToken();
1249
+ ctx.current = forNode.children[++forNode.i];
1250
+ ctx.prevSibling = ctx.current.realBefore;
1251
+ continue;
1252
+ }
1253
+ ctx.prevSibling = forNode.prevSibling;
1254
+ ctx.current = forNode;
1255
+ continue;
1256
+ }
1257
+ }
1258
+ ctx.prevSibling = prev;
1259
+ ctx.current = parent;
1260
+ } else {
1261
+ ctx.prevSibling = ctx.current || ctx.prevSibling;
1262
+ ctx.current = this.declaration(ctx);
1263
+ }
1042
1264
  }
1265
+ return componentNode;
1043
1266
  }
1044
- consume() {
1045
- const token = this.token;
1046
- this.nextToken();
1047
- return token;
1048
- }
1049
- resume(_snapshot) {
1050
- this.token = undefined;
1051
- this.needIndent = false;
1052
- this.isFirstToken = true;
1053
- this.dentStack = [0];
1054
- Object.assign(this, _snapshot);
1267
+ insertAfterAnchor(name = 'anchor') {
1268
+ const _this$ctx = this.ctx,
1269
+ realParent = _this$ctx.realParent,
1270
+ prevSibling = _this$ctx.prevSibling,
1271
+ stack = _this$ctx.stack,
1272
+ before = _this$ctx.before;
1273
+ const afterAnchor = this.createAnchor(name);
1274
+ this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1275
+ this.handleInsert(realParent, afterAnchor, prevSibling);
1276
+ return afterAnchor;
1055
1277
  }
1056
- snapshot(keys) {
1057
- const snap = {
1058
- i: this.i,
1059
- waitingTokens: this.waitingTokens.clone()
1060
- };
1061
- if (keys) {
1062
- for (const k of keys) {
1063
- snap[k] = this[k];
1064
- if (k === 'dentStack') {
1065
- snap[k] = this[k].slice();
1066
- }
1278
+ handleInsert(parent, child, prev, parentComponent) {
1279
+ if (!child.__logicType) {
1280
+ if (!prev || !prev.__logicType) {
1281
+ this.insertAfter(parent, child, prev);
1282
+ } else {
1283
+ const before = prev.realAfter;
1284
+ this.insertAfter(parent, child, before);
1285
+ }
1286
+ } else {
1287
+ const childCmp = child;
1288
+ childCmp.realParent = parent;
1289
+ if (prev?.__logicType) {
1290
+ childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
1291
+ } else {
1292
+ childCmp.realBefore = prev;
1067
1293
  }
1068
1294
  }
1069
- return snap;
1070
1295
  }
1071
- skip() {
1072
- const logicDentLen = this.dentStack[this.dentStack.length - 1];
1073
- let needIndent = false;
1074
- let skipFragment = ``;
1075
- this.token = undefined;
1076
- while (1) {
1077
- const char = this.code[this.i];
1078
- if (char === '\n') {
1079
- needIndent = true;
1080
- skipFragment += char;
1081
- this.i++;
1082
- continue;
1083
- }
1084
- if (!needIndent) {
1085
- skipFragment += char;
1086
- this.i++;
1087
- continue;
1296
+ getPrevRealSibling(prevSibling) {
1297
+ if (!prevSibling || !prevSibling.__logicType) {
1298
+ return prevSibling;
1299
+ }
1300
+ let point = prevSibling;
1301
+ while (point != null) {
1302
+ if (point.lastChild) {
1303
+ return point.lastChild.value;
1088
1304
  }
1089
- needIndent = false;
1090
- const _this$getDentValue = this.getDentValue(),
1091
- value = _this$getDentValue.value,
1092
- isEmptyLine = _this$getDentValue.isEmptyLine;
1093
- const currLen = value.length;
1094
- if (isEmptyLine) continue;
1095
- if (currLen > logicDentLen) {
1096
- skipFragment += value;
1305
+ point = point.anchor;
1306
+ }
1307
+ }
1308
+ declaration(ctx) {
1309
+ const _this$tokenizer$_hook = this.tokenizer._hook({}),
1310
+ _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
1311
+ hookType = _this$tokenizer$_hook2[0],
1312
+ value = _this$tokenizer$_hook2[1];
1313
+ let _node;
1314
+ if (value === 'if' || value === 'else' || value === 'fail') {
1315
+ return this.condDeclaration(ctx);
1316
+ } else if (value === 'for') {
1317
+ return this.forDeclaration();
1318
+ } else if (hookType) {
1319
+ const data = this.getData();
1320
+ if (hookType === 'static') {
1321
+ if (typeof value === 'function') {
1322
+ _node = this.componentOrFragmentDeclaration(value, ctx);
1323
+ } else {
1324
+ throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
1325
+ }
1097
1326
  } else {
1098
- for (let i = this.dentStack.length - 1; i >= 0; i--) {
1099
- const expLen = this.dentStack[i];
1100
- if (currLen === expLen) break;
1101
- if (currLen > expLen) {
1102
- throw SyntaxError(`缩进错误,缩进长度不匹配`);
1103
- }
1104
- if (this.shorterThanBaseDentEof()) {
1105
- break;
1106
- }
1107
- this.dentStack.pop();
1108
- if (!this.token) {
1109
- this.setToken(TokenType.Dedent, String(expLen));
1110
- } else {
1111
- this.waitingTokens.push({
1112
- type: TokenType.Dedent,
1113
- typeName: TokenType[TokenType.Dedent],
1114
- value: String(expLen)
1115
- });
1116
- }
1327
+ const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1328
+ const val = data[aoye.Keys.Raw][value];
1329
+ if (typeof val === 'function') {
1330
+ _node = this.componentOrFragmentDeclaration(val, ctx);
1331
+ } else {
1332
+ const str = valueIsMapKey ? value : this.getFn(data, value);
1333
+ _node = this.createNode('text');
1334
+ this.onePropParsed(data, _node, 'text', str, valueIsMapKey, false);
1117
1335
  }
1118
- break;
1119
1336
  }
1337
+ } else {
1338
+ _node = this.createNode(value);
1120
1339
  }
1121
- if (!this.token) {
1122
- this.nextToken();
1340
+ this.tokenizer.nextToken();
1341
+ this.headerLine(_node);
1342
+ this.extensionLines(_node);
1343
+ if (_node.__logicType & TokenizerSwitcherBit) {
1344
+ this.onePropParsed = this.oneRealPropParsed;
1345
+ this.tokenizer = _node.tokenizer;
1123
1346
  }
1124
- return skipFragment;
1125
- }
1126
- setCode(code) {
1127
- this.code = '\n' + code.trimEnd() + `\n${Tokenizer.EofId}`;
1128
- }
1129
- tokenize() {
1130
- do {
1131
- this.nextToken();
1132
- console.log('token:', TokenType[this.token?.type], JSON.stringify(this.token?.value || ''));
1133
- } while (!this.isEof());
1134
- }
1135
- isEof() {
1136
- if (!this.token) return false;
1137
- return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
1138
- }
1139
- setToken(type, value) {
1140
- this.token = {
1141
- type,
1142
- typeName: TokenType[type],
1143
- value
1144
- };
1145
- this.isFirstToken = false;
1347
+ return _node;
1146
1348
  }
1147
- nextToken() {
1148
- try {
1149
- if (this.isEof()) {
1150
- return this.token;
1151
- }
1152
- this.token = undefined;
1153
- if (this.waitingTokens.len) {
1154
- const item = this.waitingTokens.shift();
1155
- this.setToken(item.type, item.value);
1156
- return this.token;
1349
+ forDeclaration() {
1350
+ const arrExp = this.tokenizer.nextToken().value;
1351
+ this.tokenizer.nextToken();
1352
+ const itemToken = this.tokenizer.nextToken();
1353
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
1354
+ let itemExp = itemToken.value,
1355
+ vars;
1356
+ if (isDestruct) {
1357
+ itemExp = '{' + itemExp + '}';
1358
+ vars = itemExp.match(bobeShared.jsVarRegexp);
1359
+ const varStr = vars.join(',');
1360
+ itemExp = new Function(itemExp, `return {${varStr}};`);
1361
+ }
1362
+ let indexName,
1363
+ keyExp,
1364
+ char = this.tokenizer.peekChar();
1365
+ if (char === ';') {
1366
+ this.tokenizer.nextToken();
1367
+ if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
1368
+ } else if (char === '\n') ; else {
1369
+ indexName = this.tokenizer.nextToken().value;
1370
+ if (this.tokenizer.peekChar() === ';') {
1371
+ this.tokenizer.nextToken();
1372
+ if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
1157
1373
  }
1158
- outer: while (1) {
1159
- if (this.needIndent) {
1160
- this.dent();
1374
+ }
1375
+ const owner = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1376
+ const prevSibling = this.ctx.prevSibling;
1377
+ const forNode = {
1378
+ __logicType: FakeType.For,
1379
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1380
+ realParent: this.ctx.realParent,
1381
+ prevSibling,
1382
+ realBefore: prevSibling?.realAfter || prevSibling,
1383
+ realAfter: null,
1384
+ arr: null,
1385
+ arrSignal: null,
1386
+ itemExp,
1387
+ indexName,
1388
+ getKey: null,
1389
+ children: [],
1390
+ effect: null,
1391
+ owner,
1392
+ vars,
1393
+ i: 0
1394
+ };
1395
+ if (keyExp) {
1396
+ forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}};return v;`);
1397
+ }
1398
+ window['for1'] = forNode;
1399
+ const data = this.getData();
1400
+ const cells = data[aoye.Keys.Meta].cells;
1401
+ const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
1402
+ const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new aoye.Computed(this.getFn(data, arrExp));
1403
+ forNode.arrSignal = arrSignal;
1404
+ forNode.realAfter = this.insertAfterAnchor('for-after');
1405
+ const _forNode$snapshot = forNode.snapshot;
1406
+ _forNode$snapshot.dentStack;
1407
+ _forNode$snapshot.isFirstToken;
1408
+ const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
1409
+ let isFirstRender = true;
1410
+ forNode.effect = new aoye.Effect(() => {
1411
+ let arr = arrSignal.get();
1412
+ arr[aoye.Keys.Iterator];
1413
+ const prevCtx = aoye.getPulling();
1414
+ aoye.setPulling(null);
1415
+ forNode.arr = arr = aoye.toRaw(arr);
1416
+ const children = forNode.children;
1417
+ if (isFirstRender) {
1418
+ const len = arr.length;
1419
+ for (let i = len; i--;) {
1420
+ const item = this.createForItem(forNode, i, data);
1421
+ item.realAfter = this.insertAfterAnchor('for-item-after');
1422
+ item.realBefore = this.insertAfterAnchor('for-item-before');
1423
+ item.realParent = forNode.realParent;
1424
+ children[i] = item;
1425
+ }
1426
+ const firstInsert = children[0];
1427
+ if (firstInsert) {
1428
+ this.tokenizer.nextToken();
1429
+ this.tokenizer.nextToken();
1161
1430
  } else {
1162
- const char = this.code[this.i];
1163
- switch (char) {
1164
- case '\t':
1165
- case ' ':
1166
- break;
1167
- case '\n':
1168
- this.newLine();
1169
- this.needIndent = true;
1170
- break;
1171
- case '=':
1172
- this.assignment();
1173
- break;
1174
- case '|':
1175
- this.pipe();
1176
- break;
1177
- case "'":
1178
- case '"':
1179
- this.str(char);
1180
- break;
1181
- case '{':
1182
- const braceToken = this.brace();
1183
- this.setToken(TokenType.InsertionExp, braceToken);
1431
+ this.tokenizer.skip();
1432
+ }
1433
+ } else {
1434
+ const oldLen = children.length;
1435
+ const newLen = arr.length;
1436
+ const minLen = Math.min(oldLen, newLen);
1437
+ const newChildren = [];
1438
+ if (!forNode.getKey) {
1439
+ if (newLen < oldLen) {
1440
+ for (let i = oldLen - 1; i >= newLen; i--) {
1441
+ this.removeForItem(children, i);
1442
+ }
1443
+ }
1444
+ if (oldLen < newLen) {
1445
+ const lastAfter = children.at(-1)?.realAfter || forNode.realBefore;
1446
+ for (let i = newLen - 1; i >= oldLen; i--) {
1447
+ this.insertForItem(forNode, i, data, newChildren, lastAfter, snapshotForUpdate);
1448
+ }
1449
+ }
1450
+ for (let i = minLen; i--;) {
1451
+ const child = children[i];
1452
+ newChildren[i] = child;
1453
+ this.reuseForItem(child, arr[i], itemExp, i, indexName);
1454
+ }
1455
+ } else {
1456
+ let s = 0,
1457
+ e1 = oldLen - 1,
1458
+ e2 = newLen - 1;
1459
+ while (s <= e1 && s <= e2) {
1460
+ const child = children[s];
1461
+ const old = child.key;
1462
+ const itemData = this.getItemData(forNode, s, data);
1463
+ const key = forNode.getKey(itemData);
1464
+ if (old === key) {
1465
+ newChildren[s] = child;
1466
+ this.reuseForItem(child, arr[s], itemExp, s, indexName);
1467
+ s++;
1468
+ } else {
1184
1469
  break;
1185
- case '$':
1186
- const handled = this.dynamic(char);
1187
- if (handled) break;
1188
- case ';':
1189
- this.setToken(TokenType.Semicolon, ';');
1470
+ }
1471
+ }
1472
+ while (s <= e1 && s <= e2) {
1473
+ const child = children[e1];
1474
+ const old = child.key;
1475
+ const itemData = this.getItemData(forNode, e2, data);
1476
+ const key = forNode.getKey(itemData);
1477
+ if (old === key) {
1478
+ newChildren[e2] = child;
1479
+ this.reuseForItem(child, arr[e2], itemExp, e2, indexName);
1480
+ e1--;
1481
+ e2--;
1482
+ } else {
1190
1483
  break;
1191
- default:
1192
- if (bobeShared.isNum(char)) {
1193
- this.number(char);
1194
- break;
1484
+ }
1485
+ }
1486
+ if (s > e1) {
1487
+ if (s <= e2) {
1488
+ const firstBefore = s > 0 ? children[s - 1]?.realAfter || forNode.realBefore : forNode.realBefore;
1489
+ for (let i = e2; i >= s; i--) {
1490
+ this.insertForItem(forNode, i, data, newChildren, firstBefore, snapshotForUpdate);
1195
1491
  }
1196
- if (typeof char === 'string' && bobeShared.matchIdStart2(char, 0)) {
1197
- this.identifier(char);
1492
+ }
1493
+ } else if (s > e2) {
1494
+ if (s <= e1) {
1495
+ for (let i = e1; i >= s; i--) {
1496
+ this.removeForItem(children, i);
1198
1497
  }
1199
- break;
1498
+ }
1499
+ } else {
1500
+ let s1 = s,
1501
+ s2 = s;
1502
+ const mixLen = e2 - s2 + 1;
1503
+ const key2new = new Map();
1504
+ for (let i = s2; i <= e2; i++) {
1505
+ const itemData = this.getItemData(forNode, i, data);
1506
+ const key = forNode.getKey(itemData);
1507
+ key2new.set(key, i);
1508
+ }
1509
+ let maxIncNewI = -1;
1510
+ let hasMove = false;
1511
+ const new2oldI = new Array(mixLen).fill(-1);
1512
+ for (let i = s1; i <= e1; i++) {
1513
+ const key = children[i].key;
1514
+ const newI = key2new.get(key);
1515
+ if (newI == null) {
1516
+ this.removeForItem(children, i);
1517
+ continue;
1518
+ }
1519
+ const child = children[i];
1520
+ newChildren[newI] = child;
1521
+ this.reuseForItem(child, arr[newI], itemExp, newI, indexName);
1522
+ new2oldI[newI - s2] = i;
1523
+ key2new.delete(key);
1524
+ if (newI < maxIncNewI) {
1525
+ hasMove = true;
1526
+ } else {
1527
+ maxIncNewI = newI;
1528
+ }
1529
+ }
1530
+ if (!hasMove) {
1531
+ key2new.forEach((i, key) => {
1532
+ const before = i === 0 ? forNode.realBefore : newChildren[i - 1].realAfter;
1533
+ this.insertForItem(forNode, i, data, newChildren, before, snapshotForUpdate);
1534
+ });
1535
+ } else {
1536
+ const incI = macInc(new2oldI),
1537
+ incLen = incI.length;
1538
+ let p1, p2;
1539
+ for (p1 = s2, p2 = 0; p1 <= e2; p1++) {
1540
+ const oldI = new2oldI[p1];
1541
+ if (oldI === -1) {
1542
+ const before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
1543
+ this.insertForItem(forNode, p1, data, newChildren, before, snapshotForUpdate);
1544
+ continue;
1545
+ }
1546
+ const staticIdx = incI[p2] + s2;
1547
+ if (p1 === staticIdx) {
1548
+ p2 <= incLen && p2++;
1549
+ continue;
1550
+ }
1551
+ let before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
1552
+ const child = newChildren[p1];
1553
+ const realBefore = child.realBefore,
1554
+ realAfter = child.realAfter,
1555
+ realParent = child.realParent;
1556
+ let point = realBefore,
1557
+ next;
1558
+ do {
1559
+ next = this.nextSib(point);
1560
+ this.insertAfter(realParent, point, before);
1561
+ before = point;
1562
+ if (point === realAfter) break;
1563
+ point = next;
1564
+ } while (true);
1565
+ }
1566
+ }
1200
1567
  }
1201
- this.i++;
1202
1568
  }
1203
- if (this.token) {
1204
- break;
1569
+ forNode.children = newChildren;
1570
+ }
1571
+ isFirstRender = false;
1572
+ aoye.setPulling(prevCtx);
1573
+ return isDestroy => {
1574
+ if (isDestroy) {
1575
+ for (let i = 0; i < forNode.children.length; i++) {
1576
+ const item = forNode.children[i];
1577
+ item.effect.dispose();
1578
+ }
1205
1579
  }
1580
+ };
1581
+ });
1582
+ return forNode.children[0] || forNode;
1583
+ }
1584
+ insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
1585
+ const item = this.createForItem(forNode, i, parentData);
1586
+ newChildren[i] = item;
1587
+ let realAfter = this.createAnchor('for-item-after');
1588
+ this.handleInsert(forNode.realParent, realAfter, before);
1589
+ let realBefore = this.createAnchor('for-item-before');
1590
+ this.handleInsert(forNode.realParent, realBefore, before);
1591
+ item.realBefore = realBefore;
1592
+ item.realAfter = realAfter;
1593
+ this.tokenizer = forNode.owner.tokenizer;
1594
+ this.tokenizer.resume(snapshotForUpdate);
1595
+ this.tokenizer.useDedentAsEof = false;
1596
+ aoye.runWithPulling(() => {
1597
+ this.program(forNode.realParent, forNode.owner, realBefore, item);
1598
+ }, item.effect);
1599
+ }
1600
+ removeForItem(children, i) {
1601
+ const child = children[i];
1602
+ this.removeLogicNode(child);
1603
+ this.remove(child.realBefore);
1604
+ this.remove(child.realAfter);
1605
+ child.effect.dispose();
1606
+ }
1607
+ reuseForItem(child, data, itemExp, i, indexName) {
1608
+ if (typeof itemExp === 'string') {
1609
+ child.data[itemExp] = data;
1610
+ if (indexName) {
1611
+ child.data[indexName] = i;
1206
1612
  }
1207
- return this.token;
1208
- } catch (error) {
1209
- console.error(error);
1210
- return this.token;
1211
- } finally {
1212
- this.handledTokens.push(this.token);
1613
+ } else {
1614
+ indexName = indexName || KEY_INDEX;
1615
+ child.data[indexName] = i;
1213
1616
  }
1214
1617
  }
1215
- condExp() {
1216
- let value = '';
1217
- this.token = null;
1218
- while (1) {
1219
- const char = this.code[this.i];
1220
- if (char === '\n') {
1221
- break;
1618
+ forItemId = 0;
1619
+ createForItem(forNode, i, parentData) {
1620
+ let forItemNode;
1621
+ let data;
1622
+ const scope = new aoye.Scope(() => {});
1623
+ scope.scope = null;
1624
+ aoye.runWithPulling(() => {
1625
+ scope.get();
1626
+ }, null);
1627
+ data = this.getItemData(forNode, i, parentData);
1628
+ forItemNode = {
1629
+ id: this.forItemId++,
1630
+ __logicType: FakeType.ForItem,
1631
+ realParent: null,
1632
+ realBefore: null,
1633
+ realAfter: null,
1634
+ forNode,
1635
+ key: forNode.getKey?.(data),
1636
+ effect: null,
1637
+ data
1638
+ };
1639
+ forItemNode.effect = scope;
1640
+ return forItemNode;
1641
+ }
1642
+ getItemData(forNode, i, parentData) {
1643
+ const arr = forNode.arr,
1644
+ itemExp = forNode.itemExp,
1645
+ vars = forNode.vars,
1646
+ arrSignal = forNode.arrSignal,
1647
+ getKey = forNode.getKey;
1648
+ let indexName = forNode.indexName;
1649
+ let data;
1650
+ if (typeof itemExp === 'string') {
1651
+ data = aoye.deepSignal(indexName ? {
1652
+ [itemExp]: arr[i],
1653
+ [indexName]: i
1654
+ } : {
1655
+ [itemExp]: arr[i]
1656
+ }, aoye.getPulling());
1657
+ } else {
1658
+ indexName = indexName ?? KEY_INDEX;
1659
+ const rawData = {
1660
+ [indexName]: i
1661
+ };
1662
+ data = aoye.deepSignal(rawData, aoye.getPulling());
1663
+ const computedData = new aoye.Computed(() => itemExp(arrSignal.get()[getKey ? data[indexName] : i]));
1664
+ const cells = data[aoye.Keys.Meta].cells;
1665
+ for (let i = 0; i < vars.length; i++) {
1666
+ const name = vars[i];
1667
+ rawData[name] = undefined;
1668
+ cells.set(name, new aoye.Computed(() => computedData.get()[name]));
1222
1669
  }
1223
- value += char;
1224
- this.i++;
1225
1670
  }
1226
- value = value.trim();
1227
- this.setToken(TokenType.Identifier, value || true);
1228
- return this.token;
1671
+ Object.setPrototypeOf(data, parentData);
1672
+ return data;
1229
1673
  }
1230
- jsExp() {
1231
- this.token = null;
1232
- let value = '';
1233
- while (1) {
1234
- const char = this.code[this.i];
1235
- if (char === ';' || char === '\n') {
1236
- this.setToken(TokenType.Identifier, value.trim());
1237
- return this.token;
1238
- } else {
1239
- value += char;
1240
- }
1241
- this.i++;
1242
- }
1674
+ getData() {
1675
+ const _this$ctx$stack$peekB = this.ctx.stack.peekByType(NodeSort.CtxProvider),
1676
+ node = _this$ctx$stack$peekB.node;
1677
+ return node.data;
1243
1678
  }
1244
- peekChar() {
1245
- let i = this.i;
1246
- while (this.code[i] === ' ' || this.code[i] === '\t') {
1247
- i++;
1679
+ onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
1680
+ if (isFn) {
1681
+ this.setProp(node, key, value, hookI);
1682
+ } else if (typeof value === 'function') {
1683
+ new aoye.Effect(() => {
1684
+ const res = value();
1685
+ this.setProp(node, key, res, hookI);
1686
+ });
1687
+ } else if (valueIsMapKey) {
1688
+ new aoye.Effect(() => {
1689
+ const res = data[value];
1690
+ this.setProp(node, key, res, hookI);
1691
+ });
1692
+ } else {
1693
+ this.setProp(node, key, value, hookI);
1248
1694
  }
1249
- return this.code[i];
1250
- }
1251
- assignment() {
1252
- this.setToken(TokenType.Assign, '=');
1253
- }
1254
- pipe() {
1255
- this.setToken(TokenType.Pipe, '|');
1256
1695
  }
1257
- dynamic(char) {
1258
- let nextC = this.code[this.i + 1];
1259
- if (nextC !== '{') {
1260
- return false;
1261
- }
1262
- this.i++;
1263
- let value = '${';
1264
- let innerBrace = 0;
1265
- while (1) {
1266
- nextC = this.code[this.i + 1];
1267
- value += nextC;
1268
- this.i++;
1269
- if (nextC === '{') {
1270
- innerBrace++;
1271
- }
1272
- if (nextC === '}') {
1273
- if (!innerBrace) {
1274
- break;
1275
- }
1276
- innerBrace--;
1277
- }
1696
+ oneRealPropParsed = this.onePropParsed.bind(this);
1697
+ componentOrFragmentDeclaration(ComponentOrRender, ctx) {
1698
+ let Component, render, child;
1699
+ const isCC = ComponentOrRender.prototype instanceof aoye.Store;
1700
+ if (isCC) {
1701
+ Component = ComponentOrRender;
1702
+ child = Component.new();
1703
+ } else {
1704
+ render = ComponentOrRender;
1705
+ const boundStore = render.boundStore;
1706
+ child = aoye.deepSignal({}, aoye.getPulling(), true);
1707
+ Object.setPrototypeOf(child, boundStore);
1278
1708
  }
1279
- this.setToken(TokenType.Identifier, value);
1280
- return true;
1281
- }
1282
- brace() {
1283
- let inComment,
1284
- inString,
1285
- count = 0,
1286
- value = '',
1287
- backslashCount = 0;
1288
- while (1) {
1289
- const char = this.code[this.i];
1290
- const nextChar = this.code[this.i + 1];
1291
- if (inComment === 'single' && char === '\n') {
1292
- inComment = null;
1293
- } else if (inComment === 'multi' && char === '*' && nextChar === '/') {
1294
- inComment = null;
1295
- value += this.code[this.i];
1296
- this.i++;
1297
- } else if (inString) {
1298
- if (char === inString && backslashCount % 2 === 0) {
1299
- inString = null;
1300
- }
1301
- backslashCount = char === '\\' ? backslashCount + 1 : 0;
1709
+ const node = {
1710
+ __logicType: isCC ? FakeType.Component : FakeType.Fragment,
1711
+ realParent: ctx.realParent,
1712
+ realBefore: null,
1713
+ realAfter: null,
1714
+ data: child,
1715
+ tokenizer: render ? render(true) : child['ui'](true)
1716
+ };
1717
+ this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
1718
+ if (isFn) {
1719
+ child[aoye.Keys.Raw][key] = value;
1720
+ } else if (valueIsMapKey) {
1721
+ aoye.shareSignal(data, value, child, key);
1302
1722
  } else {
1303
- if (char === '/' && nextChar === '/') {
1304
- inComment = 'single';
1305
- value += this.code[this.i];
1306
- this.i++;
1307
- } else if (char === '/' && nextChar === '*') {
1308
- inComment = 'multi';
1309
- value += this.code[this.i];
1310
- this.i++;
1311
- } else if (char === "'" || char === '"' || char === '`') {
1312
- inString = char;
1313
- } else if (char === '{') {
1314
- count++;
1315
- } else if (char === '}') {
1316
- count--;
1723
+ const meta = child[aoye.Keys.Meta];
1724
+ const cells = meta.cells;
1725
+ if (typeof value === 'function') {
1726
+ const computed = new aoye.Computed(value);
1727
+ cells.set(key, computed);
1728
+ child[aoye.Keys.Raw][key] = undefined;
1729
+ } else {
1730
+ cells.set(key, {
1731
+ get: () => value
1732
+ });
1733
+ child[aoye.Keys.Raw][key] = value;
1317
1734
  }
1318
1735
  }
1319
- if (count === 0 && inString == null && inComment == null) {
1320
- return value.slice(1);
1321
- }
1322
- value += this.code[this.i];
1323
- this.i++;
1324
- }
1736
+ };
1737
+ node.realAfter = this.insertAfterAnchor('component-after');
1738
+ return node;
1325
1739
  }
1326
- newLine() {
1327
- let value = '\n';
1328
- let nextC;
1329
- while (1) {
1330
- nextC = this.code[this.i + 1];
1331
- if (nextC !== '\n') {
1332
- break;
1333
- }
1334
- value += nextC;
1335
- this.i++;
1336
- }
1337
- if (this.isFirstToken) {
1338
- return;
1339
- }
1340
- this.setToken(TokenType.NewLine, value);
1740
+ getFn(data, expression) {
1741
+ return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
1341
1742
  }
1342
- getDentValue() {
1343
- let value = '';
1344
- let nextC;
1345
- let isEmptyLine = false;
1346
- while (1) {
1347
- const nextChar = this.code[this.i];
1348
- switch (nextChar) {
1349
- case '\t':
1350
- nextC = this.Tab;
1351
- break;
1352
- case ' ':
1353
- nextC = ' ';
1354
- break;
1355
- case '\n':
1356
- nextC = '\n';
1357
- break;
1358
- default:
1359
- nextC = '';
1360
- break;
1361
- }
1362
- if (nextC === '\n') {
1363
- isEmptyLine = true;
1364
- break;
1365
- }
1366
- if (!nextC) {
1367
- break;
1368
- }
1369
- value += nextC;
1370
- this.i++;
1371
- }
1372
- return {
1373
- value,
1374
- isEmptyLine
1743
+ condDeclaration(ctx) {
1744
+ const prevSibling = ctx.prevSibling;
1745
+ const keyWord = this.tokenizer.token;
1746
+ const expToken = this.tokenizer.condExp();
1747
+ const value = expToken.value;
1748
+ const isElse = keyWord.value === 'else';
1749
+ const isIf = keyWord.value === 'if';
1750
+ const preIsCond = prevSibling?.__logicType & CondBit;
1751
+ const data = this.getData();
1752
+ const noCond = value === true;
1753
+ const valueIsMapKey = !noCond && Reflect.has(data[aoye.Keys.Raw], value);
1754
+ const owner = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1755
+ const ifNode = {
1756
+ __logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
1757
+ snapshot: this.tokenizer.snapshot(),
1758
+ realParent: null,
1759
+ realBefore: null,
1760
+ realAfter: null,
1761
+ condition: null,
1762
+ preCond: preIsCond ? prevSibling : null,
1763
+ isFirstRender: true,
1764
+ effect: null,
1765
+ owner,
1766
+ data
1375
1767
  };
1376
- }
1377
- dent() {
1378
- const _this$getDentValue2 = this.getDentValue(),
1379
- value = _this$getDentValue2.value,
1380
- isEmptyLine = _this$getDentValue2.isEmptyLine;
1381
- if (isEmptyLine) {
1382
- this.needIndent = true;
1383
- return;
1384
- }
1385
- this.needIndent = false;
1386
- if (this.isFirstToken) {
1387
- this.dentStack[0] = value.length;
1388
- return;
1389
- }
1390
- let currLen = value.length;
1391
- const indentHasLen = currLen > 0;
1392
- const prevLen = this.dentStack[this.dentStack.length - 1];
1393
- if (currLen > prevLen) {
1394
- this.dentStack.push(currLen);
1395
- this.setToken(TokenType.Indent, currLen);
1396
- return indentHasLen;
1397
- }
1398
- if (currLen < prevLen) {
1399
- for (let i = this.dentStack.length; i--;) {
1400
- const expLen = this.dentStack[i];
1401
- if (currLen === expLen) break;
1402
- if (currLen > expLen) {
1403
- throw SyntaxError('缩进大小不统一');
1404
- }
1405
- if (this.shorterThanBaseDentEof()) {
1406
- return;
1768
+ let signal;
1769
+ switch (keyWord.value) {
1770
+ case 'if':
1771
+ if (valueIsMapKey) {
1772
+ aoye.runWithPulling(() => data[value], null);
1773
+ const cells = data[aoye.Keys.Meta].cells;
1774
+ signal = cells.get(value);
1775
+ } else {
1776
+ const fn = this.getFn(data, value);
1777
+ signal = new aoye.Computed(fn);
1407
1778
  }
1408
- this.dentStack.pop();
1409
- if (!this.token) {
1410
- this.setToken(TokenType.Dedent, String(expLen));
1779
+ break;
1780
+ case 'else':
1781
+ if (noCond) {
1782
+ signal = new aoye.Computed(() => {
1783
+ let point = ifNode.preCond;
1784
+ while (point) {
1785
+ if (point.condition.get()) {
1786
+ return false;
1787
+ }
1788
+ if (point.__logicType === FakeType.If) {
1789
+ break;
1790
+ }
1791
+ point = point.preCond;
1792
+ }
1793
+ return true;
1794
+ });
1411
1795
  } else {
1412
- this.waitingTokens.push({
1413
- type: TokenType.Dedent,
1414
- typeName: TokenType[TokenType.Dedent],
1415
- value: String(expLen)
1796
+ const fn = valueIsMapKey ? null : this.getFn(data, value);
1797
+ signal = new aoye.Computed(() => {
1798
+ let point = ifNode.preCond;
1799
+ while (point) {
1800
+ if (point.condition.get()) {
1801
+ return false;
1802
+ }
1803
+ if (point.__logicType === FakeType.If) {
1804
+ break;
1805
+ }
1806
+ point = point.preCond;
1807
+ }
1808
+ return valueIsMapKey ? data[value] : fn();
1416
1809
  });
1417
1810
  }
1418
- }
1419
- return indentHasLen;
1811
+ break;
1812
+ case 'fail':
1813
+ signal = new aoye.Computed(() => {
1814
+ let point = ifNode.preCond;
1815
+ while (point) {
1816
+ if (point.condition.get()) {
1817
+ return false;
1818
+ }
1819
+ point = point.preCond;
1820
+ }
1821
+ return true;
1822
+ });
1823
+ break;
1420
1824
  }
1421
- return indentHasLen;
1422
- }
1423
- shorterThanBaseDentEof() {
1424
- const yes = this.dentStack.length === 1;
1425
- if (yes) {
1426
- if (!this.token) {
1427
- if (this.useDedentAsEof) {
1428
- this.setToken(TokenType.Dedent, '');
1825
+ ifNode.condition = signal;
1826
+ ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
1827
+ const ef = aoye.effect(({
1828
+ val
1829
+ }) => {
1830
+ if (val) {
1831
+ if (ifNode.isFirstRender) {
1832
+ this.tokenizer.nextToken();
1833
+ this.tokenizer.nextToken();
1429
1834
  } else {
1430
- this.setToken(TokenType.Identifier, Tokenizer.EofId);
1835
+ this.tokenizer = ifNode.owner.tokenizer;
1836
+ this.tokenizer.resume(ifNode.snapshot);
1837
+ this.tokenizer.useDedentAsEof = false;
1838
+ this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
1431
1839
  }
1432
1840
  } else {
1433
- if (this.useDedentAsEof) {
1434
- this.waitingTokens.push({
1435
- type: TokenType.Dedent,
1436
- typeName: TokenType[TokenType.Dedent],
1437
- value: ''
1438
- });
1841
+ if (ifNode.isFirstRender) {
1842
+ this.tokenizer.skip();
1439
1843
  } else {
1440
- this.waitingTokens.push({
1441
- type: TokenType.Identifier,
1442
- typeName: TokenType[TokenType.Identifier],
1443
- value: Tokenizer.EofId
1444
- });
1844
+ this.removeLogicNode(ifNode);
1445
1845
  }
1446
1846
  }
1847
+ ifNode.isFirstRender = false;
1848
+ }, [signal]);
1849
+ ifNode.effect = ef;
1850
+ return ifNode;
1851
+ }
1852
+ removeLogicNode(node) {
1853
+ const realBefore = node.realBefore,
1854
+ realAfter = node.realAfter,
1855
+ realParent = node.realParent;
1856
+ let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
1857
+ while (point !== realAfter) {
1858
+ const next = this.nextSib(point);
1859
+ this.remove(point, realParent, realBefore);
1860
+ point = next;
1447
1861
  }
1448
- return yes;
1449
1862
  }
1450
- identifier(char) {
1451
- let value = char;
1452
- let nextC;
1863
+ extensionLines(_node) {
1453
1864
  while (1) {
1454
- nextC = this.code[this.i + 1];
1455
- if (typeof nextC !== 'string' || !bobeShared.matchIdStart2(nextC, 0)) {
1456
- break;
1865
+ if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
1866
+ return;
1457
1867
  }
1458
- value += nextC;
1459
- this.i++;
1460
- }
1461
- if (value === Tokenizer.EofId && this.useDedentAsEof) {
1462
- this.setToken(TokenType.Dedent, '');
1463
- return;
1868
+ this.tokenizer.nextToken();
1869
+ this.attributeList(_node);
1870
+ if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
1871
+ return;
1872
+ }
1873
+ this.tokenizer.nextToken();
1464
1874
  }
1465
- let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
1466
- this.setToken(TokenType.Identifier, realValue);
1467
1875
  }
1468
- str(char) {
1469
- let value = '';
1470
- let nextC;
1471
- let continuousBackslashCount = 0;
1472
- while (1) {
1473
- nextC = this.code[this.i + 1];
1474
- const memoCount = continuousBackslashCount;
1475
- if (nextC === '\\') {
1476
- continuousBackslashCount++;
1876
+ headerLine(_node) {
1877
+ this.attributeList(_node);
1878
+ this.tokenizer.nextToken();
1879
+ }
1880
+ attributeList(_node) {
1881
+ let key, eq;
1882
+ const data = this.getData();
1883
+ while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
1884
+ if (key == null) {
1885
+ key = this.tokenizer.token.value;
1886
+ } else if (eq == null) {
1887
+ eq = '=';
1477
1888
  } else {
1478
- continuousBackslashCount = 0;
1479
- }
1480
- this.i++;
1481
- if (nextC === char && memoCount % 2 === 0) {
1482
- break;
1889
+ const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1890
+ _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 3),
1891
+ hookType = _this$tokenizer$_hook4[0],
1892
+ value = _this$tokenizer$_hook4[1],
1893
+ hookI = _this$tokenizer$_hook4[2];
1894
+ const rawVal = data[aoye.Keys.Raw][value];
1895
+ const isFn = typeof rawVal === 'function';
1896
+ if (hookType === 'dynamic') {
1897
+ const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1898
+ const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
1899
+ this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
1900
+ } else if (hookType === 'static') {
1901
+ this.onePropParsed(data, _node, key, value, false, isFn, hookI);
1902
+ } else {
1903
+ this.onePropParsed(data, _node, key, value, false, isFn, hookI);
1904
+ }
1905
+ key = null;
1906
+ eq = null;
1483
1907
  }
1484
- value += nextC;
1908
+ this.tokenizer.nextToken();
1485
1909
  }
1486
- this.setToken(TokenType.Identifier, value);
1487
1910
  }
1488
- number(char) {
1489
- let value = char;
1490
- let nextC;
1491
- while (1) {
1492
- nextC = this.code[this.i + 1];
1493
- if (!bobeShared.isNum(nextC)) {
1494
- break;
1495
- }
1496
- value += nextC;
1497
- this.i++;
1911
+ config(opt) {
1912
+ Object.assign(this, opt);
1913
+ this.opt = opt;
1914
+ }
1915
+ createNode(name) {
1916
+ return {
1917
+ name,
1918
+ props: {},
1919
+ nextSibling: null
1920
+ };
1921
+ }
1922
+ nextSib(node) {
1923
+ return node.nextSibling;
1924
+ }
1925
+ firstChild(node) {
1926
+ return node.firstChild;
1927
+ }
1928
+ createAnchor(name) {
1929
+ return {
1930
+ name,
1931
+ nextSibling: null
1932
+ };
1933
+ }
1934
+ insertAfter(parent, node, prev) {
1935
+ return this.defaultInsert(parent, node, prev);
1936
+ }
1937
+ defaultInsert(parent, node, prev) {
1938
+ if (prev) {
1939
+ const next = prev.nextSibling;
1940
+ prev.nextSibling = node;
1941
+ node.nextSibling = next;
1942
+ } else {
1943
+ const next = parent.firstChild;
1944
+ parent.firstChild = node;
1945
+ node.nextSibling = next;
1498
1946
  }
1499
- this.setToken(TokenType.Identifier, Number(value));
1500
1947
  }
1501
- eof() {
1502
- this.setToken(TokenType.Eof, 'End Of File');
1948
+ remove(node, parent, prev) {
1949
+ return this.defaultRemove(node, parent, prev);
1503
1950
  }
1504
- HookId = '_h_o_o_k_';
1505
- hookI = 0;
1506
- _hook = props => {
1507
- const value = this.token.value;
1508
- const isDynamicHook = this.token.type & TokenType.InsertionExp;
1509
- const isStaticHook = typeof value === 'string' && value.indexOf(this.HookId) === 0;
1510
- const hookType = isDynamicHook ? 'dynamic' : isStaticHook ? 'static' : undefined;
1511
- if (this.hook && isStaticHook) {
1512
- const hookI = Number(value.slice(this.HookId.length));
1513
- const res = this.hook({
1514
- ...props,
1515
- HookId: this.HookId,
1516
- i: hookI
1517
- });
1518
- return [hookType, res, hookI];
1519
- } else if (isDynamicHook) {
1520
- return [hookType, value];
1951
+ defaultRemove(node, parent, prevSibling) {
1952
+ const next = node.nextSibling;
1953
+ if (prevSibling) {
1954
+ prevSibling.nextSibling = next;
1521
1955
  }
1522
- return [hookType, value];
1523
- };
1524
- init(fragments) {
1525
- if (typeof fragments === 'string') {
1526
- this.setCode(fragments);
1527
- } else {
1528
- let code = '';
1529
- for (let i = 0; i < fragments.length - 1; i++) {
1530
- const fragment = fragments[i];
1531
- code += fragment + `${this.HookId}${i}`;
1532
- }
1533
- this.setCode(code + fragments[fragments.length - 1]);
1956
+ if (parent.firstChild === node) {
1957
+ parent.firstChild = next;
1534
1958
  }
1535
1959
  }
1960
+ setProp(node, key, value, hookI) {
1961
+ node.props[key] = value;
1962
+ }
1536
1963
  }
1537
1964
 
1538
1965
  function bobe(fragments, ...values) {
@@ -1565,6 +1992,9 @@ function customRender(option) {
1565
1992
  };
1566
1993
  }
1567
1994
 
1995
+ exports.Compiler = Compiler;
1996
+ exports.NodeType = NodeType;
1997
+ exports.Tokenizer = Tokenizer;
1568
1998
  exports.bobe = bobe;
1569
1999
  exports.customRender = customRender;
1570
2000
  Object.keys(aoye).forEach(function (k) {