bobe 0.0.32 → 0.0.34

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,1933 @@ 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)
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
871
+ }
774
872
  };
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;
873
+ }
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);
792
882
  }
793
883
  }
794
- };
795
- node.realAfter = this.insertAfterAnchor('component-after');
884
+ if (this.tokenizer.token.type & TokenType.Dedent) {
885
+ this.tokenizer.nextToken();
886
+ }
887
+ }
888
+ return children;
889
+ }
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();
898
+ }
899
+ if (value === 'for') {
900
+ return this.parseLoopNode();
901
+ }
902
+ if (hookType) {
903
+ return this.parseComponentNode();
904
+ }
905
+ return this.parseElementNode();
906
+ }
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;
796
918
  return node;
797
919
  }
798
- getFn(data, expression) {
799
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
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;
800
932
  }
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;
933
+ parseConditionalNode(node) {
934
+ const keyword = this.tokenizer.token.value;
935
+ this.tokenizer.condExp();
936
+ const condition = this.parsePropertyValue();
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
+ this.tokenizer.nextToken();
948
+ const collection = this.parsePropertyValue();
949
+ this.tokenizer.nextToken();
950
+ const itemToken = this.tokenizer.nextToken();
951
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
952
+ if (isDestruct) {
953
+ itemToken.value = '{' + itemToken.value + '}';
882
954
  }
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);
955
+ const item = this.parsePropertyValue();
956
+ let char = this.tokenizer.peekChar(),
957
+ key,
958
+ index;
959
+ if (char === ';') {
960
+ this.tokenizer.nextToken();
961
+ if (this.tokenizer.peekChar() !== '\n') {
962
+ this.tokenizer.jsExp();
963
+ key = this.parsePropertyValue();
964
+ }
965
+ } else if (char === '\n') ; else {
966
+ this.tokenizer.nextToken();
967
+ index = this.parsePropertyValue();
968
+ if (this.tokenizer.peekChar() === ';') {
969
+ this.tokenizer.nextToken();
970
+ if (this.tokenizer.peekChar() !== '\n') {
971
+ this.tokenizer.jsExp();
972
+ key = this.parsePropertyValue();
903
973
  }
904
974
  }
905
- ifNode.isFirstRender = false;
906
- }, [signal]);
907
- ifNode.effect = ef;
908
- return ifNode;
909
- }
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;
919
975
  }
976
+ this.tokenizer.nextToken();
977
+ this.tokenizer.nextToken();
978
+ node.type = NodeType.For;
979
+ node.collection = collection;
980
+ node.item = item;
981
+ node.index = index;
982
+ node.key = key;
983
+ this.hooks.parseLoopNode?.propsAdded?.call(this, node);
984
+ const children = this.handleChildren();
985
+ node.children = children;
986
+ return node;
920
987
  }
921
- extensionLines(_node) {
922
- while (1) {
923
- if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
924
- return;
925
- }
988
+ headerLineAndExtensions() {
989
+ const props = [];
990
+ props.push(...this.attributeList());
991
+ if (this.tokenizer.token.type & TokenType.NewLine) {
926
992
  this.tokenizer.nextToken();
927
- this.attributeList(_node);
928
- if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
929
- return;
930
- }
993
+ }
994
+ while (this.tokenizer.token.type & TokenType.Pipe) {
931
995
  this.tokenizer.nextToken();
996
+ props.push(...this.attributeList());
997
+ if (this.tokenizer.token.type & TokenType.NewLine) {
998
+ this.tokenizer.nextToken();
999
+ }
932
1000
  }
1001
+ return props;
933
1002
  }
934
- headerLine(_node) {
935
- this.attributeList(_node);
936
- this.tokenizer.nextToken();
1003
+ attributeList() {
1004
+ const props = [];
1005
+ while (!(this.tokenizer.token.type & TokenType.NewLine) && !(this.tokenizer.token.type & TokenType.Pipe) && !this.tokenizer.isEof()) {
1006
+ props.push(this.parseProperty());
1007
+ }
1008
+ return props;
937
1009
  }
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;
965
- }
1010
+ parseProperty(node) {
1011
+ node.type = NodeType.Property;
1012
+ node.key = this.parsePropertyKey();
1013
+ const token = this.tokenizer.nextToken();
1014
+ if (token.value === '=') {
1015
+ this.tokenizer.nextToken();
1016
+ node.value = this.parsePropertyValue();
966
1017
  this.tokenizer.nextToken();
967
1018
  }
1019
+ node.loc.start = node.key.loc.start;
1020
+ node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;
1021
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1022
+ return node;
1023
+ }
1024
+ parsePropertyKey(node) {
1025
+ node.type = NodeType.PropertyKey;
1026
+ node.key = this.tokenizer.token.value;
1027
+ return node;
968
1028
  }
969
- config(opt) {
970
- Object.assign(this, opt);
971
- this.opt = opt;
1029
+ parsePropertyValue(node) {
1030
+ const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1031
+ _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 2),
1032
+ hookType = _this$tokenizer$_hook4[0],
1033
+ value = _this$tokenizer$_hook4[1];
1034
+ node.type = hookType === 'dynamic' ? NodeType.DynamicValue : NodeType.StaticValue;
1035
+ node.value = value;
1036
+ return node;
972
1037
  }
973
- createNode(name) {
974
- return {
975
- name,
976
- props: {},
977
- nextSibling: null
1038
+ }
1039
+ function NodeLoc(target, context) {
1040
+ return function (_node) {
1041
+ _node.loc.start = this.tokenizer.token.loc.start;
1042
+ const result = target.call(this, _node);
1043
+ _node.loc.end = this.tokenizer.token.loc ? this.tokenizer.token.loc.start : this.tokenizer.getCurrentPos();
1044
+ _node.loc.source = this.tokenizer.code.slice(_node.loc.start.offset, _node.loc.end.offset);
1045
+ return result;
1046
+ };
1047
+ }
1048
+ function TokenLoc(target, context) {
1049
+ return function (_node) {
1050
+ const result = target.call(this, _node);
1051
+ _node.loc = this.tokenizer.token.loc;
1052
+ return result;
1053
+ };
1054
+ }
1055
+ function NodeHook(target, context) {
1056
+ return function (_node) {
1057
+ const hook = this.hooks[context.name];
1058
+ const node = {
1059
+ loc: {}
1060
+ };
1061
+ hook?.enter?.call(this, node);
1062
+ const result = target.call(this, node);
1063
+ hook?.leave?.call(this, node);
1064
+ return result;
1065
+ };
1066
+ }
1067
+
1068
+ class MultiTypeStack {
1069
+ typeTops = {};
1070
+ length = 0;
1071
+ stack = [];
1072
+ push(value, bits) {
1073
+ const newNode = {
1074
+ value,
1075
+ types: bits,
1076
+ prevByType: {}
978
1077
  };
1078
+ let bit;
1079
+ while (1) {
1080
+ bit = bits & ~bits + 1;
1081
+ if (!bit) break;
1082
+ bits &= ~bit;
1083
+ newNode.prevByType[bit] = this.typeTops[bit] || undefined;
1084
+ this.typeTops[bit] = newNode;
1085
+ }
1086
+ this.stack[this.length++] = newNode;
979
1087
  }
980
- nextSib(node) {
981
- return node.nextSibling;
1088
+ pop() {
1089
+ const poppedNode = this.stack[this.length - 1];
1090
+ this.stack[--this.length] = null;
1091
+ if (!poppedNode) return undefined;
1092
+ let bits = poppedNode.types;
1093
+ let bit;
1094
+ while (1) {
1095
+ bit = bits & ~bits + 1;
1096
+ if (!bit) break;
1097
+ bits &= ~bit;
1098
+ this.typeTops[bit] = poppedNode.prevByType[bit];
1099
+ }
1100
+ return [poppedNode.value, poppedNode.types];
982
1101
  }
983
- firstChild(node) {
984
- return node.firstChild;
1102
+ peekByType(cat) {
1103
+ return this.typeTops[cat]?.value;
985
1104
  }
986
- createAnchor(name) {
987
- return {
988
- name,
989
- nextSibling: null
990
- };
1105
+ peekType() {
1106
+ return this.stack.at(-1).types;
991
1107
  }
992
- insertAfter(parent, node, prev) {
993
- return this.defaultInsert(parent, node, prev);
1108
+ peek() {
1109
+ return this.stack.at(-1).value;
994
1110
  }
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;
1111
+ }
1112
+
1113
+ function macInc(arr) {
1114
+ const len = arr.length;
1115
+ let candyLast = [],
1116
+ i = 0;
1117
+ while (i < len) {
1118
+ const it = arr[i];
1119
+ if (it !== -1) {
1120
+ candyLast = [i];
1121
+ break;
1004
1122
  }
1123
+ i++;
1005
1124
  }
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;
1125
+ if (i + 1 >= len) return candyLast;
1126
+ const toPrev = new Int32Array(len);
1127
+ while (i < len) {
1128
+ const target = arr[i];
1129
+ if (target === -1) continue;
1130
+ let start = -1,
1131
+ end = candyLast.length;
1132
+ while (start + 1 < end) {
1133
+ const mid = start + end >> 1;
1134
+ if (arr[candyLast[mid]] < target) {
1135
+ start = mid;
1136
+ } else {
1137
+ end = mid;
1138
+ }
1016
1139
  }
1140
+ candyLast[end] = i;
1141
+ toPrev[i] = candyLast[start];
1142
+ i++;
1017
1143
  }
1018
- setProp(node, key, value, hookI) {
1019
- node.props[key] = value;
1144
+ let length = candyLast.length;
1145
+ for (let j = length - 1; j > 0; j--) {
1146
+ const prev = toPrev[candyLast[j]];
1147
+ candyLast[j - 1] = prev;
1020
1148
  }
1149
+ return candyLast;
1021
1150
  }
1022
1151
 
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;
1152
+ const KEY_INDEX = '__BOBE_KEY_INDEX';
1153
+
1154
+ const _excluded = ["dentStack", "isFirstToken"];
1155
+ class Interpreter {
1156
+ constructor(tokenizer) {
1157
+ this.tokenizer = tokenizer;
1158
+ }
1159
+ isLogicNode(node) {
1160
+ return node && node.__logicType & LogicalBit;
1161
+ }
1162
+ rootComponent = null;
1163
+ program(root, componentNode, before, ctxProvider) {
1164
+ this.rootComponent = componentNode;
1165
+ this.tokenizer.nextToken();
1166
+ const stack = new MultiTypeStack();
1167
+ stack.push({
1168
+ node: root,
1169
+ prev: null
1170
+ }, NodeSort.Real);
1171
+ stack.push({
1172
+ node: componentNode,
1173
+ prev: null
1174
+ }, NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher);
1175
+ if (ctxProvider) {
1176
+ stack.push({
1177
+ node: ctxProvider,
1178
+ prev: null
1179
+ }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
1180
+ }
1181
+ const rootLen = stack.length;
1182
+ const ctx = this.ctx = {
1183
+ realParent: root,
1184
+ prevSibling: before,
1185
+ current: null,
1186
+ stack,
1187
+ before
1188
+ };
1189
+ const rootPulling = aoye.getPulling();
1190
+ while (1) {
1191
+ if (this.tokenizer.isEof()) {
1192
+ if (!ctx.prevSibling) ctx.prevSibling = before;
1193
+ this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
1194
+ break;
1195
+ }
1196
+ const token = this.tokenizer.token;
1197
+ if (token.type & TokenType.Indent) {
1198
+ this.tokenizer.nextToken();
1199
+ const isLogicNode = this.isLogicNode(ctx.current);
1200
+ stack.push({
1201
+ node: ctx.current,
1202
+ prev: ctx.prevSibling
1203
+ }, !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);
1204
+ if (ctx.current.__logicType) {
1205
+ if (isLogicNode) {
1206
+ aoye.setPulling(ctx.current.effect);
1207
+ if (ctx.current.__logicType & FakeType.ForItem) {
1208
+ ctx.prevSibling = ctx.current.realBefore;
1209
+ }
1210
+ }
1211
+ } else {
1212
+ if (ctx.current) {
1213
+ ctx.realParent = ctx.current;
1214
+ }
1215
+ ctx.prevSibling = null;
1216
+ }
1217
+ ctx.current = this.declaration(ctx);
1218
+ continue;
1219
+ }
1220
+ if (ctx.current) {
1221
+ if (stack.length === rootLen && !ctx.prevSibling) {
1222
+ ctx.prevSibling = before;
1223
+ }
1224
+ this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
1225
+ }
1226
+ if (this.tokenizer.token.type & TokenType.Dedent) {
1227
+ this.tokenizer.nextToken();
1228
+ const _stack$pop = stack.pop(),
1229
+ _stack$pop2 = _slicedToArray(_stack$pop, 2),
1230
+ _stack$pop2$ = _stack$pop2[0],
1231
+ parent = _stack$pop2$.node,
1232
+ prev = _stack$pop2$.prev,
1233
+ sort = _stack$pop2[1];
1234
+ if (!parent.__logicType) {
1235
+ const prevSameType = stack.peekByType(NodeSort.Real);
1236
+ ctx.realParent = prevSameType?.node || root;
1237
+ } else {
1238
+ if (sort & NodeSort.Logic) {
1239
+ const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
1240
+ if (parentLogic) {
1241
+ aoye.setPulling(parentLogic.effect);
1242
+ } else {
1243
+ aoye.setPulling(rootPulling);
1244
+ }
1245
+ }
1246
+ if (sort & NodeSort.TokenizerSwitcher) {
1247
+ const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1248
+ this.tokenizer = switcher.tokenizer;
1249
+ }
1250
+ if (parent.__logicType === FakeType.ForItem) {
1251
+ const _ref = parent,
1252
+ forNode = _ref.forNode;
1253
+ const i = forNode.i,
1254
+ arr = forNode.arr,
1255
+ snapshot = forNode.snapshot;
1256
+ if (i + 1 < arr.length) {
1257
+ this.tokenizer.resume(snapshot);
1258
+ this.tokenizer.nextToken();
1259
+ this.tokenizer.nextToken();
1260
+ ctx.current = forNode.children[++forNode.i];
1261
+ ctx.prevSibling = ctx.current.realBefore;
1262
+ continue;
1263
+ }
1264
+ ctx.prevSibling = forNode.prevSibling;
1265
+ ctx.current = forNode;
1266
+ continue;
1267
+ }
1268
+ }
1269
+ ctx.prevSibling = prev;
1270
+ ctx.current = parent;
1271
+ } else {
1272
+ ctx.prevSibling = ctx.current || ctx.prevSibling;
1273
+ ctx.current = this.declaration(ctx);
1274
+ }
1042
1275
  }
1276
+ return componentNode;
1043
1277
  }
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);
1278
+ insertAfterAnchor(name = 'anchor') {
1279
+ const _this$ctx = this.ctx,
1280
+ realParent = _this$ctx.realParent,
1281
+ prevSibling = _this$ctx.prevSibling,
1282
+ stack = _this$ctx.stack,
1283
+ before = _this$ctx.before;
1284
+ const afterAnchor = this.createAnchor(name);
1285
+ this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1286
+ this.handleInsert(realParent, afterAnchor, prevSibling);
1287
+ return afterAnchor;
1055
1288
  }
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
- }
1289
+ handleInsert(parent, child, prev, parentComponent) {
1290
+ if (!child.__logicType) {
1291
+ if (!prev || !prev.__logicType) {
1292
+ this.insertAfter(parent, child, prev);
1293
+ } else {
1294
+ const before = prev.realAfter;
1295
+ this.insertAfter(parent, child, before);
1296
+ }
1297
+ } else {
1298
+ const childCmp = child;
1299
+ childCmp.realParent = parent;
1300
+ if (prev?.__logicType) {
1301
+ childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
1302
+ } else {
1303
+ childCmp.realBefore = prev;
1067
1304
  }
1068
1305
  }
1069
- return snap;
1070
1306
  }
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;
1307
+ getPrevRealSibling(prevSibling) {
1308
+ if (!prevSibling || !prevSibling.__logicType) {
1309
+ return prevSibling;
1310
+ }
1311
+ let point = prevSibling;
1312
+ while (point != null) {
1313
+ if (point.lastChild) {
1314
+ return point.lastChild.value;
1088
1315
  }
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;
1316
+ point = point.anchor;
1317
+ }
1318
+ }
1319
+ declaration(ctx) {
1320
+ const _this$tokenizer$_hook = this.tokenizer._hook({}),
1321
+ _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
1322
+ hookType = _this$tokenizer$_hook2[0],
1323
+ value = _this$tokenizer$_hook2[1];
1324
+ let _node;
1325
+ if (value === 'if' || value === 'else' || value === 'fail') {
1326
+ return this.condDeclaration(ctx);
1327
+ } else if (value === 'for') {
1328
+ return this.forDeclaration();
1329
+ } else if (hookType) {
1330
+ const data = this.getData();
1331
+ if (hookType === 'static') {
1332
+ if (typeof value === 'function') {
1333
+ _node = this.componentOrFragmentDeclaration(value, ctx);
1334
+ } else {
1335
+ throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
1336
+ }
1097
1337
  } 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
- }
1338
+ const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1339
+ const val = data[aoye.Keys.Raw][value];
1340
+ if (typeof val === 'function') {
1341
+ _node = this.componentOrFragmentDeclaration(val, ctx);
1342
+ } else {
1343
+ const str = valueIsMapKey ? value : this.getFn(data, value);
1344
+ _node = this.createNode('text');
1345
+ this.onePropParsed(data, _node, 'text', str, valueIsMapKey, false);
1117
1346
  }
1118
- break;
1119
1347
  }
1348
+ } else {
1349
+ _node = this.createNode(value);
1120
1350
  }
1121
- if (!this.token) {
1122
- this.nextToken();
1351
+ this.tokenizer.nextToken();
1352
+ this.headerLine(_node);
1353
+ this.extensionLines(_node);
1354
+ if (_node.__logicType & TokenizerSwitcherBit) {
1355
+ this.onePropParsed = this.oneRealPropParsed;
1356
+ this.tokenizer = _node.tokenizer;
1123
1357
  }
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;
1358
+ return _node;
1146
1359
  }
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;
1360
+ forDeclaration() {
1361
+ const arrExp = this.tokenizer.nextToken().value;
1362
+ this.tokenizer.nextToken();
1363
+ const itemToken = this.tokenizer.nextToken();
1364
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
1365
+ let itemExp = itemToken.value,
1366
+ vars;
1367
+ if (isDestruct) {
1368
+ itemExp = '{' + itemExp + '}';
1369
+ vars = itemExp.match(bobeShared.jsVarRegexp);
1370
+ const varStr = vars.join(',');
1371
+ itemExp = new Function(itemExp, `return {${varStr}};`);
1372
+ }
1373
+ let indexName,
1374
+ keyExp,
1375
+ char = this.tokenizer.peekChar();
1376
+ if (char === ';') {
1377
+ this.tokenizer.nextToken();
1378
+ if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
1379
+ } else if (char === '\n') ; else {
1380
+ indexName = this.tokenizer.nextToken().value;
1381
+ if (this.tokenizer.peekChar() === ';') {
1382
+ this.tokenizer.nextToken();
1383
+ if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
1157
1384
  }
1158
- outer: while (1) {
1159
- if (this.needIndent) {
1160
- this.dent();
1385
+ }
1386
+ const owner = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1387
+ const prevSibling = this.ctx.prevSibling;
1388
+ const forNode = {
1389
+ __logicType: FakeType.For,
1390
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1391
+ realParent: this.ctx.realParent,
1392
+ prevSibling,
1393
+ realBefore: prevSibling?.realAfter || prevSibling,
1394
+ realAfter: null,
1395
+ arr: null,
1396
+ arrSignal: null,
1397
+ itemExp,
1398
+ indexName,
1399
+ getKey: null,
1400
+ children: [],
1401
+ effect: null,
1402
+ owner,
1403
+ vars,
1404
+ i: 0
1405
+ };
1406
+ if (keyExp) {
1407
+ forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}};return v;`);
1408
+ }
1409
+ window['for1'] = forNode;
1410
+ const data = this.getData();
1411
+ const cells = data[aoye.Keys.Meta].cells;
1412
+ const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
1413
+ const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new aoye.Computed(this.getFn(data, arrExp));
1414
+ forNode.arrSignal = arrSignal;
1415
+ forNode.realAfter = this.insertAfterAnchor('for-after');
1416
+ const _forNode$snapshot = forNode.snapshot;
1417
+ _forNode$snapshot.dentStack;
1418
+ _forNode$snapshot.isFirstToken;
1419
+ const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
1420
+ let isFirstRender = true;
1421
+ forNode.effect = new aoye.Effect(() => {
1422
+ let arr = arrSignal.get();
1423
+ arr[aoye.Keys.Iterator];
1424
+ const prevCtx = aoye.getPulling();
1425
+ aoye.setPulling(null);
1426
+ forNode.arr = arr = aoye.toRaw(arr);
1427
+ const children = forNode.children;
1428
+ if (isFirstRender) {
1429
+ const len = arr.length;
1430
+ for (let i = len; i--;) {
1431
+ const item = this.createForItem(forNode, i, data);
1432
+ item.realAfter = this.insertAfterAnchor('for-item-after');
1433
+ item.realBefore = this.insertAfterAnchor('for-item-before');
1434
+ item.realParent = forNode.realParent;
1435
+ children[i] = item;
1436
+ }
1437
+ const firstInsert = children[0];
1438
+ if (firstInsert) {
1439
+ this.tokenizer.nextToken();
1440
+ this.tokenizer.nextToken();
1161
1441
  } 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);
1442
+ this.tokenizer.skip();
1443
+ }
1444
+ } else {
1445
+ const oldLen = children.length;
1446
+ const newLen = arr.length;
1447
+ const minLen = Math.min(oldLen, newLen);
1448
+ const newChildren = [];
1449
+ if (!forNode.getKey) {
1450
+ if (newLen < oldLen) {
1451
+ for (let i = oldLen - 1; i >= newLen; i--) {
1452
+ this.removeForItem(children, i);
1453
+ }
1454
+ }
1455
+ if (oldLen < newLen) {
1456
+ const lastAfter = children.at(-1)?.realAfter || forNode.realBefore;
1457
+ for (let i = newLen - 1; i >= oldLen; i--) {
1458
+ this.insertForItem(forNode, i, data, newChildren, lastAfter, snapshotForUpdate);
1459
+ }
1460
+ }
1461
+ for (let i = minLen; i--;) {
1462
+ const child = children[i];
1463
+ newChildren[i] = child;
1464
+ this.reuseForItem(child, arr[i], itemExp, i, indexName);
1465
+ }
1466
+ } else {
1467
+ let s = 0,
1468
+ e1 = oldLen - 1,
1469
+ e2 = newLen - 1;
1470
+ while (s <= e1 && s <= e2) {
1471
+ const child = children[s];
1472
+ const old = child.key;
1473
+ const itemData = this.getItemData(forNode, s, data);
1474
+ const key = forNode.getKey(itemData);
1475
+ if (old === key) {
1476
+ newChildren[s] = child;
1477
+ this.reuseForItem(child, arr[s], itemExp, s, indexName);
1478
+ s++;
1479
+ } else {
1184
1480
  break;
1185
- case '$':
1186
- const handled = this.dynamic(char);
1187
- if (handled) break;
1188
- case ';':
1189
- this.setToken(TokenType.Semicolon, ';');
1481
+ }
1482
+ }
1483
+ while (s <= e1 && s <= e2) {
1484
+ const child = children[e1];
1485
+ const old = child.key;
1486
+ const itemData = this.getItemData(forNode, e2, data);
1487
+ const key = forNode.getKey(itemData);
1488
+ if (old === key) {
1489
+ newChildren[e2] = child;
1490
+ this.reuseForItem(child, arr[e2], itemExp, e2, indexName);
1491
+ e1--;
1492
+ e2--;
1493
+ } else {
1190
1494
  break;
1191
- default:
1192
- if (bobeShared.isNum(char)) {
1193
- this.number(char);
1194
- break;
1495
+ }
1496
+ }
1497
+ if (s > e1) {
1498
+ if (s <= e2) {
1499
+ const firstBefore = s > 0 ? children[s - 1]?.realAfter || forNode.realBefore : forNode.realBefore;
1500
+ for (let i = e2; i >= s; i--) {
1501
+ this.insertForItem(forNode, i, data, newChildren, firstBefore, snapshotForUpdate);
1195
1502
  }
1196
- if (typeof char === 'string' && bobeShared.matchIdStart2(char, 0)) {
1197
- this.identifier(char);
1503
+ }
1504
+ } else if (s > e2) {
1505
+ if (s <= e1) {
1506
+ for (let i = e1; i >= s; i--) {
1507
+ this.removeForItem(children, i);
1198
1508
  }
1199
- break;
1509
+ }
1510
+ } else {
1511
+ let s1 = s,
1512
+ s2 = s;
1513
+ const mixLen = e2 - s2 + 1;
1514
+ const key2new = new Map();
1515
+ for (let i = s2; i <= e2; i++) {
1516
+ const itemData = this.getItemData(forNode, i, data);
1517
+ const key = forNode.getKey(itemData);
1518
+ key2new.set(key, i);
1519
+ }
1520
+ let maxIncNewI = -1;
1521
+ let hasMove = false;
1522
+ const new2oldI = new Array(mixLen).fill(-1);
1523
+ for (let i = s1; i <= e1; i++) {
1524
+ const key = children[i].key;
1525
+ const newI = key2new.get(key);
1526
+ if (newI == null) {
1527
+ this.removeForItem(children, i);
1528
+ continue;
1529
+ }
1530
+ const child = children[i];
1531
+ newChildren[newI] = child;
1532
+ this.reuseForItem(child, arr[newI], itemExp, newI, indexName);
1533
+ new2oldI[newI - s2] = i;
1534
+ key2new.delete(key);
1535
+ if (newI < maxIncNewI) {
1536
+ hasMove = true;
1537
+ } else {
1538
+ maxIncNewI = newI;
1539
+ }
1540
+ }
1541
+ if (!hasMove) {
1542
+ key2new.forEach((i, key) => {
1543
+ const before = i === 0 ? forNode.realBefore : newChildren[i - 1].realAfter;
1544
+ this.insertForItem(forNode, i, data, newChildren, before, snapshotForUpdate);
1545
+ });
1546
+ } else {
1547
+ const incI = macInc(new2oldI),
1548
+ incLen = incI.length;
1549
+ let p1, p2;
1550
+ for (p1 = s2, p2 = 0; p1 <= e2; p1++) {
1551
+ const oldI = new2oldI[p1];
1552
+ if (oldI === -1) {
1553
+ const before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
1554
+ this.insertForItem(forNode, p1, data, newChildren, before, snapshotForUpdate);
1555
+ continue;
1556
+ }
1557
+ const staticIdx = incI[p2] + s2;
1558
+ if (p1 === staticIdx) {
1559
+ p2 <= incLen && p2++;
1560
+ continue;
1561
+ }
1562
+ let before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
1563
+ const child = newChildren[p1];
1564
+ const realBefore = child.realBefore,
1565
+ realAfter = child.realAfter,
1566
+ realParent = child.realParent;
1567
+ let point = realBefore,
1568
+ next;
1569
+ do {
1570
+ next = this.nextSib(point);
1571
+ this.insertAfter(realParent, point, before);
1572
+ before = point;
1573
+ if (point === realAfter) break;
1574
+ point = next;
1575
+ } while (true);
1576
+ }
1577
+ }
1200
1578
  }
1201
- this.i++;
1202
1579
  }
1203
- if (this.token) {
1204
- break;
1580
+ forNode.children = newChildren;
1581
+ }
1582
+ isFirstRender = false;
1583
+ aoye.setPulling(prevCtx);
1584
+ return isDestroy => {
1585
+ if (isDestroy) {
1586
+ for (let i = 0; i < forNode.children.length; i++) {
1587
+ const item = forNode.children[i];
1588
+ item.effect.dispose();
1589
+ }
1205
1590
  }
1591
+ };
1592
+ });
1593
+ return forNode.children[0] || forNode;
1594
+ }
1595
+ insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
1596
+ const item = this.createForItem(forNode, i, parentData);
1597
+ newChildren[i] = item;
1598
+ let realAfter = this.createAnchor('for-item-after');
1599
+ this.handleInsert(forNode.realParent, realAfter, before);
1600
+ let realBefore = this.createAnchor('for-item-before');
1601
+ this.handleInsert(forNode.realParent, realBefore, before);
1602
+ item.realBefore = realBefore;
1603
+ item.realAfter = realAfter;
1604
+ this.tokenizer = forNode.owner.tokenizer;
1605
+ this.tokenizer.resume(snapshotForUpdate);
1606
+ this.tokenizer.useDedentAsEof = false;
1607
+ aoye.runWithPulling(() => {
1608
+ this.program(forNode.realParent, forNode.owner, realBefore, item);
1609
+ }, item.effect);
1610
+ }
1611
+ removeForItem(children, i) {
1612
+ const child = children[i];
1613
+ this.removeLogicNode(child);
1614
+ this.remove(child.realBefore);
1615
+ this.remove(child.realAfter);
1616
+ child.effect.dispose();
1617
+ }
1618
+ reuseForItem(child, data, itemExp, i, indexName) {
1619
+ if (typeof itemExp === 'string') {
1620
+ child.data[itemExp] = data;
1621
+ if (indexName) {
1622
+ child.data[indexName] = i;
1206
1623
  }
1207
- return this.token;
1208
- } catch (error) {
1209
- console.error(error);
1210
- return this.token;
1211
- } finally {
1212
- this.handledTokens.push(this.token);
1624
+ } else {
1625
+ indexName = indexName || KEY_INDEX;
1626
+ child.data[indexName] = i;
1213
1627
  }
1214
1628
  }
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;
1629
+ forItemId = 0;
1630
+ createForItem(forNode, i, parentData) {
1631
+ let forItemNode;
1632
+ let data;
1633
+ const scope = new aoye.Scope(() => {});
1634
+ scope.scope = null;
1635
+ aoye.runWithPulling(() => {
1636
+ scope.get();
1637
+ }, null);
1638
+ data = this.getItemData(forNode, i, parentData);
1639
+ forItemNode = {
1640
+ id: this.forItemId++,
1641
+ __logicType: FakeType.ForItem,
1642
+ realParent: null,
1643
+ realBefore: null,
1644
+ realAfter: null,
1645
+ forNode,
1646
+ key: forNode.getKey?.(data),
1647
+ effect: null,
1648
+ data
1649
+ };
1650
+ forItemNode.effect = scope;
1651
+ return forItemNode;
1652
+ }
1653
+ getItemData(forNode, i, parentData) {
1654
+ const arr = forNode.arr,
1655
+ itemExp = forNode.itemExp,
1656
+ vars = forNode.vars,
1657
+ arrSignal = forNode.arrSignal,
1658
+ getKey = forNode.getKey;
1659
+ let indexName = forNode.indexName;
1660
+ let data;
1661
+ if (typeof itemExp === 'string') {
1662
+ data = aoye.deepSignal(indexName ? {
1663
+ [itemExp]: arr[i],
1664
+ [indexName]: i
1665
+ } : {
1666
+ [itemExp]: arr[i]
1667
+ }, aoye.getPulling());
1668
+ } else {
1669
+ indexName = indexName ?? KEY_INDEX;
1670
+ const rawData = {
1671
+ [indexName]: i
1672
+ };
1673
+ data = aoye.deepSignal(rawData, aoye.getPulling());
1674
+ const computedData = new aoye.Computed(() => itemExp(arrSignal.get()[getKey ? data[indexName] : i]));
1675
+ const cells = data[aoye.Keys.Meta].cells;
1676
+ for (let i = 0; i < vars.length; i++) {
1677
+ const name = vars[i];
1678
+ rawData[name] = undefined;
1679
+ cells.set(name, new aoye.Computed(() => computedData.get()[name]));
1222
1680
  }
1223
- value += char;
1224
- this.i++;
1225
1681
  }
1226
- value = value.trim();
1227
- this.setToken(TokenType.Identifier, value || true);
1228
- return this.token;
1682
+ Object.setPrototypeOf(data, parentData);
1683
+ return data;
1229
1684
  }
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
- }
1685
+ getData() {
1686
+ const _this$ctx$stack$peekB = this.ctx.stack.peekByType(NodeSort.CtxProvider),
1687
+ node = _this$ctx$stack$peekB.node;
1688
+ return node.data;
1243
1689
  }
1244
- peekChar() {
1245
- let i = this.i;
1246
- while (this.code[i] === ' ' || this.code[i] === '\t') {
1247
- i++;
1690
+ onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
1691
+ if (isFn) {
1692
+ this.setProp(node, key, value, hookI);
1693
+ } else if (typeof value === 'function') {
1694
+ new aoye.Effect(() => {
1695
+ const res = value();
1696
+ this.setProp(node, key, res, hookI);
1697
+ });
1698
+ } else if (valueIsMapKey) {
1699
+ new aoye.Effect(() => {
1700
+ const res = data[value];
1701
+ this.setProp(node, key, res, hookI);
1702
+ });
1703
+ } else {
1704
+ this.setProp(node, key, value, hookI);
1248
1705
  }
1249
- return this.code[i];
1250
- }
1251
- assignment() {
1252
- this.setToken(TokenType.Assign, '=');
1253
- }
1254
- pipe() {
1255
- this.setToken(TokenType.Pipe, '|');
1256
1706
  }
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
- }
1707
+ oneRealPropParsed = this.onePropParsed.bind(this);
1708
+ componentOrFragmentDeclaration(ComponentOrRender, ctx) {
1709
+ let Component, render, child;
1710
+ const isCC = ComponentOrRender.prototype instanceof aoye.Store;
1711
+ if (isCC) {
1712
+ Component = ComponentOrRender;
1713
+ child = Component.new();
1714
+ } else {
1715
+ render = ComponentOrRender;
1716
+ const boundStore = render.boundStore;
1717
+ child = aoye.deepSignal({}, aoye.getPulling(), true);
1718
+ Object.setPrototypeOf(child, boundStore);
1278
1719
  }
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;
1720
+ const node = {
1721
+ __logicType: isCC ? FakeType.Component : FakeType.Fragment,
1722
+ realParent: ctx.realParent,
1723
+ realBefore: null,
1724
+ realAfter: null,
1725
+ data: child,
1726
+ tokenizer: render ? render(true) : child['ui'](true)
1727
+ };
1728
+ this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
1729
+ if (isFn) {
1730
+ child[aoye.Keys.Raw][key] = value;
1731
+ } else if (valueIsMapKey) {
1732
+ aoye.shareSignal(data, value, child, key);
1302
1733
  } 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--;
1734
+ const meta = child[aoye.Keys.Meta];
1735
+ const cells = meta.cells;
1736
+ if (typeof value === 'function') {
1737
+ const computed = new aoye.Computed(value);
1738
+ cells.set(key, computed);
1739
+ child[aoye.Keys.Raw][key] = undefined;
1740
+ } else {
1741
+ cells.set(key, {
1742
+ get: () => value
1743
+ });
1744
+ child[aoye.Keys.Raw][key] = value;
1317
1745
  }
1318
1746
  }
1319
- if (count === 0 && inString == null && inComment == null) {
1320
- return value.slice(1);
1321
- }
1322
- value += this.code[this.i];
1323
- this.i++;
1324
- }
1747
+ };
1748
+ node.realAfter = this.insertAfterAnchor('component-after');
1749
+ return node;
1325
1750
  }
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);
1751
+ getFn(data, expression) {
1752
+ return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
1341
1753
  }
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
1754
+ condDeclaration(ctx) {
1755
+ const prevSibling = ctx.prevSibling;
1756
+ const keyWord = this.tokenizer.token;
1757
+ const expToken = this.tokenizer.condExp();
1758
+ const value = expToken.value;
1759
+ const isElse = keyWord.value === 'else';
1760
+ const isIf = keyWord.value === 'if';
1761
+ const preIsCond = prevSibling?.__logicType & CondBit;
1762
+ const data = this.getData();
1763
+ const noCond = value === true;
1764
+ const valueIsMapKey = !noCond && Reflect.has(data[aoye.Keys.Raw], value);
1765
+ const owner = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1766
+ const ifNode = {
1767
+ __logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
1768
+ snapshot: this.tokenizer.snapshot(),
1769
+ realParent: null,
1770
+ realBefore: null,
1771
+ realAfter: null,
1772
+ condition: null,
1773
+ preCond: preIsCond ? prevSibling : null,
1774
+ isFirstRender: true,
1775
+ effect: null,
1776
+ owner,
1777
+ data
1375
1778
  };
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;
1779
+ let signal;
1780
+ switch (keyWord.value) {
1781
+ case 'if':
1782
+ if (valueIsMapKey) {
1783
+ aoye.runWithPulling(() => data[value], null);
1784
+ const cells = data[aoye.Keys.Meta].cells;
1785
+ signal = cells.get(value);
1786
+ } else {
1787
+ const fn = this.getFn(data, value);
1788
+ signal = new aoye.Computed(fn);
1407
1789
  }
1408
- this.dentStack.pop();
1409
- if (!this.token) {
1410
- this.setToken(TokenType.Dedent, String(expLen));
1790
+ break;
1791
+ case 'else':
1792
+ if (noCond) {
1793
+ signal = new aoye.Computed(() => {
1794
+ let point = ifNode.preCond;
1795
+ while (point) {
1796
+ if (point.condition.get()) {
1797
+ return false;
1798
+ }
1799
+ if (point.__logicType === FakeType.If) {
1800
+ break;
1801
+ }
1802
+ point = point.preCond;
1803
+ }
1804
+ return true;
1805
+ });
1411
1806
  } else {
1412
- this.waitingTokens.push({
1413
- type: TokenType.Dedent,
1414
- typeName: TokenType[TokenType.Dedent],
1415
- value: String(expLen)
1807
+ const fn = valueIsMapKey ? null : this.getFn(data, value);
1808
+ signal = new aoye.Computed(() => {
1809
+ let point = ifNode.preCond;
1810
+ while (point) {
1811
+ if (point.condition.get()) {
1812
+ return false;
1813
+ }
1814
+ if (point.__logicType === FakeType.If) {
1815
+ break;
1816
+ }
1817
+ point = point.preCond;
1818
+ }
1819
+ return valueIsMapKey ? data[value] : fn();
1416
1820
  });
1417
1821
  }
1418
- }
1419
- return indentHasLen;
1822
+ break;
1823
+ case 'fail':
1824
+ signal = new aoye.Computed(() => {
1825
+ let point = ifNode.preCond;
1826
+ while (point) {
1827
+ if (point.condition.get()) {
1828
+ return false;
1829
+ }
1830
+ point = point.preCond;
1831
+ }
1832
+ return true;
1833
+ });
1834
+ break;
1420
1835
  }
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, '');
1836
+ ifNode.condition = signal;
1837
+ ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
1838
+ const ef = aoye.effect(({
1839
+ val
1840
+ }) => {
1841
+ if (val) {
1842
+ if (ifNode.isFirstRender) {
1843
+ this.tokenizer.nextToken();
1844
+ this.tokenizer.nextToken();
1429
1845
  } else {
1430
- this.setToken(TokenType.Identifier, Tokenizer.EofId);
1846
+ this.tokenizer = ifNode.owner.tokenizer;
1847
+ this.tokenizer.resume(ifNode.snapshot);
1848
+ this.tokenizer.useDedentAsEof = false;
1849
+ this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
1431
1850
  }
1432
1851
  } else {
1433
- if (this.useDedentAsEof) {
1434
- this.waitingTokens.push({
1435
- type: TokenType.Dedent,
1436
- typeName: TokenType[TokenType.Dedent],
1437
- value: ''
1438
- });
1852
+ if (ifNode.isFirstRender) {
1853
+ this.tokenizer.skip();
1439
1854
  } else {
1440
- this.waitingTokens.push({
1441
- type: TokenType.Identifier,
1442
- typeName: TokenType[TokenType.Identifier],
1443
- value: Tokenizer.EofId
1444
- });
1855
+ this.removeLogicNode(ifNode);
1445
1856
  }
1446
1857
  }
1858
+ ifNode.isFirstRender = false;
1859
+ }, [signal]);
1860
+ ifNode.effect = ef;
1861
+ return ifNode;
1862
+ }
1863
+ removeLogicNode(node) {
1864
+ const realBefore = node.realBefore,
1865
+ realAfter = node.realAfter,
1866
+ realParent = node.realParent;
1867
+ let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
1868
+ while (point !== realAfter) {
1869
+ const next = this.nextSib(point);
1870
+ this.remove(point, realParent, realBefore);
1871
+ point = next;
1447
1872
  }
1448
- return yes;
1449
1873
  }
1450
- identifier(char) {
1451
- let value = char;
1452
- let nextC;
1874
+ extensionLines(_node) {
1453
1875
  while (1) {
1454
- nextC = this.code[this.i + 1];
1455
- if (typeof nextC !== 'string' || !bobeShared.matchIdStart2(nextC, 0)) {
1456
- break;
1876
+ if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
1877
+ return;
1457
1878
  }
1458
- value += nextC;
1459
- this.i++;
1460
- }
1461
- if (value === Tokenizer.EofId && this.useDedentAsEof) {
1462
- this.setToken(TokenType.Dedent, '');
1463
- return;
1879
+ this.tokenizer.nextToken();
1880
+ this.attributeList(_node);
1881
+ if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
1882
+ return;
1883
+ }
1884
+ this.tokenizer.nextToken();
1464
1885
  }
1465
- let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
1466
- this.setToken(TokenType.Identifier, realValue);
1467
1886
  }
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++;
1887
+ headerLine(_node) {
1888
+ this.attributeList(_node);
1889
+ this.tokenizer.nextToken();
1890
+ }
1891
+ attributeList(_node) {
1892
+ let key, eq;
1893
+ const data = this.getData();
1894
+ while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
1895
+ if (key == null) {
1896
+ key = this.tokenizer.token.value;
1897
+ } else if (eq == null) {
1898
+ eq = '=';
1477
1899
  } else {
1478
- continuousBackslashCount = 0;
1479
- }
1480
- this.i++;
1481
- if (nextC === char && memoCount % 2 === 0) {
1482
- break;
1900
+ const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1901
+ _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 3),
1902
+ hookType = _this$tokenizer$_hook4[0],
1903
+ value = _this$tokenizer$_hook4[1],
1904
+ hookI = _this$tokenizer$_hook4[2];
1905
+ const rawVal = data[aoye.Keys.Raw][value];
1906
+ const isFn = typeof rawVal === 'function';
1907
+ if (hookType === 'dynamic') {
1908
+ const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1909
+ const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
1910
+ this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
1911
+ } else if (hookType === 'static') {
1912
+ this.onePropParsed(data, _node, key, value, false, isFn, hookI);
1913
+ } else {
1914
+ this.onePropParsed(data, _node, key, value, false, isFn, hookI);
1915
+ }
1916
+ key = null;
1917
+ eq = null;
1483
1918
  }
1484
- value += nextC;
1919
+ this.tokenizer.nextToken();
1485
1920
  }
1486
- this.setToken(TokenType.Identifier, value);
1487
1921
  }
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++;
1922
+ config(opt) {
1923
+ Object.assign(this, opt);
1924
+ this.opt = opt;
1925
+ }
1926
+ createNode(name) {
1927
+ return {
1928
+ name,
1929
+ props: {},
1930
+ nextSibling: null
1931
+ };
1932
+ }
1933
+ nextSib(node) {
1934
+ return node.nextSibling;
1935
+ }
1936
+ firstChild(node) {
1937
+ return node.firstChild;
1938
+ }
1939
+ createAnchor(name) {
1940
+ return {
1941
+ name,
1942
+ nextSibling: null
1943
+ };
1944
+ }
1945
+ insertAfter(parent, node, prev) {
1946
+ return this.defaultInsert(parent, node, prev);
1947
+ }
1948
+ defaultInsert(parent, node, prev) {
1949
+ if (prev) {
1950
+ const next = prev.nextSibling;
1951
+ prev.nextSibling = node;
1952
+ node.nextSibling = next;
1953
+ } else {
1954
+ const next = parent.firstChild;
1955
+ parent.firstChild = node;
1956
+ node.nextSibling = next;
1498
1957
  }
1499
- this.setToken(TokenType.Identifier, Number(value));
1500
1958
  }
1501
- eof() {
1502
- this.setToken(TokenType.Eof, 'End Of File');
1959
+ remove(node, parent, prev) {
1960
+ return this.defaultRemove(node, parent, prev);
1503
1961
  }
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];
1962
+ defaultRemove(node, parent, prevSibling) {
1963
+ const next = node.nextSibling;
1964
+ if (prevSibling) {
1965
+ prevSibling.nextSibling = next;
1521
1966
  }
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]);
1967
+ if (parent.firstChild === node) {
1968
+ parent.firstChild = next;
1534
1969
  }
1535
1970
  }
1971
+ setProp(node, key, value, hookI) {
1972
+ node.props[key] = value;
1973
+ }
1536
1974
  }
1537
1975
 
1538
1976
  function bobe(fragments, ...values) {
@@ -1565,6 +2003,9 @@ function customRender(option) {
1565
2003
  };
1566
2004
  }
1567
2005
 
2006
+ exports.Compiler = Compiler;
2007
+ exports.NodeType = NodeType;
2008
+ exports.Tokenizer = Tokenizer;
1568
2009
  exports.bobe = bobe;
1569
2010
  exports.customRender = customRender;
1570
2011
  Object.keys(aoye).forEach(function (k) {