@bablr/bablr-vm 0.22.1 → 0.23.1
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 +2 -44
- package/lib/evaluate.js +147 -378
- package/lib/facades.js +34 -0
- package/lib/match.js +468 -325
- package/lib/source.js +9 -58
- package/lib/spans.js +29 -68
- package/lib/state.js +58 -336
- package/lib/utils/pattern.js +58 -28
- package/package.json +11 -8
- package/lib/node.js +0 -327
package/lib/state.js
CHANGED
|
@@ -1,141 +1,27 @@
|
|
|
1
|
-
import { agast as createAgast, TagPathFacade as TagPath } from '@bablr/agast-vm';
|
|
2
1
|
import emptyStack from '@iter-tools/imm-stack';
|
|
3
2
|
import { WeakStackFrame } from '@bablr/weak-stack';
|
|
4
3
|
import { getCooked, maybeWait } from '@bablr/agast-helpers/stream';
|
|
5
|
-
import * as
|
|
4
|
+
import * as BTree from '@bablr/agast-helpers/btree';
|
|
6
5
|
import { reifyExpression } from '@bablr/agast-vm-helpers';
|
|
7
|
-
import {
|
|
8
|
-
Matcher,
|
|
9
|
-
Node,
|
|
10
|
-
Regex,
|
|
11
|
-
GapTag,
|
|
12
|
-
InitializerTag,
|
|
13
|
-
OpenNodeTag,
|
|
14
|
-
ReferenceTag,
|
|
15
|
-
ShiftTag,
|
|
16
|
-
Property,
|
|
17
|
-
BindingTag,
|
|
18
|
-
PropertyWrapper,
|
|
19
|
-
} from '@bablr/agast-vm-helpers/symbols';
|
|
20
|
-
import {
|
|
21
|
-
buildBindingTag,
|
|
22
|
-
buildChild,
|
|
23
|
-
buildInitializerTag,
|
|
24
|
-
buildNullNode,
|
|
25
|
-
buildProperty,
|
|
26
|
-
buildPropertyWrapper,
|
|
27
|
-
buildReferenceTag,
|
|
28
|
-
getOr,
|
|
29
|
-
multiFragmentFlags,
|
|
30
|
-
} from '@bablr/agast-helpers/tree';
|
|
6
|
+
import { Matcher, Node, Regex, ShiftTag } from '@bablr/agast-vm-helpers/symbols';
|
|
31
7
|
import { match, guardWithPattern } from './utils/pattern.js';
|
|
32
|
-
import {
|
|
33
|
-
import { FragmentFacade } from './node.js';
|
|
34
|
-
import { wrapperIsFull } from '@bablr/agast-helpers/path';
|
|
35
|
-
|
|
36
|
-
const { freeze } = Object;
|
|
8
|
+
import { getOpenTag } from '@bablr/agast-helpers/path';
|
|
37
9
|
|
|
38
10
|
export const nodeStates = new WeakMap();
|
|
39
11
|
|
|
40
|
-
export const StateFacade = class BABLRStateFacade {
|
|
41
|
-
constructor(state) {
|
|
42
|
-
facades.set(state, this);
|
|
43
|
-
freeze(this);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
static from(source) {
|
|
47
|
-
return State.from(actuals.get(source));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get ctx() {
|
|
51
|
-
return actuals.get(this).context;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get span() {
|
|
55
|
-
return actuals.get(this).span.name;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get resultPath() {
|
|
59
|
-
return actuals.get(this).resultPath;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get result() {
|
|
63
|
-
return actuals.get(this).result;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get referenceTag() {
|
|
67
|
-
return actuals.get(this).referenceTag;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get referenceTagPath() {
|
|
71
|
-
return actuals.get(this).referenceTagPath;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
get referencePath() {
|
|
75
|
-
return actuals.get(this).referencePath;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
get holding() {
|
|
79
|
-
return actuals.get(this).holding;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
get language() {
|
|
83
|
-
return actuals.get(this).language;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
get depths() {
|
|
87
|
-
const { path, result, shift, nodeShift } = actuals.get(this).depths;
|
|
88
|
-
return { path, result, shift, nodeShift };
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
get held() {
|
|
92
|
-
const { held } = actuals.get(this);
|
|
93
|
-
return held && FragmentFacade.wrapNode(held.node, this.ctx);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
get node() {
|
|
97
|
-
return FragmentFacade.wrapNode(actuals.get(this).node, this.ctx);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
get parentNode() {
|
|
101
|
-
return FragmentFacade.wrapNode(actuals.get(this).parentNode, this.ctx);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
get source() {
|
|
105
|
-
return facades.get(actuals.get(this).source);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
get depth() {
|
|
109
|
-
return actuals.get(this).depth;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
get status() {
|
|
113
|
-
return actuals.get(this).status;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
get parent() {
|
|
117
|
-
return facades.get(actuals.get(this).parent);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
nodeForPath(path) {
|
|
121
|
-
return actuals.get(this).nodeForPath(path);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
12
|
export const State = class BABLRState extends WeakStackFrame {
|
|
126
13
|
constructor(
|
|
127
14
|
parent,
|
|
128
15
|
source,
|
|
129
16
|
context,
|
|
130
|
-
|
|
17
|
+
languages,
|
|
131
18
|
expressions = emptyStack,
|
|
132
19
|
balanced = emptyStack,
|
|
133
|
-
spans = emptyStack
|
|
134
|
-
referenceTagPath = null,
|
|
20
|
+
spans = emptyStack,
|
|
135
21
|
resultPath = null,
|
|
136
22
|
depths = { path: -1, result: -1, emitted: -1, shift: 0, nodeShift: 0 },
|
|
137
23
|
held = null,
|
|
138
|
-
|
|
24
|
+
node = null,
|
|
139
25
|
) {
|
|
140
26
|
super(parent);
|
|
141
27
|
|
|
@@ -143,51 +29,29 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
143
29
|
|
|
144
30
|
this.source = source;
|
|
145
31
|
this.context = context;
|
|
146
|
-
this.
|
|
32
|
+
this.languages = languages;
|
|
147
33
|
this.expressions = expressions;
|
|
148
34
|
this.balanced = balanced;
|
|
149
35
|
this.spans = spans;
|
|
150
|
-
this.referenceTagPath = referenceTagPath;
|
|
151
36
|
this.resultPath = resultPath;
|
|
152
37
|
this.depths = depths;
|
|
153
38
|
this.held = held;
|
|
154
|
-
this.
|
|
39
|
+
this.node = node;
|
|
155
40
|
|
|
156
41
|
this.status = 'active';
|
|
157
|
-
|
|
158
|
-
this.emitted = null;
|
|
159
|
-
|
|
160
|
-
new StateFacade(this);
|
|
161
42
|
}
|
|
162
43
|
|
|
163
44
|
static from(source, context, language, expressions = []) {
|
|
164
45
|
return State.create(
|
|
165
46
|
source,
|
|
166
47
|
context,
|
|
167
|
-
language,
|
|
48
|
+
BTree.fromValues([language]),
|
|
168
49
|
emptyStack.push(...emptyStack.push(...expressions).valuesReverse()),
|
|
169
50
|
);
|
|
170
51
|
}
|
|
171
52
|
|
|
172
|
-
get
|
|
173
|
-
return this.
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
get referencePath() {
|
|
177
|
-
let refPath = this.referenceTagPath;
|
|
178
|
-
|
|
179
|
-
if (!refPath) return null;
|
|
180
|
-
|
|
181
|
-
let { previousSibling } = refPath;
|
|
182
|
-
let isShift = previousSibling.tag.type === ShiftTag;
|
|
183
|
-
|
|
184
|
-
let referenceTagPath = previousSibling;
|
|
185
|
-
|
|
186
|
-
if (isShift) {
|
|
187
|
-
let refIndex = previousSibling.tagsIndex - 1 - previousSibling.tag.value.index * 3;
|
|
188
|
-
referenceTagPath = previousSibling.siblingAt(refIndex);
|
|
189
|
-
}
|
|
190
|
-
return referenceTagPath;
|
|
53
|
+
get language() {
|
|
54
|
+
return BTree.getAt(-1, this.languages);
|
|
191
55
|
}
|
|
192
56
|
|
|
193
57
|
get guardedSource() {
|
|
@@ -201,67 +65,70 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
201
65
|
return this.spans.value;
|
|
202
66
|
}
|
|
203
67
|
|
|
204
|
-
get path() {
|
|
205
|
-
return this.agast?.state.path;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
68
|
get result() {
|
|
209
|
-
return this.resultPath
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
get parentNode() {
|
|
213
|
-
throw new Error('not implemented');
|
|
69
|
+
return this.resultPath?.tag;
|
|
214
70
|
}
|
|
215
71
|
|
|
216
72
|
get holding() {
|
|
217
73
|
return !!this.held;
|
|
218
74
|
}
|
|
219
75
|
|
|
220
|
-
get referenceTag() {
|
|
221
|
-
return this.referenceTagPath?.tag;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
get isGap() {
|
|
225
|
-
return this.tag.type === GapTag;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
76
|
get speculative() {
|
|
229
77
|
return !!this.parent;
|
|
230
78
|
}
|
|
231
79
|
|
|
232
|
-
|
|
80
|
+
getPublic() {
|
|
81
|
+
let { languages, spans, depths, held, node, source, result, resultPath, status } = this;
|
|
82
|
+
return {
|
|
83
|
+
languages,
|
|
84
|
+
span: spans.value?.name,
|
|
85
|
+
depths: { ...depths },
|
|
86
|
+
holding: !!held,
|
|
87
|
+
held,
|
|
88
|
+
node,
|
|
89
|
+
atGap: source.atGap,
|
|
90
|
+
done: source.done,
|
|
91
|
+
sourceIndex: source.index,
|
|
92
|
+
result,
|
|
93
|
+
resultPath,
|
|
94
|
+
status,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
guardedMatch(pattern) {
|
|
233
99
|
let { span, source } = this;
|
|
234
100
|
let { guard } = span;
|
|
235
101
|
|
|
102
|
+
let branchedSource = false;
|
|
236
103
|
let pattern_ = pattern;
|
|
237
104
|
if (pattern.type === Matcher) {
|
|
238
|
-
|
|
239
|
-
} else if (pattern.type === Regex || pattern.type === Node) {
|
|
240
|
-
pattern_ = pattern.value;
|
|
241
|
-
} else if (typeof pattern !== 'string') {
|
|
242
|
-
throw new Error();
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (span.type === 'Lexical' && attributes.balancer) {
|
|
246
|
-
// also check that the open node starts a lexical span?
|
|
247
|
-
guard = null;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (pattern_?.literalValue) {
|
|
251
|
-
pattern_ = pattern_.literalValue || getCooked(pattern_.tags);
|
|
105
|
+
let { nodeMatcher } = reifyExpression(pattern.value);
|
|
252
106
|
|
|
253
|
-
if (
|
|
254
|
-
pattern_ =
|
|
107
|
+
if (nodeMatcher?.literalValue) {
|
|
108
|
+
pattern_ = nodeMatcher.literalValue; // || getCooked(pattern_.value.tags);
|
|
109
|
+
} else {
|
|
110
|
+
throw new Error();
|
|
255
111
|
}
|
|
112
|
+
} else if (pattern.type === Node) {
|
|
113
|
+
if (!getOpenTag(pattern.value).value.flags.token) throw new Error();
|
|
114
|
+
|
|
115
|
+
pattern_ = reifyExpression(pattern.value);
|
|
116
|
+
} else if (pattern.type === Regex) {
|
|
117
|
+
pattern_ = pattern.value;
|
|
118
|
+
} else if (pattern.type !== Matcher && typeof pattern !== 'string') {
|
|
119
|
+
throw new Error();
|
|
256
120
|
}
|
|
257
121
|
|
|
258
|
-
let guardedSource = guard
|
|
122
|
+
let guardedSource = guard ? guardWithPattern(guard, source) : source;
|
|
259
123
|
|
|
260
|
-
let result = match(pattern_, guardedSource
|
|
124
|
+
let result = match(pattern_, guardedSource);
|
|
261
125
|
|
|
262
126
|
return maybeWait(result, (result) => {
|
|
263
|
-
if (
|
|
264
|
-
|
|
127
|
+
if (branchedSource) {
|
|
128
|
+
source.release();
|
|
129
|
+
}
|
|
130
|
+
if (guard && !guardedSource.done) {
|
|
131
|
+
return maybeWait(guardedSource.return(), () => result);
|
|
265
132
|
}
|
|
266
133
|
return result;
|
|
267
134
|
});
|
|
@@ -274,63 +141,29 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
274
141
|
branch() {
|
|
275
142
|
let baseState = this;
|
|
276
143
|
let {
|
|
277
|
-
agast,
|
|
278
144
|
source,
|
|
279
145
|
context,
|
|
280
146
|
balanced,
|
|
281
147
|
spans,
|
|
282
148
|
resultPath,
|
|
283
149
|
depths,
|
|
284
|
-
referenceTagPath,
|
|
285
150
|
held,
|
|
286
151
|
node,
|
|
287
|
-
|
|
152
|
+
languages,
|
|
288
153
|
expressions,
|
|
289
154
|
} = baseState;
|
|
290
155
|
|
|
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
|
-
);
|
|
307
|
-
}
|
|
308
|
-
if (node.tags.closeTag) newAgast.vm.next(node.tags.closeTag);
|
|
309
|
-
|
|
310
|
-
let newNode = newAgast.state.node;
|
|
311
|
-
let nodeState = nodeStates.get(node);
|
|
312
|
-
let newResultPath;
|
|
313
|
-
|
|
314
|
-
if (resultPath.path.node === node) {
|
|
315
|
-
newResultPath = TagPath.fromNode(newNode, resultPath.tagsIndex);
|
|
316
|
-
} else {
|
|
317
|
-
newResultPath = resultPath;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
nodeStates.set(newNode, { ...nodeState });
|
|
321
|
-
|
|
322
156
|
let child = this.push(
|
|
323
157
|
source.branch(),
|
|
324
158
|
context,
|
|
325
|
-
|
|
159
|
+
languages,
|
|
326
160
|
expressions,
|
|
327
161
|
balanced,
|
|
328
162
|
spans,
|
|
329
|
-
|
|
330
|
-
newResultPath,
|
|
163
|
+
resultPath,
|
|
331
164
|
{ ...depths },
|
|
332
165
|
held,
|
|
333
|
-
|
|
166
|
+
node,
|
|
334
167
|
);
|
|
335
168
|
|
|
336
169
|
return child;
|
|
@@ -347,40 +180,11 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
347
180
|
throw new Error('accepted the root state');
|
|
348
181
|
}
|
|
349
182
|
|
|
350
|
-
if (parent.depths.path === accepted.depths.path) {
|
|
351
|
-
let parentChildren = parent.node.tags;
|
|
352
|
-
|
|
353
|
-
if (parent.node.type !== accepted.node.type) throw new Error();
|
|
354
|
-
|
|
355
|
-
let lastParentProp = parentChildren.at(-1);
|
|
356
|
-
|
|
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);
|
|
363
|
-
|
|
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
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
183
|
parent.spans = accepted.spans;
|
|
379
184
|
parent.balanced = accepted.balanced;
|
|
380
|
-
parent.referenceTagPath = accepted.referenceTagPath;
|
|
381
185
|
parent.held = accepted.held;
|
|
382
186
|
parent.depths = accepted.depths;
|
|
383
|
-
parent.
|
|
187
|
+
parent.languages = accepted.languages;
|
|
384
188
|
parent.expressions = accepted.expressions;
|
|
385
189
|
|
|
386
190
|
if (parent.depths.result + 1 === accepted.depths.result) {
|
|
@@ -397,97 +201,15 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
397
201
|
return parent;
|
|
398
202
|
}
|
|
399
203
|
|
|
400
|
-
reject(finishedMatch
|
|
401
|
-
let { bind = false } = options;
|
|
204
|
+
reject(finishedMatch) {
|
|
402
205
|
let rejectedState = this;
|
|
403
206
|
|
|
404
|
-
let didBranch = finishedMatch.s !== finishedMatch.parent.state;
|
|
405
|
-
let abandon =
|
|
406
|
-
(!finishedMatch.isNode && !didBranch) ||
|
|
407
|
-
finishedMatch.cover ||
|
|
408
|
-
finishedMatch.effects.success === 'none';
|
|
409
207
|
let shallower =
|
|
410
208
|
finishedMatch.coveredBoundary.didShift &&
|
|
411
209
|
finishedMatch.coveredBoundary.shiftMatch.state.depth === this.depth - 2
|
|
412
210
|
? finishedMatch.coveredBoundary.shiftMatch.state
|
|
413
211
|
: this.parent;
|
|
414
212
|
|
|
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) {
|
|
421
|
-
if (shallower.node.type !== rejectedState.node.type) throw new Error();
|
|
422
|
-
|
|
423
|
-
for (let i = parentChildren.size; i < ourChildren.size; i++) {
|
|
424
|
-
let tag = ourChildren.at(i);
|
|
425
|
-
|
|
426
|
-
if (tag.type === PropertyWrapper) {
|
|
427
|
-
for (let wrappedTag of tag.value.tags) {
|
|
428
|
-
if (wrappedTag.type === ReferenceTag) {
|
|
429
|
-
refTag = wrappedTag;
|
|
430
|
-
}
|
|
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;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
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())),
|
|
477
|
-
);
|
|
478
|
-
} else {
|
|
479
|
-
if (!refTag.value.flags.expression) {
|
|
480
|
-
shallower.agast.vm.next(refTag);
|
|
481
|
-
shallower.agast.vm.next(buildInitializerTag(refTag.value.isArray));
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
shallower.referenceTagPath = null;
|
|
486
|
-
shallower.resultPath = TagPath.fromNode(shallower.node, -1);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
213
|
if (this.status === 'rejected') {
|
|
492
214
|
return shallower;
|
|
493
215
|
}
|
package/lib/utils/pattern.js
CHANGED
|
@@ -4,7 +4,7 @@ import { generateMatches } from '@bablr/regex-vm';
|
|
|
4
4
|
import {
|
|
5
5
|
getStreamIterator,
|
|
6
6
|
maybeWait,
|
|
7
|
-
|
|
7
|
+
printName,
|
|
8
8
|
StreamIterable,
|
|
9
9
|
} from '@bablr/agast-helpers/stream';
|
|
10
10
|
import * as Tags from '@bablr/agast-helpers/tags';
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
buildOpenNodeTag,
|
|
25
25
|
tokenFlags,
|
|
26
26
|
} from '@bablr/agast-helpers/builders';
|
|
27
|
-
import { streamIteratorSymbol } from '@bablr/stream-iterator';
|
|
27
|
+
import { streamIteratorSymbol, wait } from '@bablr/stream-iterator';
|
|
28
28
|
|
|
29
29
|
function* __wrapSource(source) {
|
|
30
30
|
let source_ = source.source || source;
|
|
@@ -36,16 +36,31 @@ function* __wrapSource(source) {
|
|
|
36
36
|
yield '';
|
|
37
37
|
}
|
|
38
38
|
let iter = getStreamIterator(source);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
while (!step.done) {
|
|
42
|
-
yield step.value;
|
|
39
|
+
let step;
|
|
40
|
+
try {
|
|
43
41
|
step = iter.next();
|
|
44
|
-
}
|
|
45
42
|
|
|
46
|
-
|
|
43
|
+
if (step instanceof Promise) {
|
|
44
|
+
step = yield wait(step);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
while (!step.done) {
|
|
48
|
+
yield step.value;
|
|
49
|
+
step = iter.next();
|
|
50
|
+
|
|
51
|
+
if (step instanceof Promise) {
|
|
52
|
+
step = yield wait(step);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
yield Symbol.for('EOS');
|
|
57
|
+
} finally {
|
|
58
|
+
step = iter.return();
|
|
47
59
|
|
|
48
|
-
|
|
60
|
+
if (step instanceof Promise) {
|
|
61
|
+
step = yield wait(step);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
49
64
|
}
|
|
50
65
|
|
|
51
66
|
export const wrapSource = (source) => {
|
|
@@ -73,7 +88,7 @@ const buildFragmentRegex = (frag) => {
|
|
|
73
88
|
buildAlternatives([
|
|
74
89
|
buildAlternative(
|
|
75
90
|
buildElements(
|
|
76
|
-
[...Tags.traverse(frag.tags)].flatMap((tag) => {
|
|
91
|
+
[...Tags.traverse(frag.value.tags)].flatMap((tag) => {
|
|
77
92
|
if (tag.type === LiteralTag) {
|
|
78
93
|
let str = tag.value;
|
|
79
94
|
return [...str].map((chr) => buildToken('Character', chr));
|
|
@@ -110,25 +125,34 @@ const promiseCo = (gen) => {
|
|
|
110
125
|
function* __stringEqual(str, iterable) {
|
|
111
126
|
let strIter = str[Symbol.iterator]();
|
|
112
127
|
let iter = getStreamIterator(iterable);
|
|
128
|
+
let step;
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
130
|
+
try {
|
|
131
|
+
let strStep = strIter.next();
|
|
132
|
+
step = iter.next();
|
|
116
133
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
134
|
+
while (!strStep.done) {
|
|
135
|
+
if (step instanceof Promise) {
|
|
136
|
+
step = yield wait(step);
|
|
137
|
+
}
|
|
121
138
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
139
|
+
if (step.value !== strStep.value) {
|
|
140
|
+
step = iter.return();
|
|
141
|
+
if (step instanceof Promise) {
|
|
142
|
+
step = yield wait(step);
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
126
146
|
|
|
127
|
-
|
|
128
|
-
|
|
147
|
+
strStep = strIter.next();
|
|
148
|
+
step = iter.next();
|
|
149
|
+
}
|
|
150
|
+
} finally {
|
|
151
|
+
step = iter.return();
|
|
152
|
+
if (step instanceof Promise) {
|
|
153
|
+
step = yield wait(step);
|
|
154
|
+
}
|
|
129
155
|
}
|
|
130
|
-
|
|
131
|
-
iter.return();
|
|
132
156
|
return true;
|
|
133
157
|
}
|
|
134
158
|
|
|
@@ -148,13 +172,13 @@ export const match = (pattern, source) => {
|
|
|
148
172
|
}
|
|
149
173
|
|
|
150
174
|
const pattern_ =
|
|
151
|
-
pattern.type === null && pattern.flags.token
|
|
175
|
+
pattern.type === null && pattern.value.flags.token
|
|
152
176
|
? buildFragmentRegex(pattern)
|
|
153
177
|
: isString(pattern)
|
|
154
178
|
? buildStringRegex(pattern)
|
|
155
179
|
: pattern;
|
|
156
180
|
|
|
157
|
-
if (
|
|
181
|
+
if (printName(pattern_.value.name) !== 'Pattern') throw new Error();
|
|
158
182
|
|
|
159
183
|
assertValidRegex(pattern_);
|
|
160
184
|
|
|
@@ -163,9 +187,11 @@ export const match = (pattern, source) => {
|
|
|
163
187
|
const step = iter.next();
|
|
164
188
|
|
|
165
189
|
return maybeWait(step, (step) => {
|
|
190
|
+
if (!step.done && step.value.length > 1) throw new Error('capturing group');
|
|
166
191
|
const result = step.done ? null : step.value[0];
|
|
167
|
-
iter.return()
|
|
168
|
-
|
|
192
|
+
return maybeWait(iter.return(), () => {
|
|
193
|
+
return isEmpty(result) ? null : result;
|
|
194
|
+
});
|
|
169
195
|
});
|
|
170
196
|
};
|
|
171
197
|
|
|
@@ -201,6 +227,10 @@ class GuardedIterator {
|
|
|
201
227
|
this.source.release();
|
|
202
228
|
}
|
|
203
229
|
|
|
230
|
+
release() {
|
|
231
|
+
this.source.release();
|
|
232
|
+
}
|
|
233
|
+
|
|
204
234
|
[streamIteratorSymbol]() {
|
|
205
235
|
return this;
|
|
206
236
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/bablr-vm",
|
|
3
3
|
"description": "A VM for parsing using BABLR languages",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.23.1",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
},
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@bablr/agast-helpers": "0.
|
|
16
|
-
"@bablr/agast-vm": "0.
|
|
17
|
-
"@bablr/agast-vm-helpers": "0.
|
|
15
|
+
"@bablr/agast-helpers": "0.10.0",
|
|
16
|
+
"@bablr/agast-vm": "0.11.0",
|
|
17
|
+
"@bablr/agast-vm-helpers": "0.10.0",
|
|
18
18
|
"@bablr/coroutine": "0.1.0",
|
|
19
|
-
"@bablr/helpers": "0.
|
|
20
|
-
"@bablr/regex-vm": "0.
|
|
21
|
-
"@bablr/stream-iterator": "
|
|
19
|
+
"@bablr/helpers": "0.25.0",
|
|
20
|
+
"@bablr/regex-vm": "0.14.0",
|
|
21
|
+
"@bablr/stream-iterator": "2.0.0",
|
|
22
22
|
"@bablr/weak-stack": "1.0.1",
|
|
23
23
|
"@iter-tools/imm-stack": "1.2.0",
|
|
24
24
|
"iter-tools-es": "7.5.3"
|
|
@@ -32,7 +32,10 @@
|
|
|
32
32
|
"iter-tools-es": "^7.3.1",
|
|
33
33
|
"prettier": "^2.6.2"
|
|
34
34
|
},
|
|
35
|
-
"repository":
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/bablr-lang/bablr-vm.git"
|
|
38
|
+
},
|
|
36
39
|
"homepage": "https://github.com/bablr-lang/bablr-vm",
|
|
37
40
|
"license": "MIT"
|
|
38
41
|
}
|