@bablr/bablr-vm 0.19.1 → 0.20.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 +28 -12
- package/lib/evaluate.js +133 -126
- package/lib/match.js +127 -101
- package/lib/node.js +155 -57
- package/lib/source.js +3 -1
- package/lib/state.js +207 -62
- package/lib/utils/pattern.js +31 -2
- package/package.json +6 -6
- package/lib/strategy.js +0 -327
package/lib/state.js
CHANGED
|
@@ -3,26 +3,32 @@ import { WeakStackFrame } from '@bablr/weak-stack';
|
|
|
3
3
|
import { getCooked } from '@bablr/agast-helpers/stream';
|
|
4
4
|
import { reifyExpression } from '@bablr/agast-vm-helpers';
|
|
5
5
|
import {
|
|
6
|
+
CloseNodeTag,
|
|
6
7
|
EmbeddedMatcher,
|
|
7
8
|
EmbeddedNode,
|
|
8
9
|
EmbeddedRegex,
|
|
9
10
|
GapTag,
|
|
11
|
+
InitializerTag,
|
|
12
|
+
OpenNodeTag,
|
|
10
13
|
ReferenceTag,
|
|
11
14
|
ShiftTag,
|
|
12
|
-
} from '@bablr/agast-helpers/symbols';
|
|
15
|
+
} from '@bablr/agast-vm-helpers/symbols';
|
|
13
16
|
import * as btree from '@bablr/agast-helpers/btree';
|
|
17
|
+
import * as sumtree from '@bablr/agast-helpers/sumtree';
|
|
14
18
|
import {
|
|
15
|
-
buildCall,
|
|
16
|
-
buildEmbeddedRegex,
|
|
17
|
-
buildEmbeddedTag,
|
|
18
19
|
buildGapTag,
|
|
20
|
+
buildInitializerTag,
|
|
21
|
+
buildNullNode,
|
|
19
22
|
buildReferenceTag,
|
|
20
23
|
buildStubNode,
|
|
21
24
|
} from '@bablr/agast-helpers/tree';
|
|
22
|
-
import {
|
|
25
|
+
import { getShifted, TagPath } from '@bablr/agast-helpers/path';
|
|
23
26
|
import { match, guardWithPattern } from './utils/pattern.js';
|
|
24
27
|
import { facades, actuals } from './facades.js';
|
|
25
28
|
import { buildInternalState, FragmentFacade, internalStates } from './node.js';
|
|
29
|
+
import { buildCall, buildEmbeddedTag } from '@bablr/agast-vm-helpers/builders';
|
|
30
|
+
|
|
31
|
+
const { hasOwn } = Object;
|
|
26
32
|
|
|
27
33
|
export const nodeStates = new WeakMap();
|
|
28
34
|
|
|
@@ -47,6 +53,10 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
47
53
|
return actuals.get(this).resultPath;
|
|
48
54
|
}
|
|
49
55
|
|
|
56
|
+
get result() {
|
|
57
|
+
return actuals.get(this).result;
|
|
58
|
+
}
|
|
59
|
+
|
|
50
60
|
get reference() {
|
|
51
61
|
return actuals.get(this).reference;
|
|
52
62
|
}
|
|
@@ -55,6 +65,10 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
55
65
|
return actuals.get(this).referencePath;
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
get unshiftedReferencePath() {
|
|
69
|
+
return actuals.get(this).unshiftedReferencePath;
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
get holding() {
|
|
59
73
|
return actuals.get(this).holding;
|
|
60
74
|
}
|
|
@@ -63,17 +77,26 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
63
77
|
return actuals.get(this).path;
|
|
64
78
|
}
|
|
65
79
|
|
|
80
|
+
get language() {
|
|
81
|
+
return actuals.get(this).language;
|
|
82
|
+
}
|
|
83
|
+
|
|
66
84
|
get depths() {
|
|
67
85
|
const { path, result } = actuals.get(this).depths;
|
|
68
86
|
return { path, result };
|
|
69
87
|
}
|
|
70
88
|
|
|
89
|
+
get held() {
|
|
90
|
+
const { held } = actuals.get(this);
|
|
91
|
+
return held && FragmentFacade.wrapNode(held, this.ctx);
|
|
92
|
+
}
|
|
93
|
+
|
|
71
94
|
get node() {
|
|
72
|
-
return FragmentFacade.
|
|
95
|
+
return FragmentFacade.wrapNode(actuals.get(this).node, this.ctx);
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
get parentNode() {
|
|
76
|
-
return FragmentFacade.
|
|
99
|
+
return FragmentFacade.wrapNode(actuals.get(this).parentNode, this.ctx);
|
|
77
100
|
}
|
|
78
101
|
|
|
79
102
|
get source() {
|
|
@@ -102,6 +125,7 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
102
125
|
parent,
|
|
103
126
|
source,
|
|
104
127
|
context,
|
|
128
|
+
language,
|
|
105
129
|
expressions = emptyStack,
|
|
106
130
|
balanced = emptyStack,
|
|
107
131
|
spans = emptyStack.push({ name: 'Bare' }),
|
|
@@ -117,6 +141,7 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
117
141
|
|
|
118
142
|
this.source = source;
|
|
119
143
|
this.context = context;
|
|
144
|
+
this.language = language;
|
|
120
145
|
this.expressions = expressions;
|
|
121
146
|
this.balanced = balanced;
|
|
122
147
|
this.spans = spans;
|
|
@@ -133,12 +158,29 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
133
158
|
new StateFacade(this);
|
|
134
159
|
}
|
|
135
160
|
|
|
136
|
-
static from(source, context, expressions = []) {
|
|
137
|
-
return State.create(source, context, emptyStack.push(...expressions));
|
|
161
|
+
static from(source, context, language, expressions = []) {
|
|
162
|
+
return State.create(source, context, language, emptyStack.push(...expressions));
|
|
138
163
|
}
|
|
139
164
|
|
|
140
|
-
get
|
|
141
|
-
|
|
165
|
+
get unshiftedReferencePath() {
|
|
166
|
+
let refPath = this.referencePath;
|
|
167
|
+
|
|
168
|
+
if (!refPath) return null;
|
|
169
|
+
|
|
170
|
+
let { previousSibling } = refPath;
|
|
171
|
+
let isShift = previousSibling.tag.type === ShiftTag;
|
|
172
|
+
|
|
173
|
+
let referencePath = previousSibling;
|
|
174
|
+
|
|
175
|
+
if (isShift) {
|
|
176
|
+
let refIndex = previousSibling.childrenIndex - 1 - previousSibling.tag.value.index * 2;
|
|
177
|
+
referencePath = previousSibling.siblingAt(refIndex);
|
|
178
|
+
}
|
|
179
|
+
return referencePath;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
get undefinedAttributes() {
|
|
183
|
+
return nodeStates.get(this.node).undefinedAttributes;
|
|
142
184
|
}
|
|
143
185
|
|
|
144
186
|
get guardedSource() {
|
|
@@ -156,6 +198,10 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
156
198
|
throw new Error('not implemented');
|
|
157
199
|
}
|
|
158
200
|
|
|
201
|
+
get result() {
|
|
202
|
+
return this.resultPath.tag;
|
|
203
|
+
}
|
|
204
|
+
|
|
159
205
|
get parentNode() {
|
|
160
206
|
throw new Error('not implemented');
|
|
161
207
|
}
|
|
@@ -188,6 +234,9 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
188
234
|
instructionsPump.queue(buildCall('advance', buildEmbeddedTag(tag)));
|
|
189
235
|
agast.next();
|
|
190
236
|
|
|
237
|
+
if (tag.type === OpenNodeTag) this.depths.result++;
|
|
238
|
+
if (tag.type === CloseNodeTag) this.depths.result--;
|
|
239
|
+
|
|
191
240
|
this.resultPath = TagPath.from(path, -1);
|
|
192
241
|
}
|
|
193
242
|
|
|
@@ -198,30 +247,31 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
198
247
|
let pattern_ = pattern;
|
|
199
248
|
if (pattern.type === EmbeddedMatcher) {
|
|
200
249
|
pattern_ = reifyExpression(pattern.value).nodeMatcher;
|
|
201
|
-
} else if (pattern.type === EmbeddedRegex) {
|
|
250
|
+
} else if (pattern.type === EmbeddedRegex || pattern.type === EmbeddedNode) {
|
|
202
251
|
pattern_ = pattern.value;
|
|
203
252
|
} else if (typeof pattern !== 'string') {
|
|
204
253
|
throw new Error();
|
|
205
254
|
}
|
|
206
255
|
|
|
256
|
+
let openNode =
|
|
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
|
+
|
|
207
263
|
if (
|
|
208
264
|
span.type === 'Lexical' &&
|
|
209
|
-
|
|
210
|
-
(
|
|
211
|
-
?
|
|
212
|
-
:
|
|
265
|
+
openNode &&
|
|
266
|
+
(openNode.flags.token
|
|
267
|
+
? openNode.attributes.balancer || openNode.attributes.balanced
|
|
268
|
+
: openNode.attributes?.balancer)
|
|
213
269
|
) {
|
|
214
270
|
// also check that the open node starts a lexical span?
|
|
215
271
|
guard = null;
|
|
216
272
|
}
|
|
217
273
|
|
|
218
274
|
if (pattern_?.intrinsicValue) {
|
|
219
|
-
// if (pattern.type === OpenNodeTag) {
|
|
220
|
-
|
|
221
|
-
// // TODO differntiate better between self-closing tags and matchers
|
|
222
|
-
// pattern = pattern.value;
|
|
223
|
-
// }
|
|
224
|
-
|
|
225
275
|
pattern_ = pattern_.intrinsicValue || getCooked(pattern_.children);
|
|
226
276
|
|
|
227
277
|
if (pattern_.type === Symbol.for('String')) {
|
|
@@ -248,31 +298,35 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
248
298
|
referencePath,
|
|
249
299
|
held,
|
|
250
300
|
node,
|
|
301
|
+
language,
|
|
251
302
|
expressions,
|
|
252
303
|
} = baseState;
|
|
253
304
|
|
|
254
|
-
let resolver = new PathResolver();
|
|
255
|
-
|
|
256
305
|
const internalState = buildInternalState();
|
|
257
306
|
|
|
258
|
-
for (let
|
|
307
|
+
for (let tagPath = TagPath.fromNode(node, 0); tagPath; tagPath = tagPath.nextSibling) {
|
|
308
|
+
let { tag } = tagPath;
|
|
309
|
+
|
|
259
310
|
if (tag.type === GapTag) {
|
|
260
|
-
let
|
|
311
|
+
let ref = tagPath.previousSibling.tag;
|
|
312
|
+
let firstRef =
|
|
313
|
+
ref.type === ShiftTag
|
|
314
|
+
? tagPath.siblingAt(tagPath.childrenIndex - ref.value.index * 2 - 1)
|
|
315
|
+
: ref;
|
|
316
|
+
let { name, isArray, flags } = firstRef.value;
|
|
261
317
|
const resolvedPath = buildReferenceTag(
|
|
262
318
|
name,
|
|
263
319
|
isArray,
|
|
264
320
|
flags,
|
|
265
|
-
|
|
321
|
+
isArray ? btree.getSize(internalState.path.node.properties[name]) : null,
|
|
266
322
|
);
|
|
267
|
-
const expr =
|
|
323
|
+
const expr = getShifted(ref.value.index || 0, resolvedPath, node);
|
|
268
324
|
internalState.expressionsPump.queue(expr);
|
|
269
325
|
} else if (tag.type === EmbeddedNode) {
|
|
270
326
|
internalState.expressionsPump.queue(tag.value);
|
|
271
327
|
tag = buildGapTag();
|
|
272
328
|
}
|
|
273
329
|
|
|
274
|
-
resolver.advance(tag);
|
|
275
|
-
|
|
276
330
|
internalState.instructionsPump.queue(buildCall('advance', buildEmbeddedTag(tag)));
|
|
277
331
|
internalState.agast.next();
|
|
278
332
|
}
|
|
@@ -282,7 +336,7 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
282
336
|
let newResultPath;
|
|
283
337
|
|
|
284
338
|
if (resultPath.path.node === node) {
|
|
285
|
-
newResultPath = TagPath.
|
|
339
|
+
newResultPath = TagPath.fromNode(newNode, resultPath.childrenIndex);
|
|
286
340
|
} else {
|
|
287
341
|
newResultPath = resultPath;
|
|
288
342
|
}
|
|
@@ -293,12 +347,13 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
293
347
|
const child = this.push(
|
|
294
348
|
source.branch(),
|
|
295
349
|
context,
|
|
350
|
+
language,
|
|
296
351
|
expressions,
|
|
297
352
|
balanced,
|
|
298
353
|
spans,
|
|
299
354
|
referencePath,
|
|
300
355
|
newResultPath,
|
|
301
|
-
depths,
|
|
356
|
+
{ ...depths },
|
|
302
357
|
held,
|
|
303
358
|
newNode,
|
|
304
359
|
);
|
|
@@ -317,41 +372,45 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
317
372
|
throw new Error('accepted the root state');
|
|
318
373
|
}
|
|
319
374
|
|
|
320
|
-
parent.spans = accepted.spans;
|
|
321
|
-
parent.balanced = accepted.balanced;
|
|
322
|
-
parent.referencePath = accepted.referencePath;
|
|
323
|
-
parent.held = accepted.held;
|
|
324
|
-
parent.depths = accepted.depths;
|
|
325
|
-
parent.expressions = accepted.expressions;
|
|
326
|
-
// do I need this condition?
|
|
327
375
|
if (parent.depths.path === accepted.depths.path) {
|
|
328
376
|
const parentChildren = parent.node.children;
|
|
329
|
-
parent.node.children = parentChildren;
|
|
330
377
|
|
|
331
378
|
const internalState = internalStates.get(parent.node);
|
|
332
379
|
const { path: parentPath } = internalState;
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
380
|
+
|
|
381
|
+
if (parent.node.type !== accepted.node.type) throw new Error();
|
|
382
|
+
|
|
383
|
+
for (
|
|
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);
|
|
337
389
|
|
|
338
390
|
if (tag.type === GapTag) {
|
|
339
|
-
let
|
|
340
|
-
let
|
|
341
|
-
let
|
|
391
|
+
let previousSibling = sumtree.getAt(i - 1, accepted.node.children);
|
|
392
|
+
let isShift = previousSibling.type === ShiftTag;
|
|
393
|
+
let reference = previousSibling;
|
|
342
394
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
395
|
+
if (isShift) {
|
|
396
|
+
reference = sumtree.getAt(
|
|
397
|
+
i - 1 - previousSibling.value.index * 2,
|
|
398
|
+
accepted.node.children,
|
|
399
|
+
);
|
|
400
|
+
}
|
|
346
401
|
|
|
347
402
|
let { name, isArray, flags } = reference.value;
|
|
348
403
|
const resolvedPath = buildReferenceTag(
|
|
349
404
|
name,
|
|
350
405
|
isArray,
|
|
351
406
|
flags,
|
|
352
|
-
isArray ? btree.
|
|
407
|
+
isArray ? btree.getSize(parentPath.node.properties[name]) - (isShift ? 1 : 0) : null,
|
|
408
|
+
);
|
|
409
|
+
const expr = getShifted(
|
|
410
|
+
isShift ? previousSibling.value.index : null,
|
|
411
|
+
resolvedPath,
|
|
412
|
+
accepted.node,
|
|
353
413
|
);
|
|
354
|
-
const expr = get(resolvedPath, accepted.node);
|
|
355
414
|
internalState.expressionsPump.queue(expr);
|
|
356
415
|
} else if (tag.type === EmbeddedNode) {
|
|
357
416
|
internalState.expressionsPump.queue(tag.value);
|
|
@@ -360,16 +419,23 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
360
419
|
|
|
361
420
|
internalState.instructionsPump.queue(buildCall('advance', buildEmbeddedTag(tag)));
|
|
362
421
|
internalState.agast.next();
|
|
363
|
-
|
|
364
|
-
updatePath(parentPath, tag);
|
|
365
422
|
}
|
|
366
423
|
}
|
|
367
424
|
|
|
368
|
-
|
|
369
|
-
|
|
425
|
+
parent.spans = accepted.spans;
|
|
426
|
+
parent.balanced = accepted.balanced;
|
|
427
|
+
parent.referencePath = accepted.referencePath;
|
|
428
|
+
parent.held = accepted.held;
|
|
429
|
+
parent.depths = accepted.depths;
|
|
430
|
+
parent.language = accepted.language;
|
|
431
|
+
parent.expressions = accepted.expressions;
|
|
432
|
+
|
|
433
|
+
if (parent.depths.result + 1 === accepted.depths.result) {
|
|
434
|
+
parent.resultPath = parent.resultPath.siblingAt(accepted.resultPath.childrenIndex);
|
|
370
435
|
} else {
|
|
371
436
|
parent.resultPath = accepted.resultPath;
|
|
372
437
|
}
|
|
438
|
+
if (!parent.resultPath) throw new Error();
|
|
373
439
|
|
|
374
440
|
nodeStates.set(parent.node, nodeStates.get(accepted.node));
|
|
375
441
|
|
|
@@ -378,22 +444,101 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
378
444
|
return parent;
|
|
379
445
|
}
|
|
380
446
|
|
|
381
|
-
reject() {
|
|
382
|
-
|
|
383
|
-
|
|
447
|
+
reject(finishedMatch, options) {
|
|
448
|
+
let { bind = false } = options;
|
|
449
|
+
let rejectedState = this;
|
|
450
|
+
|
|
451
|
+
let didBranch = finishedMatch.s !== finishedMatch.parent.state;
|
|
452
|
+
let abandon =
|
|
453
|
+
(!finishedMatch.isNode && !didBranch) ||
|
|
454
|
+
finishedMatch.cover ||
|
|
455
|
+
finishedMatch.effects.success === 'none';
|
|
456
|
+
let shallower = finishedMatch.didShift ? finishedMatch.shiftMatch.state : this.parent;
|
|
457
|
+
|
|
458
|
+
if (shallower) {
|
|
459
|
+
let parentChildren = shallower.node.children;
|
|
460
|
+
let ourChildren = finishedMatch.fragmentNode.children;
|
|
461
|
+
let internalState = internalStates.get(shallower.node);
|
|
462
|
+
|
|
463
|
+
if (!abandon && shallower.node.type) {
|
|
464
|
+
if (shallower.node.type !== rejectedState.node.type) throw new Error();
|
|
465
|
+
|
|
466
|
+
for (let i = sumtree.getSize(parentChildren); i < sumtree.getSize(ourChildren); i++) {
|
|
467
|
+
let tag = sumtree.getAt(i, ourChildren);
|
|
468
|
+
|
|
469
|
+
if ([InitializerTag, GapTag].includes(tag.type)) {
|
|
470
|
+
let previousSibling = sumtree.getAt(i - 1, ourChildren);
|
|
471
|
+
let isShift = previousSibling.type === ShiftTag;
|
|
472
|
+
|
|
473
|
+
let reference = previousSibling;
|
|
474
|
+
|
|
475
|
+
if (isShift) {
|
|
476
|
+
let refIndex = i - 1 - previousSibling.value.index * 2;
|
|
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();
|
|
493
|
+
}
|
|
494
|
+
if (bind || tag.type === GapTag) {
|
|
495
|
+
internalState.expressionsPump.queue(buildNullNode());
|
|
496
|
+
internalState.instructionsPump.queue(
|
|
497
|
+
buildCall('advance', buildEmbeddedTag(buildGapTag())),
|
|
498
|
+
);
|
|
499
|
+
} else {
|
|
500
|
+
internalState.instructionsPump.queue(buildCall('advance', buildEmbeddedTag(tag)));
|
|
501
|
+
}
|
|
502
|
+
internalState.agast.next();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
let lastParentTagPath = TagPath.fromNode(shallower.node, -1);
|
|
508
|
+
if (lastParentTagPath?.tag.type === ReferenceTag) {
|
|
509
|
+
let ref = lastParentTagPath?.tag;
|
|
510
|
+
if (bind) {
|
|
511
|
+
internalState.expressionsPump.queue(buildNullNode());
|
|
512
|
+
internalState.instructionsPump.queue(
|
|
513
|
+
buildCall('advance', buildEmbeddedTag(buildGapTag())),
|
|
514
|
+
);
|
|
515
|
+
internalState.agast.next();
|
|
516
|
+
} else {
|
|
517
|
+
if (!ref.value.flags.expression) {
|
|
518
|
+
internalState.instructionsPump.queue(
|
|
519
|
+
buildCall('advance', buildEmbeddedTag(buildInitializerTag(ref.value.isArray))),
|
|
520
|
+
);
|
|
521
|
+
internalState.agast.next();
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
shallower.referencePath = null;
|
|
525
|
+
shallower.resultPath = TagPath.fromNode(shallower.node, -1);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
384
529
|
|
|
385
530
|
if (this.status === 'rejected') {
|
|
386
|
-
return
|
|
531
|
+
return shallower;
|
|
387
532
|
}
|
|
388
533
|
|
|
389
534
|
if (this.status !== 'active') throw new Error();
|
|
390
535
|
|
|
391
536
|
this.status = 'rejected';
|
|
392
537
|
|
|
393
|
-
if (!
|
|
538
|
+
if (!shallower) throw new Error('rejected root state');
|
|
394
539
|
|
|
395
540
|
rejectedState.source.reject();
|
|
396
541
|
|
|
397
|
-
return
|
|
542
|
+
return shallower;
|
|
398
543
|
}
|
|
399
544
|
};
|
package/lib/utils/pattern.js
CHANGED
|
@@ -2,15 +2,18 @@ import isString from 'iter-tools-es/methods/is-string';
|
|
|
2
2
|
import isEmpty from 'iter-tools-es/methods/is-empty';
|
|
3
3
|
import { generateMatches } from '@bablr/regex-vm';
|
|
4
4
|
import { getStreamIterator, maybeWait, printType } from '@bablr/agast-helpers/stream';
|
|
5
|
+
import * as sumtree from '@bablr/agast-helpers/sumtree';
|
|
5
6
|
import * as l from '@bablr/agast-vm-helpers/languages';
|
|
6
7
|
import {
|
|
7
8
|
buildAlternative,
|
|
8
9
|
buildAlternatives,
|
|
9
10
|
buildElements,
|
|
10
11
|
buildPattern,
|
|
12
|
+
buildRegexGap,
|
|
11
13
|
buildToken,
|
|
12
14
|
} from '@bablr/helpers/builders';
|
|
13
|
-
import { buildEmbeddedRegex } from '@bablr/agast-helpers/builders';
|
|
15
|
+
import { buildEmbeddedRegex } from '@bablr/agast-vm-helpers/builders';
|
|
16
|
+
import { GapTag, LiteralTag } from '@bablr/agast-helpers/symbols';
|
|
14
17
|
|
|
15
18
|
export const assertValidRegex = (expr) => {
|
|
16
19
|
const { flags } = expr;
|
|
@@ -30,8 +33,34 @@ const buildStringRegex = (str) => {
|
|
|
30
33
|
);
|
|
31
34
|
};
|
|
32
35
|
|
|
36
|
+
const buildFragmentRegex = (frag) => {
|
|
37
|
+
return buildPattern(
|
|
38
|
+
buildAlternatives([
|
|
39
|
+
buildAlternative(
|
|
40
|
+
buildElements(
|
|
41
|
+
[...sumtree.traverse(frag.children)].flatMap((tag) => {
|
|
42
|
+
if (tag.type === LiteralTag) {
|
|
43
|
+
let str = tag.value;
|
|
44
|
+
return [...str].map((chr) => buildToken(l.Regex, 'Character', chr));
|
|
45
|
+
} else if (tag.type === GapTag) {
|
|
46
|
+
return [buildRegexGap()];
|
|
47
|
+
} else {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}),
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
]),
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
33
57
|
export const match = (pattern, source) => {
|
|
34
|
-
const pattern_ =
|
|
58
|
+
const pattern_ =
|
|
59
|
+
pattern.type === null && pattern.flags.token
|
|
60
|
+
? buildFragmentRegex(pattern)
|
|
61
|
+
: isString(pattern)
|
|
62
|
+
? buildStringRegex(pattern)
|
|
63
|
+
: pattern;
|
|
35
64
|
|
|
36
65
|
if (printType(pattern_.type) !== 'Pattern') throw new Error();
|
|
37
66
|
|
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.20.0",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -12,12 +12,12 @@
|
|
|
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.7.0",
|
|
16
|
+
"@bablr/agast-vm": "0.8.0",
|
|
17
|
+
"@bablr/agast-vm-helpers": "0.7.0",
|
|
18
18
|
"@bablr/coroutine": "0.1.0",
|
|
19
|
-
"@bablr/helpers": "0.
|
|
20
|
-
"@bablr/regex-vm": "0.
|
|
19
|
+
"@bablr/helpers": "0.22.0",
|
|
20
|
+
"@bablr/regex-vm": "0.11.0",
|
|
21
21
|
"@bablr/weak-stack": "1.0.0",
|
|
22
22
|
"@iter-tools/imm-stack": "1.1.0",
|
|
23
23
|
"iter-tools-es": "7.5.3"
|