@bablr/bablr-vm 0.20.0 → 0.21.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 +6 -6
- package/lib/evaluate.js +297 -149
- package/lib/match.js +252 -103
- package/lib/node.js +100 -99
- package/lib/source.js +110 -110
- package/lib/state.js +121 -167
- package/lib/utils/pattern.js +80 -13
- package/package.json +7 -7
- 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/evaluate.js
CHANGED
|
@@ -1,35 +1,52 @@
|
|
|
1
1
|
import { Coroutine } from '@bablr/coroutine';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
buildAttributeDefinition,
|
|
4
|
+
buildBindingTag,
|
|
5
|
+
buildChild,
|
|
6
|
+
buildCloseNodeTag,
|
|
7
|
+
buildFacadeProperty,
|
|
8
|
+
buildProperty,
|
|
9
|
+
} from '@bablr/agast-helpers/builders';
|
|
3
10
|
import { getStreamIterator, printType, StreamIterable } from '@bablr/agast-helpers/stream';
|
|
4
|
-
import { formatType } from './utils/format.js';
|
|
5
11
|
import { facades } from './facades.js';
|
|
6
|
-
import {
|
|
12
|
+
import { State } from './state.js';
|
|
7
13
|
import { updateSpans } from './spans.js';
|
|
8
14
|
import {
|
|
9
15
|
OpenNodeTag,
|
|
10
16
|
CloseNodeTag,
|
|
11
17
|
GapTag,
|
|
18
|
+
BindingTag,
|
|
12
19
|
LiteralTag,
|
|
13
20
|
ReferenceTag,
|
|
14
21
|
DoctypeTag,
|
|
15
22
|
NullTag,
|
|
16
23
|
ShiftTag,
|
|
24
|
+
InitializerTag,
|
|
25
|
+
AttributeDefinition,
|
|
26
|
+
Property,
|
|
17
27
|
} from '@bablr/agast-helpers/symbols';
|
|
18
28
|
import * as sym from '@bablr/agast-vm-helpers/symbols';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
29
|
+
import { agast, PathFacade, TagPathFacade as TagPath } from '@bablr/agast-vm';
|
|
30
|
+
import { states } from './node.js';
|
|
31
|
+
import {
|
|
32
|
+
buildOpenNodeTag,
|
|
33
|
+
buildReferenceTag,
|
|
34
|
+
buildStubNode,
|
|
35
|
+
getFlagsWithGap,
|
|
36
|
+
getRoot,
|
|
37
|
+
treeFromStreamSync,
|
|
38
|
+
} from '@bablr/agast-helpers/tree';
|
|
22
39
|
import { getEmbeddedObject, getEmbeddedTag } from '@bablr/agast-vm-helpers/deembed';
|
|
23
40
|
import { Match } from './match.js';
|
|
24
41
|
import { effectsFor, reifyExpression } from '@bablr/agast-vm-helpers';
|
|
25
|
-
import { TagPath } from '@bablr/agast-helpers/path';
|
|
26
42
|
import { getProduction } from '@bablr/helpers/grammar';
|
|
27
|
-
import { buildWriteEffect } from '@bablr/agast-vm-helpers/builders';
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
import { buildEmbeddedNode, buildWriteEffect } from '@bablr/agast-vm-helpers/builders';
|
|
44
|
+
import { has } from '@bablr/agast-helpers/object';
|
|
45
|
+
import { referencesAreEqual } from '@bablr/agast-helpers/path';
|
|
46
|
+
import { isPlainObject } from '@bablr/helpers/object';
|
|
31
47
|
|
|
32
|
-
|
|
48
|
+
const defineAttribute = (m, path, value) => {
|
|
49
|
+
m.agast.vm.next(buildAttributeDefinition(path, value));
|
|
33
50
|
};
|
|
34
51
|
|
|
35
52
|
const getSourceLength = (tags) => {
|
|
@@ -53,6 +70,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
53
70
|
let m = null;
|
|
54
71
|
let language = null;
|
|
55
72
|
let finishedMatch = null;
|
|
73
|
+
let doctype = null;
|
|
56
74
|
|
|
57
75
|
let co = new Coroutine(getStreamIterator(strategy(facades.get(ctx))));
|
|
58
76
|
|
|
@@ -64,6 +82,18 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
64
82
|
}
|
|
65
83
|
|
|
66
84
|
if (co.done) {
|
|
85
|
+
if (!s.source.done) {
|
|
86
|
+
throw new Error(`parse ate ${s.source.index} characters but the input was not consumed`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let { exchange } = s.source;
|
|
90
|
+
|
|
91
|
+
s.source.release();
|
|
92
|
+
|
|
93
|
+
if (exchange && exchange.sources > 0) {
|
|
94
|
+
throw new Error('Source did not close all forks: ' + exchange.sources);
|
|
95
|
+
}
|
|
96
|
+
|
|
67
97
|
return co.value && states.get(co.value).node;
|
|
68
98
|
}
|
|
69
99
|
|
|
@@ -73,24 +103,27 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
73
103
|
const { verb } = instr;
|
|
74
104
|
|
|
75
105
|
switch (verb) {
|
|
76
|
-
case '
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (language !== null) throw new Error();
|
|
106
|
+
case 'write': {
|
|
107
|
+
const { arguments: { 0: text, 1: { value: writeOptions } = {} } = [] } = instr;
|
|
80
108
|
|
|
81
|
-
|
|
109
|
+
if (options.emitEffects) {
|
|
110
|
+
yield buildWriteEffect(text, writeOptions);
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
82
114
|
|
|
83
|
-
|
|
115
|
+
case 'match': {
|
|
116
|
+
let { arguments: { 0: pattern } = [] } = instr;
|
|
84
117
|
|
|
85
|
-
|
|
118
|
+
let result = s.guardedMatch(pattern);
|
|
86
119
|
|
|
87
|
-
if (
|
|
88
|
-
yield
|
|
120
|
+
if (result instanceof Promise) {
|
|
121
|
+
result = yield result;
|
|
89
122
|
}
|
|
90
123
|
|
|
91
|
-
|
|
124
|
+
let node = result && treeFromStreamSync(result);
|
|
92
125
|
|
|
93
|
-
returnValue =
|
|
126
|
+
returnValue = node && buildEmbeddedNode(node);
|
|
94
127
|
break;
|
|
95
128
|
}
|
|
96
129
|
|
|
@@ -100,47 +133,101 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
100
133
|
const tag = getEmbeddedTag(embeddedTags);
|
|
101
134
|
|
|
102
135
|
if (tag.type !== ReferenceTag) {
|
|
103
|
-
s.
|
|
136
|
+
s.referenceTagPath = null;
|
|
104
137
|
}
|
|
105
138
|
|
|
106
|
-
if (
|
|
139
|
+
if (
|
|
140
|
+
!m.isNode &&
|
|
141
|
+
m.coveredBoundary !== m &&
|
|
142
|
+
!((s.holding && tag.type === GapTag) || tag.type === OpenNodeTag)
|
|
143
|
+
) {
|
|
107
144
|
throw new Error('cannot advance inside a cover');
|
|
145
|
+
}
|
|
108
146
|
|
|
109
147
|
switch (tag.type) {
|
|
110
148
|
case DoctypeTag: {
|
|
111
|
-
|
|
112
|
-
s.node.type = null;
|
|
113
|
-
s.node.language = tag.value.attributes.bablrLanguage;
|
|
114
|
-
s.advance(tag);
|
|
115
|
-
|
|
116
|
-
m.setRangePreviousIndex(0);
|
|
149
|
+
doctype = tag;
|
|
117
150
|
break;
|
|
118
151
|
}
|
|
119
152
|
|
|
120
153
|
case ReferenceTag: {
|
|
121
|
-
s.
|
|
154
|
+
if (s.node.type && tag.value.type === '.') throw new Error();
|
|
155
|
+
if (s.held && s.node.children.at(2)?.type === InitializerTag) {
|
|
156
|
+
if (!referencesAreEqual(s.node.children.at(1), tag) || s.node.children.size > 3) {
|
|
157
|
+
throw new Error();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
m.advance(tag, s);
|
|
122
162
|
|
|
123
|
-
s.
|
|
124
|
-
if (s.
|
|
163
|
+
s.referenceTagPath = TagPath.fromNode(s.node, -1);
|
|
164
|
+
if (s.referenceTagPath.tag.type === BindingTag) throw new Error();
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
case ShiftTag: {
|
|
169
|
+
let { index, height } = tag.value;
|
|
170
|
+
let refTag = s.node.children.at(-3);
|
|
171
|
+
let lastShiftTag = refTag;
|
|
172
|
+
|
|
173
|
+
if (refTag.type === ShiftTag) {
|
|
174
|
+
refTag = s.node.children.at(-3 - refTag.value.index * 3);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (refTag.type !== ReferenceTag) throw new Error();
|
|
178
|
+
|
|
179
|
+
s.depths.shift = height;
|
|
180
|
+
s.depths.nodeShift = index;
|
|
181
|
+
|
|
182
|
+
if (index !== (lastShiftTag.type === ShiftTag ? lastShiftTag.value.index + 1 : 1)) {
|
|
183
|
+
throw new Error();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
s.source.shift();
|
|
187
|
+
s.held = buildFacadeProperty(
|
|
188
|
+
refTag.value,
|
|
189
|
+
s.resultPath.tag.value,
|
|
190
|
+
s.resultPath.nextSibling.tag.value.node,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
m.advance(tag, s);
|
|
194
|
+
s.referenceTagPath = TagPath.fromNode(s.node, -1);
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
case BindingTag: {
|
|
199
|
+
m.advance(tag, s);
|
|
200
|
+
|
|
201
|
+
let propertyChild = buildChild(
|
|
202
|
+
sym.Property,
|
|
203
|
+
buildProperty(s.held.reference, tag.value, s.held.node.node),
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
m.agastFragment.vm.next(propertyChild);
|
|
207
|
+
|
|
208
|
+
s.held = null;
|
|
125
209
|
break;
|
|
126
210
|
}
|
|
127
211
|
|
|
128
212
|
case OpenNodeTag: {
|
|
129
213
|
s.depths.path++;
|
|
214
|
+
s.depths.nodeShift = 0;
|
|
130
215
|
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
s.node = m.node;
|
|
216
|
+
if (!m.coveredBoundary.shiftMatch) {
|
|
217
|
+
s.depths.shift = 0;
|
|
135
218
|
}
|
|
136
219
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
220
|
+
s.agast = m.agast;
|
|
221
|
+
|
|
222
|
+
if (s.depths.path === 0) {
|
|
223
|
+
m.advance(doctype);
|
|
141
224
|
}
|
|
142
225
|
|
|
143
|
-
|
|
226
|
+
m.advance(tag, s);
|
|
227
|
+
|
|
228
|
+
if (s.depths.path === 0) {
|
|
229
|
+
m.setRangePreviousIndex(1);
|
|
230
|
+
}
|
|
144
231
|
|
|
145
232
|
if (tag.value.type) {
|
|
146
233
|
updateSpans(m, s.node, 'open');
|
|
@@ -153,41 +240,78 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
153
240
|
const { node } = s;
|
|
154
241
|
|
|
155
242
|
s.depths.path--;
|
|
243
|
+
s.depths.nodeShift = 0;
|
|
244
|
+
s.depths.shift = 0;
|
|
245
|
+
|
|
246
|
+
if (m.rangeInitial.tag.type === ShiftTag) {
|
|
247
|
+
s.depths.nodeShift = m.rangeInitial.tag.value.index;
|
|
248
|
+
s.depths.shift = m.rangeInitial.tag.value.height;
|
|
249
|
+
}
|
|
156
250
|
|
|
157
|
-
if (
|
|
158
|
-
const refPath = m.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
251
|
+
if (node.children.at(0).value.type) {
|
|
252
|
+
const refPath = m.referencePath;
|
|
253
|
+
|
|
254
|
+
m.advance(tag, s);
|
|
255
|
+
let gaplessNode = null;
|
|
256
|
+
|
|
257
|
+
if (refPath?.tag.value.type === '@') {
|
|
258
|
+
let { vm: escapeVm, state: escapeState } = agast();
|
|
259
|
+
|
|
260
|
+
let tagPath = PathFacade.from(node).tagPathAt(0);
|
|
261
|
+
|
|
262
|
+
while (tagPath) {
|
|
263
|
+
let vmReturn = null;
|
|
264
|
+
if (tagPath.tag.type === GapTag) {
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
if (tagPath.tag.type === OpenNodeTag) {
|
|
268
|
+
let { flags, type, attributes } = tagPath.tag.value;
|
|
269
|
+
|
|
270
|
+
if (tagPath.node.flags.hasGap) {
|
|
271
|
+
vmReturn = escapeVm.next(
|
|
272
|
+
buildOpenNodeTag(getFlagsWithGap(flags, false), type, attributes),
|
|
273
|
+
);
|
|
274
|
+
} else {
|
|
275
|
+
vmReturn = escapeVm.next(
|
|
276
|
+
buildChild(
|
|
277
|
+
sym.Property,
|
|
278
|
+
buildProperty(
|
|
279
|
+
tagPath.path.reference.value,
|
|
280
|
+
tagPath.path.referenceTagPath.nextSibling.tag.value,
|
|
281
|
+
tagPath.node.node,
|
|
282
|
+
),
|
|
172
283
|
),
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
284
|
+
);
|
|
285
|
+
tagPath = tagPath.path.tagPathAt(-1).nextUnshifted;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
} else if (tagPath.tag.type === ReferenceTag && tagPath.tag.value.flags.hasGap) {
|
|
289
|
+
let { flags, name, type, isArray, index } = tagPath.tag.value;
|
|
176
290
|
|
|
177
|
-
|
|
291
|
+
flags = getFlagsWithGap(flags, false);
|
|
178
292
|
|
|
179
|
-
|
|
180
|
-
|
|
293
|
+
vmReturn = escapeVm.next(buildReferenceTag(type, name, isArray, flags, index));
|
|
294
|
+
} else {
|
|
295
|
+
vmReturn = escapeVm.next(tagPath.tag);
|
|
296
|
+
}
|
|
181
297
|
|
|
182
|
-
|
|
298
|
+
if (tagPath.tag.type === CloseNodeTag && !tagPath.nextUnshifted) {
|
|
299
|
+
gaplessNode = vmReturn.value;
|
|
300
|
+
}
|
|
183
301
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
302
|
+
tagPath = tagPath.nextUnshifted;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
187
305
|
|
|
188
|
-
s.
|
|
306
|
+
s.agast = m.agastFragment;
|
|
189
307
|
|
|
190
|
-
|
|
308
|
+
s.held = Object.freeze({
|
|
309
|
+
reference: refPath.tag.value,
|
|
310
|
+
binding: null,
|
|
311
|
+
node: gaplessNode || m.node,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
updateSpans(m, s.resultPath.node, 'close');
|
|
191
315
|
|
|
192
316
|
if (!m.parent) {
|
|
193
317
|
if (!s.source.done) {
|
|
@@ -199,8 +323,8 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
199
323
|
}
|
|
200
324
|
}
|
|
201
325
|
} else {
|
|
202
|
-
|
|
203
|
-
s.
|
|
326
|
+
m.advance(tag, s);
|
|
327
|
+
s.agast = m.agastFragment;
|
|
204
328
|
}
|
|
205
329
|
|
|
206
330
|
break;
|
|
@@ -231,7 +355,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
231
355
|
sourceStep = yield sourceStep;
|
|
232
356
|
}
|
|
233
357
|
|
|
234
|
-
|
|
358
|
+
m.advance(tag, s);
|
|
235
359
|
} else {
|
|
236
360
|
throw new Error('Failed to advance literal');
|
|
237
361
|
}
|
|
@@ -251,7 +375,13 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
251
375
|
}
|
|
252
376
|
|
|
253
377
|
if (s.held) {
|
|
254
|
-
|
|
378
|
+
if (!s.agast.state.held) throw new Error();
|
|
379
|
+
s.agast.vm.next(
|
|
380
|
+
buildChild(
|
|
381
|
+
Property,
|
|
382
|
+
buildProperty(m.referencePath.tag.value, null, buildStubNode(tag)),
|
|
383
|
+
),
|
|
384
|
+
);
|
|
255
385
|
|
|
256
386
|
s.resultPath = TagPath.fromNode(s.resultPath.node, -1);
|
|
257
387
|
|
|
@@ -260,55 +390,72 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
260
390
|
}
|
|
261
391
|
|
|
262
392
|
if (s.expressions.size) {
|
|
263
|
-
|
|
393
|
+
let expression = s.expressions.value;
|
|
394
|
+
let node = getRoot(isPlainObject(expression) ? expression : expression.node);
|
|
395
|
+
|
|
396
|
+
let mergedBinding = buildBindingTag(m.mergedLanguagePath);
|
|
264
397
|
|
|
265
|
-
|
|
398
|
+
s.agast.vm.next(mergedBinding);
|
|
399
|
+
s.agast.vm.next(
|
|
400
|
+
buildChild(
|
|
401
|
+
Property,
|
|
402
|
+
buildProperty(s.resultPath.tag.value, mergedBinding.value, node),
|
|
403
|
+
),
|
|
404
|
+
);
|
|
266
405
|
|
|
267
406
|
s.expressions = s.expressions.pop();
|
|
268
407
|
break;
|
|
269
408
|
}
|
|
270
409
|
|
|
271
|
-
if (
|
|
272
|
-
|
|
410
|
+
if (s.node.children.size) {
|
|
411
|
+
m.advance(tag, s);
|
|
273
412
|
} else {
|
|
274
413
|
m.add(m.node);
|
|
275
414
|
|
|
276
|
-
|
|
415
|
+
m.advance(tag, s);
|
|
277
416
|
}
|
|
278
417
|
|
|
279
|
-
s.
|
|
418
|
+
s.referenceTagPath = null;
|
|
280
419
|
|
|
281
|
-
s.
|
|
420
|
+
s.agast = m.agastFragment;
|
|
282
421
|
} else {
|
|
283
422
|
throw new Error('Failed to advance gap');
|
|
284
423
|
}
|
|
285
424
|
break;
|
|
286
425
|
}
|
|
287
426
|
|
|
288
|
-
|
|
289
|
-
s.
|
|
290
|
-
|
|
427
|
+
case InitializerTag: {
|
|
428
|
+
if (s.held && s.node.children.at(2)?.type === InitializerTag) {
|
|
429
|
+
throw new Error();
|
|
430
|
+
}
|
|
431
|
+
m.advance(tag, s);
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
291
434
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
435
|
+
case AttributeDefinition: {
|
|
436
|
+
const { path, value } = tag.value;
|
|
295
437
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
438
|
+
if (!has(m.node.attributes, path)) {
|
|
439
|
+
throw new Error('undefined attributes must be declared');
|
|
440
|
+
}
|
|
299
441
|
|
|
300
|
-
|
|
301
|
-
let { arguments: { 0: pattern } = [] } = instr;
|
|
442
|
+
if (s.held) throw new Error('invalid place for an attribute binding');
|
|
302
443
|
|
|
303
|
-
|
|
444
|
+
if (value && typeof value === 'object') throw new Error('unimplemented');
|
|
304
445
|
|
|
305
|
-
|
|
306
|
-
|
|
446
|
+
defineAttribute(m, path, value);
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
default:
|
|
451
|
+
m.advance(tag, s);
|
|
307
452
|
}
|
|
308
453
|
|
|
309
|
-
|
|
454
|
+
if (s.depth === 0 && (s.node || s.resultPath?.node)) {
|
|
455
|
+
yield* m.emit(options);
|
|
456
|
+
}
|
|
310
457
|
|
|
311
|
-
returnValue =
|
|
458
|
+
returnValue = tag;
|
|
312
459
|
break;
|
|
313
460
|
}
|
|
314
461
|
|
|
@@ -327,6 +474,8 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
327
474
|
case 'branch': {
|
|
328
475
|
s = s.branch();
|
|
329
476
|
|
|
477
|
+
// m.node = s.agast.node;
|
|
478
|
+
|
|
330
479
|
returnValue = facades.get(s);
|
|
331
480
|
break;
|
|
332
481
|
}
|
|
@@ -334,6 +483,10 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
334
483
|
case 'accept': {
|
|
335
484
|
s = s.accept(finishedMatch.fragmentNode);
|
|
336
485
|
|
|
486
|
+
if (s.depth === 0 && (s.node || s.resultPath?.node)) {
|
|
487
|
+
yield* m.emit(options);
|
|
488
|
+
}
|
|
489
|
+
|
|
337
490
|
returnValue = facades.get(s);
|
|
338
491
|
break;
|
|
339
492
|
}
|
|
@@ -351,6 +504,10 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
351
504
|
|
|
352
505
|
s = finishedState.parent;
|
|
353
506
|
|
|
507
|
+
if (s.depth === 0 && (s.node || s.resultPath?.node)) {
|
|
508
|
+
yield* m.emit(options);
|
|
509
|
+
}
|
|
510
|
+
|
|
354
511
|
returnValue = facades.get(s);
|
|
355
512
|
break;
|
|
356
513
|
}
|
|
@@ -361,9 +518,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
361
518
|
} = instr;
|
|
362
519
|
|
|
363
520
|
let effects = effectsFor(verb.description);
|
|
364
|
-
let didShift = verb.description.startsWith('
|
|
365
|
-
|
|
366
|
-
let { undefinedAttributes } = options;
|
|
521
|
+
let didShift = verb.description.startsWith('shift');
|
|
367
522
|
|
|
368
523
|
let parentMatch = m;
|
|
369
524
|
|
|
@@ -391,42 +546,39 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
391
546
|
if (parentMatch && parentMatch.cover && !m.isNode) {
|
|
392
547
|
if (matcher_.refMatcher) {
|
|
393
548
|
let m = matcher_.refMatcher;
|
|
394
|
-
if (
|
|
549
|
+
if (m.type !== '.' || m.flags.expression || m.flags.hasGap || m.isArray) {
|
|
395
550
|
throw new Error('no references inside covers');
|
|
396
551
|
}
|
|
397
552
|
}
|
|
398
553
|
}
|
|
399
554
|
|
|
400
555
|
if (didShift) {
|
|
401
|
-
s.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
let refTag = sumtree.getAt(-2, s.node.children);
|
|
405
|
-
|
|
406
|
-
s.advance(buildShiftTag(refTag.type === ShiftTag ? refTag.value.index + 1 : 1));
|
|
407
|
-
s.referencePath = TagPath.fromNode(s.node, -1);
|
|
556
|
+
if (s.node.children.at(-1)?.type !== ShiftTag) {
|
|
557
|
+
throw new Error('advance shift tag before starting new held frame');
|
|
558
|
+
}
|
|
408
559
|
}
|
|
409
560
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
m.fragmentNode = s.node;
|
|
561
|
+
let broken = !parentMatch || effects.success === 'none' || s.agast.state.node.type === null;
|
|
413
562
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
});
|
|
563
|
+
if (effects.success !== 'none') {
|
|
564
|
+
m.agastFragment = s.agast;
|
|
565
|
+
} else {
|
|
566
|
+
s.agast = m.agastFragment = m.agast;
|
|
567
|
+
s.referenceTagPath = null;
|
|
568
|
+
}
|
|
421
569
|
|
|
422
570
|
({ language } = m);
|
|
423
571
|
|
|
424
|
-
|
|
572
|
+
let offset = m.isNode ? -1 : 0;
|
|
573
|
+
|
|
574
|
+
if (!broken) {
|
|
425
575
|
let previousIndex = [CloseNodeTag, NullTag, GapTag].includes(s.resultPath.tag.type)
|
|
426
|
-
?
|
|
576
|
+
? m.fragmentNode.children.size - 1
|
|
427
577
|
: s.resultPath.childrenIndex;
|
|
428
578
|
|
|
429
|
-
m.setRangePreviousIndex(previousIndex);
|
|
579
|
+
m.setRangePreviousIndex(previousIndex + offset);
|
|
580
|
+
} else if (parentMatch) {
|
|
581
|
+
m.setRangePreviousIndex(m.fragmentNode.children.size - 1 + offset);
|
|
430
582
|
}
|
|
431
583
|
|
|
432
584
|
returnValue = facades.get(m);
|
|
@@ -436,22 +588,23 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
436
588
|
}
|
|
437
589
|
|
|
438
590
|
case 'endFrame': {
|
|
439
|
-
const {
|
|
440
|
-
arguments: { 0: hasContinuation },
|
|
441
|
-
} = instr;
|
|
442
591
|
finishedMatch = m;
|
|
443
592
|
|
|
444
593
|
m = m.endFrame();
|
|
445
594
|
|
|
595
|
+
if (finishedMatch.effects.success !== 'none') {
|
|
596
|
+
s.agast = finishedMatch.agastFragment;
|
|
597
|
+
} else {
|
|
598
|
+
finishedMatch.agastFragment.vm.next(buildCloseNodeTag());
|
|
599
|
+
s.agast = m.agast;
|
|
600
|
+
s.referenceTagPath = m.referencePath;
|
|
601
|
+
}
|
|
602
|
+
|
|
446
603
|
if (!m) {
|
|
447
604
|
returnValue = m;
|
|
448
605
|
break;
|
|
449
606
|
}
|
|
450
607
|
|
|
451
|
-
if (finishedMatch.state.status !== 'rejected') {
|
|
452
|
-
yield* m.emit();
|
|
453
|
-
}
|
|
454
|
-
|
|
455
608
|
returnValue = m && facades.get(m);
|
|
456
609
|
break;
|
|
457
610
|
}
|
|
@@ -461,50 +614,45 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
461
614
|
|
|
462
615
|
m = m.throw_();
|
|
463
616
|
|
|
464
|
-
s.status = 'rejected';
|
|
465
617
|
if (m && finishedMatch.s === s) {
|
|
466
|
-
s.
|
|
618
|
+
s.agast = m.agast;
|
|
467
619
|
}
|
|
468
620
|
|
|
469
621
|
returnValue = m && facades.get(m);
|
|
470
622
|
break;
|
|
471
623
|
}
|
|
472
624
|
|
|
473
|
-
case '
|
|
474
|
-
|
|
625
|
+
case 'getState': {
|
|
626
|
+
returnValue = facades.get(s);
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
475
629
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if (value && typeof value === 'object') throw new Error('unimplemented');
|
|
630
|
+
case 'init': {
|
|
631
|
+
let { arguments: { 0: canonicalURL } = [] } = instr;
|
|
479
632
|
|
|
480
|
-
|
|
633
|
+
if (language !== null) throw new Error();
|
|
481
634
|
|
|
482
|
-
|
|
635
|
+
s = State.from(rootSource, ctx, canonicalURL, options.expressions);
|
|
483
636
|
|
|
484
|
-
|
|
485
|
-
}
|
|
637
|
+
s.source.advance();
|
|
486
638
|
|
|
487
|
-
|
|
488
|
-
const { arguments: { 0: text, 1: { value: writeOptions } = {} } = [] } = instr;
|
|
639
|
+
const sourceStep = s.source.head.step;
|
|
489
640
|
|
|
490
|
-
if (
|
|
491
|
-
yield
|
|
641
|
+
if (sourceStep instanceof Promise) {
|
|
642
|
+
yield sourceStep;
|
|
492
643
|
}
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
495
644
|
|
|
496
|
-
|
|
645
|
+
language = ctx.languages.get(canonicalURL);
|
|
646
|
+
|
|
497
647
|
returnValue = facades.get(s);
|
|
498
648
|
break;
|
|
499
649
|
}
|
|
500
650
|
|
|
501
651
|
default: {
|
|
502
|
-
throw new Error(`Unexpected call of {type: ${
|
|
652
|
+
throw new Error(`Unexpected call of {type: ${printType(verb)}}`);
|
|
503
653
|
}
|
|
504
654
|
}
|
|
505
655
|
|
|
506
656
|
co.advance(returnValue);
|
|
507
657
|
}
|
|
508
|
-
|
|
509
|
-
return s.node;
|
|
510
658
|
}
|