@bablr/bablr-vm 0.23.0 → 0.23.2
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 +14 -21
- package/lib/evaluate.js +36 -42
- package/lib/facades.js +23 -12
- package/lib/match.js +121 -138
- package/lib/state.js +37 -19
- package/package.json +6 -7
package/lib/context.js
CHANGED
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
import { buildDependentLanguages } from '@bablr/helpers/grammar';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export const ContextFacade = class BABLRContextFacade {
|
|
5
|
-
constructor(actual) {
|
|
6
|
-
facades.set(actual, this);
|
|
7
|
-
Object.freeze(this);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
get languages() {
|
|
11
|
-
return actuals.get(this).languages;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
get grammars() {
|
|
15
|
-
return actuals.get(this).grammars;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
get productionEnhancer() {
|
|
19
|
-
return actuals.get(this).productionEnhancer;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
2
|
+
import { getGapNode } from './facades.js';
|
|
22
3
|
|
|
23
4
|
export const Context = class BABLRContext {
|
|
24
5
|
static from(language, productionEnhancer) {
|
|
@@ -28,11 +9,13 @@ export const Context = class BABLRContext {
|
|
|
28
9
|
constructor(languages, productionEnhancer) {
|
|
29
10
|
this.languages = languages;
|
|
30
11
|
this.productionEnhancer = productionEnhancer;
|
|
12
|
+
this.getGrammar = (language) => this.grammars.get(language);
|
|
13
|
+
|
|
14
|
+
Object.freeze(productionEnhancer);
|
|
31
15
|
|
|
32
16
|
this.unboxedValues = new WeakMap();
|
|
33
17
|
|
|
34
18
|
this.grammars = new WeakMap();
|
|
35
|
-
this.facade = new ContextFacade(this);
|
|
36
19
|
|
|
37
20
|
for (const { 1: language } of this.languages) {
|
|
38
21
|
if (!language) throw new Error();
|
|
@@ -40,4 +23,14 @@ export const Context = class BABLRContext {
|
|
|
40
23
|
this.grammars.set(language, new language.grammar());
|
|
41
24
|
}
|
|
42
25
|
}
|
|
26
|
+
|
|
27
|
+
getPublic() {
|
|
28
|
+
let { productionEnhancer, getGrammar } = this;
|
|
29
|
+
|
|
30
|
+
return Object.freeze({
|
|
31
|
+
getGrammar,
|
|
32
|
+
getGapNode,
|
|
33
|
+
productionEnhancer,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
43
36
|
};
|
package/lib/evaluate.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { Coroutine } from '@bablr/coroutine';
|
|
3
3
|
import { buildAttributeDefinition, buildCloseNodeTag } from '@bablr/agast-helpers/builders';
|
|
4
4
|
import { getStreamIterator, printType, StreamIterable, wait } from '@bablr/agast-helpers/stream';
|
|
5
|
-
import { facades } from './facades.js';
|
|
6
5
|
import { State } from './state.js';
|
|
7
6
|
import {
|
|
8
7
|
OpenNodeTag,
|
|
@@ -22,12 +21,8 @@ import { buildWriteEffect } from '@bablr/agast-vm-helpers/builders';
|
|
|
22
21
|
import { has } from '@bablr/agast-helpers/object';
|
|
23
22
|
import { reifyBablrOptions } from '@bablr/agast-vm-helpers';
|
|
24
23
|
import { buildNode, getTags } from '@bablr/agast-helpers/path';
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export const isKnownValid = (language, node) => {
|
|
29
|
-
return !!validNodesByLanguage.get(language)?.has(node);
|
|
30
|
-
};
|
|
24
|
+
import * as BTree from '@bablr/agast-helpers/btree';
|
|
25
|
+
import { resolveLanguage } from '@bablr/helpers/grammar';
|
|
31
26
|
|
|
32
27
|
const getSourceLength = (tags) => {
|
|
33
28
|
let i = 0;
|
|
@@ -41,11 +36,18 @@ const getSourceLength = (tags) => {
|
|
|
41
36
|
return i;
|
|
42
37
|
};
|
|
43
38
|
|
|
44
|
-
export const bablr = (
|
|
45
|
-
|
|
39
|
+
export const bablr = (
|
|
40
|
+
ctx,
|
|
41
|
+
rootSource,
|
|
42
|
+
language,
|
|
43
|
+
strategy,
|
|
44
|
+
options = {},
|
|
45
|
+
registerNode = () => {},
|
|
46
|
+
) => {
|
|
47
|
+
return new StreamIterable(__bablr(ctx, rootSource, language, strategy, options, registerNode));
|
|
46
48
|
};
|
|
47
49
|
|
|
48
|
-
function* __bablr(ctx, rootSource, strategy, options) {
|
|
50
|
+
function* __bablr(ctx, rootSource, rootLanguage, strategy, options, registerNode) {
|
|
49
51
|
let s = null;
|
|
50
52
|
let m = null;
|
|
51
53
|
let finishedMatch = null;
|
|
@@ -53,14 +55,22 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
53
55
|
|
|
54
56
|
let getState = () => s.getPublic();
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
s = State.from(rootSource, ctx, rootLanguage, options.expressions);
|
|
59
|
+
|
|
60
|
+
s.source.advance();
|
|
61
|
+
|
|
62
|
+
if (options.holdUndefinedAttributes) {
|
|
63
|
+
throw new Error('holdUndefinedAttributes not implemented');
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
let co = new Coroutine(getStreamIterator(strategy(
|
|
66
|
+
let co = new Coroutine(getStreamIterator(strategy(ctx.getPublic(), rootLanguage, getState)));
|
|
61
67
|
|
|
62
68
|
co.advance();
|
|
63
69
|
|
|
70
|
+
if (s.source.head.step instanceof Promise) {
|
|
71
|
+
yield wait(s.source.head.step);
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
for (;;) {
|
|
65
75
|
if (co.current instanceof Promise) {
|
|
66
76
|
co.current = yield wait(co.current);
|
|
@@ -71,6 +81,8 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
71
81
|
throw new Error(`parse ate ${s.source.index} characters but the input was not consumed`);
|
|
72
82
|
}
|
|
73
83
|
|
|
84
|
+
if (m) throw new Error();
|
|
85
|
+
|
|
74
86
|
let { exchange } = s.source;
|
|
75
87
|
|
|
76
88
|
s.source.release();
|
|
@@ -79,7 +91,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
79
91
|
throw new Error('Source did not close all forks: ' + exchange.sources);
|
|
80
92
|
}
|
|
81
93
|
|
|
82
|
-
return
|
|
94
|
+
return options.tree === undefined || options.tree ? finishedMatch.node : undefined;
|
|
83
95
|
}
|
|
84
96
|
|
|
85
97
|
const instr = co.value;
|
|
@@ -229,8 +241,6 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
229
241
|
s.node = m.node;
|
|
230
242
|
}
|
|
231
243
|
|
|
232
|
-
validNodesByLanguage.get(language).add(node);
|
|
233
|
-
|
|
234
244
|
break;
|
|
235
245
|
}
|
|
236
246
|
|
|
@@ -347,7 +357,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
347
357
|
|
|
348
358
|
yield* m.emit(outerOptions);
|
|
349
359
|
|
|
350
|
-
returnValue =
|
|
360
|
+
returnValue = m.getPublic();
|
|
351
361
|
break;
|
|
352
362
|
}
|
|
353
363
|
|
|
@@ -359,6 +369,10 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
359
369
|
m = m.endFrame(outerOptions);
|
|
360
370
|
s = m ? m.state : s;
|
|
361
371
|
|
|
372
|
+
if (finishedMatch.isNode) {
|
|
373
|
+
registerNode(m.language, m.node);
|
|
374
|
+
}
|
|
375
|
+
|
|
362
376
|
if (m) {
|
|
363
377
|
m.running = null;
|
|
364
378
|
if (finishedMatch.shiftMatch) {
|
|
@@ -367,7 +381,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
367
381
|
yield* m.emit(outerOptions);
|
|
368
382
|
}
|
|
369
383
|
|
|
370
|
-
returnValue = m &&
|
|
384
|
+
returnValue = m && m.getPublic();
|
|
371
385
|
break;
|
|
372
386
|
}
|
|
373
387
|
|
|
@@ -377,7 +391,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
377
391
|
|
|
378
392
|
let parentMatch = m;
|
|
379
393
|
|
|
380
|
-
if (finishedMatch.type
|
|
394
|
+
if (finishedMatch.type === '__') throw new Error();
|
|
381
395
|
|
|
382
396
|
m = Match.startFrame(
|
|
383
397
|
ctx,
|
|
@@ -395,7 +409,7 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
395
409
|
|
|
396
410
|
yield* finishedMatch.emit(outerOptions);
|
|
397
411
|
|
|
398
|
-
returnValue = m &&
|
|
412
|
+
returnValue = m && m.getPublic();
|
|
399
413
|
break;
|
|
400
414
|
}
|
|
401
415
|
|
|
@@ -410,32 +424,12 @@ function* __bablr(ctx, rootSource, strategy, options) {
|
|
|
410
424
|
s = m.state;
|
|
411
425
|
}
|
|
412
426
|
|
|
413
|
-
returnValue = m &&
|
|
427
|
+
returnValue = m && m.getPublic();
|
|
414
428
|
break;
|
|
415
429
|
}
|
|
416
430
|
|
|
417
431
|
case 'getState': {
|
|
418
|
-
returnValue =
|
|
419
|
-
break;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
case 'init': {
|
|
423
|
-
let { arguments: { 0: canonicalURL } = [] } = instr;
|
|
424
|
-
|
|
425
|
-
if (s !== null) throw new Error();
|
|
426
|
-
|
|
427
|
-
// TODO get rid of ctx.languages
|
|
428
|
-
s = State.from(rootSource, ctx, ctx.languages.get(canonicalURL), options.expressions);
|
|
429
|
-
|
|
430
|
-
s.source.advance();
|
|
431
|
-
|
|
432
|
-
const sourceStep = s.source.head.step;
|
|
433
|
-
|
|
434
|
-
if (sourceStep instanceof Promise) {
|
|
435
|
-
yield wait(sourceStep);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
returnValue = facades.get(s);
|
|
432
|
+
returnValue = s.getPublic();
|
|
439
433
|
break;
|
|
440
434
|
}
|
|
441
435
|
|
package/lib/facades.js
CHANGED
|
@@ -1,33 +1,44 @@
|
|
|
1
1
|
import * as Tags from '@bablr/agast-helpers/tags';
|
|
2
|
-
import { buildGapTag,
|
|
2
|
+
import { buildGapTag, buildPropertyTag } from '@bablr/agast-helpers/builders';
|
|
3
3
|
import { buildFacadeLayer } from '@bablr/agast-vm-helpers/facades';
|
|
4
|
-
import { buildNode, getTags } from '@bablr/agast-helpers/path';
|
|
4
|
+
import { buildNode, getTags, isStubNode } from '@bablr/agast-helpers/path';
|
|
5
5
|
import { Property } from '@bablr/agast-helpers/symbols';
|
|
6
6
|
|
|
7
7
|
export const { facades, actuals } = buildFacadeLayer();
|
|
8
8
|
|
|
9
|
+
let gapNodes = new WeakMap();
|
|
10
|
+
|
|
11
|
+
export const getGapNode = (gap) => gapNodes.get(gap);
|
|
12
|
+
|
|
9
13
|
export const buildFacadeNode = (node) => {
|
|
14
|
+
if (!node) return null;
|
|
15
|
+
|
|
10
16
|
let facadeTags = Tags.fromValues([]);
|
|
11
17
|
|
|
18
|
+
if (isStubNode(node)) {
|
|
19
|
+
return node;
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
for (let tag of Tags.traverse(getTags(node))) {
|
|
13
23
|
if (tag.type === Property) {
|
|
14
24
|
let property = tag;
|
|
15
|
-
let { reference,
|
|
16
|
-
|
|
17
|
-
let property_ = property;
|
|
25
|
+
let { reference, shift, node, tags } = property.value;
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
let tags_;
|
|
28
|
+
if (reference?.flags.intrinsic || ['_', '#', '@'].includes(reference?.type)) {
|
|
29
|
+
tags_ = [tags[0], tags[1], buildFacadeNode(node)];
|
|
30
|
+
} else {
|
|
20
31
|
let gapNode = buildNode(buildGapTag());
|
|
21
|
-
if (!reference
|
|
22
|
-
|
|
32
|
+
if (!reference?.flags.hasGap) {
|
|
33
|
+
gapNodes.set(gapNode, node);
|
|
23
34
|
}
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
property_ = buildProperty(tags_);
|
|
36
|
+
tags_ = [tags[0], tags[1], gapNode];
|
|
28
37
|
}
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
tags_ = tags_.slice(0, tags.length);
|
|
40
|
+
|
|
41
|
+
facadeTags = Tags.push(facadeTags, buildPropertyTag(tags_, shift));
|
|
31
42
|
} else {
|
|
32
43
|
facadeTags = Tags.push(facadeTags, tag);
|
|
33
44
|
}
|
package/lib/match.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getProduction } from '@bablr/helpers/grammar';
|
|
2
|
-
import { WeakStackFrame } from '@bablr/weak-stack';
|
|
3
2
|
|
|
4
3
|
import { agast } from '@bablr/agast-vm';
|
|
5
4
|
import * as Tags from '@bablr/agast-helpers/tags';
|
|
@@ -14,11 +13,10 @@ import {
|
|
|
14
13
|
buildPropertyTag,
|
|
15
14
|
buildOpenFragmentTag,
|
|
16
15
|
nodeFlags,
|
|
17
|
-
streamFromTree,
|
|
18
16
|
} from '@bablr/agast-helpers/tree';
|
|
19
17
|
import { effectsFor, reifyExpression, shouldBranch } from '@bablr/agast-vm-helpers';
|
|
20
18
|
|
|
21
|
-
import {
|
|
19
|
+
import { buildFacadeNode } from './facades.js';
|
|
22
20
|
import {
|
|
23
21
|
CloseNodeTag,
|
|
24
22
|
OpenNodeTag,
|
|
@@ -41,134 +39,13 @@ import {
|
|
|
41
39
|
} from '@bablr/agast-helpers/path';
|
|
42
40
|
import { updateSpans } from './spans.js';
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
constructor(match) {
|
|
46
|
-
facades.set(match, this);
|
|
47
|
-
Object.freeze(this);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get language() {
|
|
51
|
-
return actuals.get(this).language;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get matcher() {
|
|
55
|
-
return actuals.get(this).matcher;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get options() {
|
|
59
|
-
return actuals.get(this).options;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get mergedReference() {
|
|
63
|
-
return actuals.get(this).mergedReference;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get propertyMatcher() {
|
|
67
|
-
return actuals.get(this).propertyMatcher;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get rawPropertyMatcher() {
|
|
71
|
-
return actuals.get(this).rawPropertyMatcher;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
get depth() {
|
|
75
|
-
return actuals.get(this).depth;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
get path() {
|
|
79
|
-
return actuals.get(this).path;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
get fragment() {
|
|
83
|
-
return actuals.get(this).fragment;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
get pathDepth() {
|
|
87
|
-
return actuals.get(this).depths.path;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
get pathName() {
|
|
91
|
-
return actuals.get(this).pathName;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
get node() {
|
|
95
|
-
return actuals.get(this).node;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get props() {
|
|
99
|
-
return actuals.get(this).props;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
get type() {
|
|
103
|
-
return actuals.get(this).type;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
get isNode() {
|
|
107
|
-
return actuals.get(this).isNode;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
get isCover() {
|
|
111
|
-
return actuals.get(this).isCover;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
get allowEmpty() {
|
|
115
|
-
return actuals.get(this).allowEmpty;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
get didShift() {
|
|
119
|
-
return actuals.get(this).didShift;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
get isCoverBoundary() {
|
|
123
|
-
return actuals.get(this).isCoverBoundary;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
get coveredBoundary() {
|
|
127
|
-
return facades.get(actuals.get(this).coveredBoundary);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
get nodeMatch() {
|
|
131
|
-
return facades.get(actuals.get(this).nodeMatch);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
get cover() {
|
|
135
|
-
return facades.get(actuals.get(this).cover);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
get shiftMatch() {
|
|
139
|
-
return facades.get(actuals.get(this).coveredBoundary.shiftMatch);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
get effects() {
|
|
143
|
-
return actuals.get(this).effects;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
get parent() {
|
|
147
|
-
return facades.get(actuals.get(this).parent);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
get grammar() {
|
|
151
|
-
return actuals.get(this).grammar;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
get state() {
|
|
155
|
-
return actuals.get(this).s.getPublic();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
get s() {
|
|
159
|
-
return actuals.get(this).s.getPublic();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
ancestors(...args) {
|
|
163
|
-
return actuals.get(this).ancestors(...args);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
42
|
+
let facades = new WeakMap();
|
|
166
43
|
|
|
167
44
|
const normalizeBindingPath = (path) => {
|
|
168
45
|
if (path.length <= 1) return path;
|
|
169
46
|
};
|
|
170
47
|
|
|
171
|
-
export class Match
|
|
48
|
+
export class Match {
|
|
172
49
|
static startFrame(ctx, s, m, finishedMatch, verb, matcher, options) {
|
|
173
50
|
let effects = effectsFor(verb.description);
|
|
174
51
|
let isShift = verb.description.startsWith('shift'); // should this be didShift?
|
|
@@ -230,8 +107,7 @@ export class Match extends WeakStackFrame {
|
|
|
230
107
|
}
|
|
231
108
|
let matcher = reifyExpression(rawMatcher);
|
|
232
109
|
|
|
233
|
-
|
|
234
|
-
|
|
110
|
+
this.parent = parent;
|
|
235
111
|
this.context = context;
|
|
236
112
|
this.state = state;
|
|
237
113
|
this.rawPropertyMatcher = rawMatcher;
|
|
@@ -240,6 +116,7 @@ export class Match extends WeakStackFrame {
|
|
|
240
116
|
this.shiftMatch = shiftMatch;
|
|
241
117
|
this.emittedMatch = parent?.emittedMatch || this;
|
|
242
118
|
|
|
119
|
+
this.depth = !parent ? 0 : parent.depth + 1;
|
|
243
120
|
this.agast = null;
|
|
244
121
|
this.cover = null;
|
|
245
122
|
this.running = null;
|
|
@@ -290,12 +167,10 @@ export class Match extends WeakStackFrame {
|
|
|
290
167
|
this.agast.vm.next(shiftMatch.rootNode);
|
|
291
168
|
}
|
|
292
169
|
this.rootNode = this.agast.getState().node;
|
|
293
|
-
|
|
294
|
-
new MatchFacade(this);
|
|
295
170
|
}
|
|
296
171
|
|
|
297
172
|
static from(context, state, matcher, props, options) {
|
|
298
|
-
return Match
|
|
173
|
+
return new Match(null, context, state, matcher, effectsFor('eat'), props, options);
|
|
299
174
|
}
|
|
300
175
|
|
|
301
176
|
get language() {
|
|
@@ -363,7 +238,7 @@ export class Match extends WeakStackFrame {
|
|
|
363
238
|
get path() {
|
|
364
239
|
let { agast } = this;
|
|
365
240
|
|
|
366
|
-
return agast.getState().path || agast.getState().resultPath?.path;
|
|
241
|
+
return Path.wrap(agast.getState().path || agast.getState().resultPath?.path);
|
|
367
242
|
}
|
|
368
243
|
|
|
369
244
|
get coveredBoundary() {
|
|
@@ -410,6 +285,10 @@ export class Match extends WeakStackFrame {
|
|
|
410
285
|
return this.propertyMatcher.nodeMatcher.type === '_';
|
|
411
286
|
}
|
|
412
287
|
|
|
288
|
+
push(context, state, rawMatcher, effects, shiftMatch, options) {
|
|
289
|
+
return new Match(this, context, state, rawMatcher, effects, shiftMatch, options);
|
|
290
|
+
}
|
|
291
|
+
|
|
413
292
|
advance(tag) {
|
|
414
293
|
let { vm, getState } = this.agast;
|
|
415
294
|
let s = this.state;
|
|
@@ -426,9 +305,9 @@ export class Match extends WeakStackFrame {
|
|
|
426
305
|
s.depths.result--;
|
|
427
306
|
}
|
|
428
307
|
|
|
429
|
-
this.rootNode = agastState.path.atDepth(0).node;
|
|
308
|
+
this.rootNode = Path.wrap(agastState.path).atDepth(0).node;
|
|
430
309
|
|
|
431
|
-
s.resultPath = agastState.resultPath;
|
|
310
|
+
s.resultPath = TagPath.wrap(agastState.resultPath);
|
|
432
311
|
|
|
433
312
|
// if (this.emitted?.depth > 1) throw new Error();
|
|
434
313
|
|
|
@@ -679,9 +558,18 @@ export class Match extends WeakStackFrame {
|
|
|
679
558
|
let finishedMatch = m;
|
|
680
559
|
m = m.parent;
|
|
681
560
|
|
|
682
|
-
let
|
|
683
|
-
|
|
684
|
-
|
|
561
|
+
let parentRoot = Path.from(m.rootNode);
|
|
562
|
+
|
|
563
|
+
if (m.type !== '__') {
|
|
564
|
+
parentRoot = parentRoot.tagPathAt(getCloseTag(m.rootNode) ? -2 : -1).inner;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
let finishedChildren =
|
|
568
|
+
finishedMatch.type !== '__' ? 1 : Tags.getSize(finishedMatch.rootNode.value.children);
|
|
569
|
+
|
|
570
|
+
let parentNextTagPath = parentRoot?.tagPathAt(
|
|
571
|
+
finishedMatch.parentPreviousTagPath.tagsIndex + finishedChildren + 1,
|
|
572
|
+
);
|
|
685
573
|
|
|
686
574
|
tagPath = parentNextTagPath;
|
|
687
575
|
|
|
@@ -750,7 +638,9 @@ export class Match extends WeakStackFrame {
|
|
|
750
638
|
do {
|
|
751
639
|
if (m.running) {
|
|
752
640
|
m = m.running;
|
|
753
|
-
|
|
641
|
+
// TODO is -1 ok
|
|
642
|
+
let shiftIndex = m.didShift ? -1 : 0;
|
|
643
|
+
tagPath = TagPath.fromNode(m.rootNode, shiftIndex);
|
|
754
644
|
} else if (m.parent && (!m.parent.running || m.parent.running !== m)) {
|
|
755
645
|
tagPath = m.parentPreviousTagPath;
|
|
756
646
|
|
|
@@ -788,4 +678,97 @@ export class Match extends WeakStackFrame {
|
|
|
788
678
|
}
|
|
789
679
|
}
|
|
790
680
|
}
|
|
681
|
+
|
|
682
|
+
getPublic() {
|
|
683
|
+
let cached = facades.get(this);
|
|
684
|
+
if (cached) {
|
|
685
|
+
return cached;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
let {
|
|
689
|
+
parent,
|
|
690
|
+
cover,
|
|
691
|
+
nodeMatch,
|
|
692
|
+
shiftMatch,
|
|
693
|
+
coveredBoundary,
|
|
694
|
+
mergedReference,
|
|
695
|
+
matcher,
|
|
696
|
+
propertyMatcher,
|
|
697
|
+
rawPropertyMatcher,
|
|
698
|
+
language,
|
|
699
|
+
isNode,
|
|
700
|
+
isCover,
|
|
701
|
+
isCoverBoundary,
|
|
702
|
+
effects,
|
|
703
|
+
options,
|
|
704
|
+
allowEmpty,
|
|
705
|
+
depth,
|
|
706
|
+
state,
|
|
707
|
+
} = this;
|
|
708
|
+
|
|
709
|
+
let getParent = () => {
|
|
710
|
+
let value = parent;
|
|
711
|
+
if (parent) facades.set((value = facades.get(parent) || parent.getPublic()));
|
|
712
|
+
return value;
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
let getCover = () => {
|
|
716
|
+
let value = cover;
|
|
717
|
+
if (cover) facades.set((value = facades.get(cover) || cover.getPublic()));
|
|
718
|
+
return value;
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
let getCoveredBoundary = () => {
|
|
722
|
+
let value = coveredBoundary;
|
|
723
|
+
if (coveredBoundary)
|
|
724
|
+
facades.set((value = facades.get(coveredBoundary) || coveredBoundary.getPublic()));
|
|
725
|
+
return value;
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
let getNodeMatch = () => {
|
|
729
|
+
let value = nodeMatch;
|
|
730
|
+
if (nodeMatch) facades.set((value = facades.get(nodeMatch) || nodeMatch.getPublic()));
|
|
731
|
+
return value;
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
let getShiftMatch = () => {
|
|
735
|
+
let value = shiftMatch;
|
|
736
|
+
if (shiftMatch) facades.set((value = facades.get(shiftMatch) || shiftMatch.getPublic()));
|
|
737
|
+
return value;
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
let getState = () => {
|
|
741
|
+
return state.getPublic();
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
let getNode = () => {
|
|
745
|
+
return buildFacadeNode(this.node);
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
cached = {
|
|
749
|
+
getParent,
|
|
750
|
+
getCover,
|
|
751
|
+
getCoveredBoundary,
|
|
752
|
+
getNodeMatch,
|
|
753
|
+
getShiftMatch,
|
|
754
|
+
getState,
|
|
755
|
+
getNode,
|
|
756
|
+
mergedReference,
|
|
757
|
+
matcher,
|
|
758
|
+
propertyMatcher,
|
|
759
|
+
rawPropertyMatcher,
|
|
760
|
+
language,
|
|
761
|
+
isNode,
|
|
762
|
+
isCover,
|
|
763
|
+
isCoverBoundary,
|
|
764
|
+
effects,
|
|
765
|
+
options,
|
|
766
|
+
allowEmpty,
|
|
767
|
+
depth,
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
facades.set(this, cached);
|
|
771
|
+
|
|
772
|
+
return cached;
|
|
773
|
+
}
|
|
791
774
|
}
|
package/lib/state.js
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import emptyStack from '@iter-tools/imm-stack';
|
|
2
|
-
import {
|
|
3
|
-
import { getCooked, maybeWait } from '@bablr/agast-helpers/stream';
|
|
2
|
+
import { maybeWait } from '@bablr/agast-helpers/stream';
|
|
4
3
|
import * as BTree from '@bablr/agast-helpers/btree';
|
|
5
4
|
import { reifyExpression } from '@bablr/agast-vm-helpers';
|
|
6
|
-
import { Matcher, Node, Regex
|
|
5
|
+
import { Matcher, Node, Regex } from '@bablr/agast-vm-helpers/symbols';
|
|
7
6
|
import { match, guardWithPattern } from './utils/pattern.js';
|
|
8
7
|
import { getOpenTag } from '@bablr/agast-helpers/path';
|
|
9
8
|
|
|
10
9
|
export const nodeStates = new WeakMap();
|
|
11
10
|
|
|
12
|
-
export const State = class BABLRState
|
|
11
|
+
export const State = class BABLRState {
|
|
12
|
+
static from(source, context, language, expressions = []) {
|
|
13
|
+
return new State(
|
|
14
|
+
null,
|
|
15
|
+
source,
|
|
16
|
+
context,
|
|
17
|
+
BTree.fromValues([language]),
|
|
18
|
+
emptyStack.push(...emptyStack.push(...expressions).valuesReverse()),
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
constructor(
|
|
14
23
|
parent,
|
|
15
24
|
source,
|
|
@@ -23,10 +32,9 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
23
32
|
held = null,
|
|
24
33
|
node = null,
|
|
25
34
|
) {
|
|
26
|
-
super(parent);
|
|
27
|
-
|
|
28
35
|
if (!source) throw new Error('invalid args to State');
|
|
29
36
|
|
|
37
|
+
this.parent = parent;
|
|
30
38
|
this.source = source;
|
|
31
39
|
this.context = context;
|
|
32
40
|
this.languages = languages;
|
|
@@ -38,18 +46,10 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
38
46
|
this.held = held;
|
|
39
47
|
this.node = node;
|
|
40
48
|
|
|
49
|
+
this.depth = !parent ? 0 : parent.depth + 1;
|
|
41
50
|
this.status = 'active';
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
static from(source, context, language, expressions = []) {
|
|
45
|
-
return State.create(
|
|
46
|
-
source,
|
|
47
|
-
context,
|
|
48
|
-
BTree.fromValues([language]),
|
|
49
|
-
emptyStack.push(...emptyStack.push(...expressions).valuesReverse()),
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
53
|
get language() {
|
|
54
54
|
return BTree.getAt(-1, this.languages);
|
|
55
55
|
}
|
|
@@ -77,12 +77,29 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
77
77
|
return !!this.parent;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
push(source, context, languages, expressions, balanced, spans, resultPath, depths, held, node) {
|
|
81
|
+
return new State(
|
|
82
|
+
this,
|
|
83
|
+
source,
|
|
84
|
+
context,
|
|
85
|
+
languages,
|
|
86
|
+
expressions,
|
|
87
|
+
balanced,
|
|
88
|
+
spans,
|
|
89
|
+
resultPath,
|
|
90
|
+
depths,
|
|
91
|
+
held,
|
|
92
|
+
node,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
80
96
|
getPublic() {
|
|
81
97
|
let { languages, spans, depths, held, node, source, result, resultPath, status } = this;
|
|
82
|
-
|
|
98
|
+
|
|
99
|
+
return Object.freeze({
|
|
83
100
|
languages,
|
|
84
101
|
span: spans.value?.name,
|
|
85
|
-
depths: { ...depths },
|
|
102
|
+
depths: Object.freeze({ ...depths }),
|
|
86
103
|
holding: !!held,
|
|
87
104
|
held,
|
|
88
105
|
node,
|
|
@@ -90,9 +107,9 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
90
107
|
done: source.done,
|
|
91
108
|
sourceIndex: source.index,
|
|
92
109
|
result,
|
|
93
|
-
resultPath,
|
|
110
|
+
resultPath: resultPath?.frames || null,
|
|
94
111
|
status,
|
|
95
|
-
};
|
|
112
|
+
});
|
|
96
113
|
}
|
|
97
114
|
|
|
98
115
|
guardedMatch(pattern) {
|
|
@@ -101,6 +118,7 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
101
118
|
|
|
102
119
|
let branchedSource = false;
|
|
103
120
|
let pattern_ = pattern;
|
|
121
|
+
|
|
104
122
|
if (pattern.type === Matcher) {
|
|
105
123
|
let { nodeMatcher } = reifyExpression(pattern.value);
|
|
106
124
|
|
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.23.
|
|
4
|
+
"version": "0.23.2",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -12,14 +12,13 @@
|
|
|
12
12
|
},
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@bablr/agast-helpers": "0.10.
|
|
16
|
-
"@bablr/agast-vm": "0.11.
|
|
17
|
-
"@bablr/agast-vm-helpers": "0.10.
|
|
15
|
+
"@bablr/agast-helpers": "0.10.2",
|
|
16
|
+
"@bablr/agast-vm": "0.11.1",
|
|
17
|
+
"@bablr/agast-vm-helpers": "0.10.2",
|
|
18
18
|
"@bablr/coroutine": "0.1.0",
|
|
19
|
-
"@bablr/helpers": "0.25.
|
|
20
|
-
"@bablr/regex-vm": "0.14.
|
|
19
|
+
"@bablr/helpers": "0.25.1",
|
|
20
|
+
"@bablr/regex-vm": "0.14.1",
|
|
21
21
|
"@bablr/stream-iterator": "2.0.0",
|
|
22
|
-
"@bablr/weak-stack": "1.0.1",
|
|
23
22
|
"@iter-tools/imm-stack": "1.2.0",
|
|
24
23
|
"iter-tools-es": "7.5.3"
|
|
25
24
|
},
|