@bablr/bablr-vm 0.20.1 → 0.22.0
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/lib/context.js +9 -8
- package/lib/evaluate.js +329 -159
- package/lib/match.js +278 -115
- package/lib/node.js +123 -120
- package/lib/source.js +111 -114
- package/lib/spans.js +1 -4
- package/lib/state.js +184 -223
- package/lib/utils/pattern.js +116 -18
- package/package.json +8 -8
- package/lib/utils/array.js +0 -13
- package/lib/utils/format.js +0 -9
- package/lib/utils/object.js +0 -97
- package/lib/utils/pump.js +0 -20
- package/lib/utils/token.js +0 -30
package/lib/state.js
CHANGED
|
@@ -1,40 +1,46 @@
|
|
|
1
|
+
import { agast as createAgast, TagPathFacade as TagPath } from '@bablr/agast-vm';
|
|
1
2
|
import emptyStack from '@iter-tools/imm-stack';
|
|
2
3
|
import { WeakStackFrame } from '@bablr/weak-stack';
|
|
3
|
-
import { getCooked } from '@bablr/agast-helpers/stream';
|
|
4
|
+
import { getCooked, maybeWait } from '@bablr/agast-helpers/stream';
|
|
5
|
+
import * as Tags from '@bablr/agast-helpers/tags';
|
|
4
6
|
import { reifyExpression } from '@bablr/agast-vm-helpers';
|
|
5
7
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
EmbeddedRegex,
|
|
8
|
+
Matcher,
|
|
9
|
+
Node,
|
|
10
|
+
Regex,
|
|
10
11
|
GapTag,
|
|
11
12
|
InitializerTag,
|
|
12
13
|
OpenNodeTag,
|
|
13
14
|
ReferenceTag,
|
|
14
15
|
ShiftTag,
|
|
16
|
+
Property,
|
|
17
|
+
BindingTag,
|
|
18
|
+
PropertyWrapper,
|
|
15
19
|
} from '@bablr/agast-vm-helpers/symbols';
|
|
16
|
-
import * as btree from '@bablr/agast-helpers/btree';
|
|
17
|
-
import * as sumtree from '@bablr/agast-helpers/sumtree';
|
|
18
20
|
import {
|
|
19
|
-
|
|
21
|
+
buildBindingTag,
|
|
22
|
+
buildChild,
|
|
20
23
|
buildInitializerTag,
|
|
21
24
|
buildNullNode,
|
|
25
|
+
buildProperty,
|
|
26
|
+
buildPropertyWrapper,
|
|
22
27
|
buildReferenceTag,
|
|
23
|
-
|
|
28
|
+
getOr,
|
|
29
|
+
multiFragmentFlags,
|
|
24
30
|
} from '@bablr/agast-helpers/tree';
|
|
25
|
-
import { getShifted, TagPath } from '@bablr/agast-helpers/path';
|
|
26
31
|
import { match, guardWithPattern } from './utils/pattern.js';
|
|
27
32
|
import { facades, actuals } from './facades.js';
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
33
|
+
import { FragmentFacade } from './node.js';
|
|
34
|
+
import { wrapperIsFull } from '@bablr/agast-helpers/path';
|
|
30
35
|
|
|
31
|
-
const {
|
|
36
|
+
const { freeze } = Object;
|
|
32
37
|
|
|
33
38
|
export const nodeStates = new WeakMap();
|
|
34
39
|
|
|
35
40
|
export const StateFacade = class BABLRStateFacade {
|
|
36
41
|
constructor(state) {
|
|
37
42
|
facades.set(state, this);
|
|
43
|
+
freeze(this);
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
static from(source) {
|
|
@@ -57,38 +63,34 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
57
63
|
return actuals.get(this).result;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
get
|
|
61
|
-
return actuals.get(this).
|
|
66
|
+
get referenceTag() {
|
|
67
|
+
return actuals.get(this).referenceTag;
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
get
|
|
65
|
-
return actuals.get(this).
|
|
70
|
+
get referenceTagPath() {
|
|
71
|
+
return actuals.get(this).referenceTagPath;
|
|
66
72
|
}
|
|
67
73
|
|
|
68
|
-
get
|
|
69
|
-
return actuals.get(this).
|
|
74
|
+
get referencePath() {
|
|
75
|
+
return actuals.get(this).referencePath;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
get holding() {
|
|
73
79
|
return actuals.get(this).holding;
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
get path() {
|
|
77
|
-
return actuals.get(this).path;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
82
|
get language() {
|
|
81
83
|
return actuals.get(this).language;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
get depths() {
|
|
85
|
-
const { path, result } = actuals.get(this).depths;
|
|
86
|
-
return { path, result };
|
|
87
|
+
const { path, result, shift, nodeShift } = actuals.get(this).depths;
|
|
88
|
+
return { path, result, shift, nodeShift };
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
get held() {
|
|
90
92
|
const { held } = actuals.get(this);
|
|
91
|
-
return held && FragmentFacade.wrapNode(held, this.ctx);
|
|
93
|
+
return held && FragmentFacade.wrapNode(held.node, this.ctx);
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
get node() {
|
|
@@ -129,11 +131,11 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
129
131
|
expressions = emptyStack,
|
|
130
132
|
balanced = emptyStack,
|
|
131
133
|
spans = emptyStack.push({ name: 'Bare' }),
|
|
132
|
-
|
|
134
|
+
referenceTagPath = null,
|
|
133
135
|
resultPath = null,
|
|
134
|
-
depths = { path: -1, result: -1, emitted: -1 },
|
|
136
|
+
depths = { path: -1, result: -1, emitted: -1, shift: 0, nodeShift: 0 },
|
|
135
137
|
held = null,
|
|
136
|
-
|
|
138
|
+
agast = null,
|
|
137
139
|
) {
|
|
138
140
|
super(parent);
|
|
139
141
|
|
|
@@ -145,11 +147,11 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
145
147
|
this.expressions = expressions;
|
|
146
148
|
this.balanced = balanced;
|
|
147
149
|
this.spans = spans;
|
|
148
|
-
this.
|
|
150
|
+
this.referenceTagPath = referenceTagPath;
|
|
149
151
|
this.resultPath = resultPath;
|
|
150
152
|
this.depths = depths;
|
|
151
153
|
this.held = held;
|
|
152
|
-
this.
|
|
154
|
+
this.agast = agast;
|
|
153
155
|
|
|
154
156
|
this.status = 'active';
|
|
155
157
|
|
|
@@ -159,33 +161,38 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
static from(source, context, language, expressions = []) {
|
|
162
|
-
return State.create(
|
|
164
|
+
return State.create(
|
|
165
|
+
source,
|
|
166
|
+
context,
|
|
167
|
+
language,
|
|
168
|
+
emptyStack.push(...emptyStack.push(...expressions).valuesReverse()),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get node() {
|
|
173
|
+
return this.agast?.state.node;
|
|
163
174
|
}
|
|
164
175
|
|
|
165
|
-
get
|
|
166
|
-
let refPath = this.
|
|
176
|
+
get referencePath() {
|
|
177
|
+
let refPath = this.referenceTagPath;
|
|
167
178
|
|
|
168
179
|
if (!refPath) return null;
|
|
169
180
|
|
|
170
181
|
let { previousSibling } = refPath;
|
|
171
182
|
let isShift = previousSibling.tag.type === ShiftTag;
|
|
172
183
|
|
|
173
|
-
let
|
|
184
|
+
let referenceTagPath = previousSibling;
|
|
174
185
|
|
|
175
186
|
if (isShift) {
|
|
176
|
-
let refIndex = previousSibling.
|
|
177
|
-
|
|
187
|
+
let refIndex = previousSibling.tagsIndex - 1 - previousSibling.tag.value.index * 3;
|
|
188
|
+
referenceTagPath = previousSibling.siblingAt(refIndex);
|
|
178
189
|
}
|
|
179
|
-
return
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
get undefinedAttributes() {
|
|
183
|
-
return nodeStates.get(this.node).undefinedAttributes;
|
|
190
|
+
return referenceTagPath;
|
|
184
191
|
}
|
|
185
192
|
|
|
186
193
|
get guardedSource() {
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
let { source, span } = this;
|
|
195
|
+
let { guard } = span;
|
|
189
196
|
|
|
190
197
|
return guard ? guardWithPattern(guard, source) : source;
|
|
191
198
|
}
|
|
@@ -195,7 +202,7 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
195
202
|
}
|
|
196
203
|
|
|
197
204
|
get path() {
|
|
198
|
-
|
|
205
|
+
return this.agast?.state.path;
|
|
199
206
|
}
|
|
200
207
|
|
|
201
208
|
get result() {
|
|
@@ -210,8 +217,8 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
210
217
|
return !!this.held;
|
|
211
218
|
}
|
|
212
219
|
|
|
213
|
-
get
|
|
214
|
-
return this.
|
|
220
|
+
get referenceTag() {
|
|
221
|
+
return this.referenceTagPath?.tag;
|
|
215
222
|
}
|
|
216
223
|
|
|
217
224
|
get isGap() {
|
|
@@ -222,64 +229,42 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
222
229
|
return !!this.parent;
|
|
223
230
|
}
|
|
224
231
|
|
|
225
|
-
|
|
226
|
-
const { path, instructionsPump, expressionsPump, agast } = internalStates.get(this.node);
|
|
227
|
-
|
|
228
|
-
if (tag.type === GapTag) {
|
|
229
|
-
expressionsPump.queue(
|
|
230
|
-
this.expressions.size ? this.expressions.value : buildStubNode(buildGapTag()),
|
|
231
|
-
);
|
|
232
|
-
this.expressions = this.expressions.pop();
|
|
233
|
-
}
|
|
234
|
-
instructionsPump.queue(buildCall('advance', buildEmbeddedTag(tag)));
|
|
235
|
-
agast.next();
|
|
236
|
-
|
|
237
|
-
if (tag.type === OpenNodeTag) this.depths.result++;
|
|
238
|
-
if (tag.type === CloseNodeTag) this.depths.result--;
|
|
239
|
-
|
|
240
|
-
this.resultPath = TagPath.from(path, -1);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
guardedMatch(pattern) {
|
|
232
|
+
guardedMatch(pattern, attributes = {}) {
|
|
244
233
|
let { span, source } = this;
|
|
245
234
|
let { guard } = span;
|
|
246
235
|
|
|
247
236
|
let pattern_ = pattern;
|
|
248
|
-
if (pattern.type ===
|
|
237
|
+
if (pattern.type === Matcher) {
|
|
249
238
|
pattern_ = reifyExpression(pattern.value).nodeMatcher;
|
|
250
|
-
} else if (pattern.type ===
|
|
239
|
+
} else if (pattern.type === Regex || pattern.type === Node) {
|
|
251
240
|
pattern_ = pattern.value;
|
|
252
241
|
} else if (typeof pattern !== 'string') {
|
|
253
242
|
throw new Error();
|
|
254
243
|
}
|
|
255
244
|
|
|
256
|
-
|
|
257
|
-
this.resultPath.tag.type === OpenNodeTag && this.resultPath.tag.value.flags.token
|
|
258
|
-
? this.resultPath.node
|
|
259
|
-
: typeof pattern_ === 'string'
|
|
260
|
-
? null
|
|
261
|
-
: pattern_;
|
|
262
|
-
|
|
263
|
-
if (
|
|
264
|
-
span.type === 'Lexical' &&
|
|
265
|
-
openNode &&
|
|
266
|
-
(openNode.flags.token
|
|
267
|
-
? openNode.attributes.balancer || openNode.attributes.balanced
|
|
268
|
-
: openNode.attributes?.balancer)
|
|
269
|
-
) {
|
|
245
|
+
if (span.type === 'Lexical' && attributes.balancer) {
|
|
270
246
|
// also check that the open node starts a lexical span?
|
|
271
247
|
guard = null;
|
|
272
248
|
}
|
|
273
249
|
|
|
274
|
-
if (pattern_?.
|
|
275
|
-
pattern_ = pattern_.
|
|
250
|
+
if (pattern_?.literalValue) {
|
|
251
|
+
pattern_ = pattern_.literalValue || getCooked(pattern_.tags);
|
|
276
252
|
|
|
277
253
|
if (pattern_.type === Symbol.for('String')) {
|
|
278
254
|
pattern_ = reifyExpression(pattern_);
|
|
279
255
|
}
|
|
280
256
|
}
|
|
281
257
|
|
|
282
|
-
|
|
258
|
+
let guardedSource = guard && guardWithPattern(guard, source);
|
|
259
|
+
|
|
260
|
+
let result = match(pattern_, guardedSource || source);
|
|
261
|
+
|
|
262
|
+
return maybeWait(result, (result) => {
|
|
263
|
+
if (guardedSource && !guardedSource.done) {
|
|
264
|
+
guardedSource.return();
|
|
265
|
+
}
|
|
266
|
+
return result;
|
|
267
|
+
});
|
|
283
268
|
}
|
|
284
269
|
|
|
285
270
|
match(pattern) {
|
|
@@ -287,151 +272,119 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
287
272
|
}
|
|
288
273
|
|
|
289
274
|
branch() {
|
|
290
|
-
|
|
275
|
+
let baseState = this;
|
|
291
276
|
let {
|
|
277
|
+
agast,
|
|
292
278
|
source,
|
|
293
279
|
context,
|
|
294
280
|
balanced,
|
|
295
281
|
spans,
|
|
296
282
|
resultPath,
|
|
297
283
|
depths,
|
|
298
|
-
|
|
284
|
+
referenceTagPath,
|
|
299
285
|
held,
|
|
300
286
|
node,
|
|
301
287
|
language,
|
|
302
288
|
expressions,
|
|
303
289
|
} = baseState;
|
|
304
290
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
isArray ? btree.getSize(internalState.path.node.properties[name]) : null,
|
|
322
|
-
);
|
|
323
|
-
const expr = getShifted(ref.value.index || 0, resolvedPath, node);
|
|
324
|
-
internalState.expressionsPump.queue(expr);
|
|
325
|
-
} else if (tag.type === EmbeddedNode) {
|
|
326
|
-
internalState.expressionsPump.queue(tag.value);
|
|
327
|
-
tag = buildGapTag();
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
internalState.instructionsPump.queue(buildCall('advance', buildEmbeddedTag(tag)));
|
|
331
|
-
internalState.agast.next();
|
|
291
|
+
let newAgast = createAgast(agast.options);
|
|
292
|
+
|
|
293
|
+
let fragRefTag = buildReferenceTag('_', null, false, multiFragmentFlags);
|
|
294
|
+
|
|
295
|
+
if (node.tags.openTag) newAgast.vm.next(node.tags.openTag);
|
|
296
|
+
if (node.tags.childrenNode) {
|
|
297
|
+
let property = buildProperty(fragRefTag.value, null, node.tags.childrenNode);
|
|
298
|
+
newAgast.vm.next(
|
|
299
|
+
buildChild(
|
|
300
|
+
PropertyWrapper,
|
|
301
|
+
buildPropertyWrapper(
|
|
302
|
+
[fragRefTag, buildBindingTag(), buildChild(Property, property)],
|
|
303
|
+
property,
|
|
304
|
+
),
|
|
305
|
+
),
|
|
306
|
+
);
|
|
332
307
|
}
|
|
308
|
+
if (node.tags.closeTag) newAgast.vm.next(node.tags.closeTag);
|
|
333
309
|
|
|
334
|
-
|
|
335
|
-
|
|
310
|
+
let newNode = newAgast.state.node;
|
|
311
|
+
let nodeState = nodeStates.get(node);
|
|
336
312
|
let newResultPath;
|
|
337
313
|
|
|
338
314
|
if (resultPath.path.node === node) {
|
|
339
|
-
newResultPath = TagPath.fromNode(newNode, resultPath.
|
|
315
|
+
newResultPath = TagPath.fromNode(newNode, resultPath.tagsIndex);
|
|
340
316
|
} else {
|
|
341
317
|
newResultPath = resultPath;
|
|
342
318
|
}
|
|
343
319
|
|
|
344
320
|
nodeStates.set(newNode, { ...nodeState });
|
|
345
|
-
internalStates.set(newNode, internalState);
|
|
346
321
|
|
|
347
|
-
|
|
322
|
+
let child = this.push(
|
|
348
323
|
source.branch(),
|
|
349
324
|
context,
|
|
350
325
|
language,
|
|
351
326
|
expressions,
|
|
352
327
|
balanced,
|
|
353
328
|
spans,
|
|
354
|
-
|
|
329
|
+
referenceTagPath,
|
|
355
330
|
newResultPath,
|
|
356
331
|
{ ...depths },
|
|
357
332
|
held,
|
|
358
|
-
|
|
333
|
+
newAgast,
|
|
359
334
|
);
|
|
360
335
|
|
|
361
336
|
return child;
|
|
362
337
|
}
|
|
363
338
|
|
|
364
339
|
accept() {
|
|
365
|
-
|
|
340
|
+
let accepted = this;
|
|
366
341
|
|
|
367
342
|
this.status = 'accepted';
|
|
368
343
|
|
|
369
|
-
|
|
344
|
+
let { parent } = this;
|
|
370
345
|
|
|
371
346
|
if (!parent) {
|
|
372
347
|
throw new Error('accepted the root state');
|
|
373
348
|
}
|
|
374
349
|
|
|
375
350
|
if (parent.depths.path === accepted.depths.path) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const internalState = internalStates.get(parent.node);
|
|
379
|
-
const { path: parentPath } = internalState;
|
|
351
|
+
let parentChildren = parent.node.tags;
|
|
380
352
|
|
|
381
353
|
if (parent.node.type !== accepted.node.type) throw new Error();
|
|
382
354
|
|
|
383
|
-
|
|
384
|
-
let i = sumtree.getSize(parentChildren);
|
|
385
|
-
i < sumtree.getSize(accepted.node.children);
|
|
386
|
-
i++
|
|
387
|
-
) {
|
|
388
|
-
let tag = sumtree.getAt(i, accepted.node.children);
|
|
389
|
-
|
|
390
|
-
if (tag.type === GapTag) {
|
|
391
|
-
let previousSibling = sumtree.getAt(i - 1, accepted.node.children);
|
|
392
|
-
let isShift = previousSibling.type === ShiftTag;
|
|
393
|
-
let reference = previousSibling;
|
|
394
|
-
|
|
395
|
-
if (isShift) {
|
|
396
|
-
reference = sumtree.getAt(
|
|
397
|
-
i - 1 - previousSibling.value.index * 2,
|
|
398
|
-
accepted.node.children,
|
|
399
|
-
);
|
|
400
|
-
}
|
|
355
|
+
let lastParentProp = parentChildren.at(-1);
|
|
401
356
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
);
|
|
409
|
-
const expr = getShifted(
|
|
410
|
-
isShift ? previousSibling.value.index : null,
|
|
411
|
-
resolvedPath,
|
|
412
|
-
accepted.node,
|
|
413
|
-
);
|
|
414
|
-
internalState.expressionsPump.queue(expr);
|
|
415
|
-
} else if (tag.type === EmbeddedNode) {
|
|
416
|
-
internalState.expressionsPump.queue(tag.value);
|
|
417
|
-
tag = buildGapTag();
|
|
418
|
-
}
|
|
357
|
+
let partialOffset =
|
|
358
|
+
lastParentProp.type === PropertyWrapper && !wrapperIsFull(lastParentProp) ? -1 : 0;
|
|
359
|
+
|
|
360
|
+
for (let i = parentChildren.size + partialOffset; i < accepted.node.tags.size; i++) {
|
|
361
|
+
let acceptedTag = accepted.node.tags.at(i);
|
|
362
|
+
let tag = parentChildren.at(i);
|
|
419
363
|
|
|
420
|
-
|
|
421
|
-
|
|
364
|
+
// let wrapperTag =
|
|
365
|
+
|
|
366
|
+
for (
|
|
367
|
+
let i = tag ? Tags.getSize(tag.value.tags) : 0;
|
|
368
|
+
i < Tags.getSize(acceptedTag.value.tags);
|
|
369
|
+
i++
|
|
370
|
+
) {
|
|
371
|
+
let tag = Tags.getAt(i, acceptedTag.value.tags);
|
|
372
|
+
|
|
373
|
+
parent.agast.vm.next(tag);
|
|
374
|
+
}
|
|
422
375
|
}
|
|
423
376
|
}
|
|
424
377
|
|
|
425
378
|
parent.spans = accepted.spans;
|
|
426
379
|
parent.balanced = accepted.balanced;
|
|
427
|
-
parent.
|
|
380
|
+
parent.referenceTagPath = accepted.referenceTagPath;
|
|
428
381
|
parent.held = accepted.held;
|
|
429
382
|
parent.depths = accepted.depths;
|
|
430
383
|
parent.language = accepted.language;
|
|
431
384
|
parent.expressions = accepted.expressions;
|
|
432
385
|
|
|
433
386
|
if (parent.depths.result + 1 === accepted.depths.result) {
|
|
434
|
-
parent.resultPath = parent.resultPath.siblingAt(accepted.resultPath.
|
|
387
|
+
parent.resultPath = parent.resultPath.siblingAt(accepted.resultPath.tagsIndex);
|
|
435
388
|
} else {
|
|
436
389
|
parent.resultPath = accepted.resultPath;
|
|
437
390
|
}
|
|
@@ -453,75 +406,83 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
453
406
|
(!finishedMatch.isNode && !didBranch) ||
|
|
454
407
|
finishedMatch.cover ||
|
|
455
408
|
finishedMatch.effects.success === 'none';
|
|
456
|
-
let shallower =
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
409
|
+
let shallower =
|
|
410
|
+
finishedMatch.coveredBoundary.didShift &&
|
|
411
|
+
finishedMatch.coveredBoundary.shiftMatch.state.depth === this.depth - 2
|
|
412
|
+
? finishedMatch.coveredBoundary.shiftMatch.state
|
|
413
|
+
: this.parent;
|
|
414
|
+
|
|
415
|
+
if (!abandon && shallower) {
|
|
416
|
+
let parentChildren = shallower.node.tags;
|
|
417
|
+
let ourChildren = finishedMatch.fragmentNode.tags;
|
|
418
|
+
let refTag;
|
|
419
|
+
|
|
420
|
+
if (shallower.node.type) {
|
|
464
421
|
if (shallower.node.type !== rejectedState.node.type) throw new Error();
|
|
465
422
|
|
|
466
|
-
for (let i =
|
|
467
|
-
let tag =
|
|
468
|
-
|
|
469
|
-
if ([InitializerTag, GapTag].includes(tag.type)) {
|
|
470
|
-
let previousSibling = sumtree.getAt(i - 1, ourChildren);
|
|
471
|
-
let isShift = previousSibling.type === ShiftTag;
|
|
423
|
+
for (let i = parentChildren.size; i < ourChildren.size; i++) {
|
|
424
|
+
let tag = ourChildren.at(i);
|
|
472
425
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
reference = sumtree.getAt(refIndex, ourChildren);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
let lastParentTag = TagPath.from(internalState.path, -1).tag.type;
|
|
481
|
-
|
|
482
|
-
if (
|
|
483
|
-
!['#', '@'].includes(reference.value.name) &&
|
|
484
|
-
!reference.value.isArray &&
|
|
485
|
-
!hasOwn(shallower.node.properties, reference.value.name) &&
|
|
486
|
-
lastParentTag !== ShiftTag
|
|
487
|
-
) {
|
|
488
|
-
if (lastParentTag !== ReferenceTag) {
|
|
489
|
-
internalState.instructionsPump.queue(
|
|
490
|
-
buildCall('advance', buildEmbeddedTag(reference)),
|
|
491
|
-
);
|
|
492
|
-
internalState.agast.next();
|
|
426
|
+
if (tag.type === PropertyWrapper) {
|
|
427
|
+
for (let wrappedTag of tag.value.tags) {
|
|
428
|
+
if (wrappedTag.type === ReferenceTag) {
|
|
429
|
+
refTag = wrappedTag;
|
|
493
430
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
431
|
+
|
|
432
|
+
if ([InitializerTag, GapTag].includes(wrappedTag.type)) {
|
|
433
|
+
let previousSibling = ourChildren.at(i, 0);
|
|
434
|
+
let isShift = previousSibling.type === ShiftTag;
|
|
435
|
+
|
|
436
|
+
let referenceTag = previousSibling;
|
|
437
|
+
|
|
438
|
+
if (isShift) {
|
|
439
|
+
let refIndex = i - 1 - previousSibling.value.index;
|
|
440
|
+
referenceTag = ourChildren.at(refIndex, 0);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (
|
|
444
|
+
!['#', '@'].includes(referenceTag.value.type) &&
|
|
445
|
+
!referenceTag.value.isArray &&
|
|
446
|
+
getOr(0, referenceTag.value.name, shallower.node) === 0 &&
|
|
447
|
+
refTag !== ShiftTag
|
|
448
|
+
) {
|
|
449
|
+
if (refTag !== ReferenceTag) {
|
|
450
|
+
shallower.agast.vm.next(refTag);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
if (bind || wrappedTag.type === GapTag) {
|
|
454
|
+
shallower.agast.vm.next(
|
|
455
|
+
buildChild(Property, buildProperty(refTag.value, null, buildNullNode())),
|
|
456
|
+
);
|
|
457
|
+
} else {
|
|
458
|
+
shallower.agast.vm.next(wrappedTag);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
refTag = null;
|
|
501
462
|
}
|
|
502
|
-
internalState.agast.next();
|
|
503
463
|
}
|
|
504
464
|
}
|
|
505
465
|
}
|
|
506
466
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
if (!ref.value.flags.expression) {
|
|
518
|
-
internalState.instructionsPump.queue(
|
|
519
|
-
buildCall('advance', buildEmbeddedTag(buildInitializerTag(ref.value.isArray))),
|
|
467
|
+
if (refTag?.type === ReferenceTag) {
|
|
468
|
+
if (
|
|
469
|
+
refTag.value.name &&
|
|
470
|
+
!refTag.value.isArray &&
|
|
471
|
+
!shallower.node.properties.has(refTag.value.name)
|
|
472
|
+
) {
|
|
473
|
+
if (bind) {
|
|
474
|
+
shallower.agast.vm.next(refTag);
|
|
475
|
+
shallower.agast.vm.next(
|
|
476
|
+
buildChild(Property, buildProperty(refTag.value, [], buildNullNode())),
|
|
520
477
|
);
|
|
521
|
-
|
|
478
|
+
} else {
|
|
479
|
+
if (!refTag.value.flags.expression) {
|
|
480
|
+
shallower.agast.vm.next(refTag);
|
|
481
|
+
shallower.agast.vm.next(buildInitializerTag(refTag.value.isArray));
|
|
482
|
+
}
|
|
522
483
|
}
|
|
523
484
|
}
|
|
524
|
-
shallower.
|
|
485
|
+
shallower.referenceTagPath = null;
|
|
525
486
|
shallower.resultPath = TagPath.fromNode(shallower.node, -1);
|
|
526
487
|
}
|
|
527
488
|
}
|