@bablr/bablr-vm 0.17.0 → 0.18.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 +75 -0
- package/lib/index.js +2 -0
- package/lib/node.js +97 -0
- package/lib/source.js +1 -1
- package/lib/spans.js +17 -26
- package/lib/state.js +22 -10
- package/lib/strategy.js +56 -19
- package/lib/utils/pattern.js +1 -1
- package/package.json +5 -5
- package/lib/facades.js +0 -3
package/lib/context.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { buildDependentLanguages } from '@bablr/helpers/grammar';
|
|
2
|
+
import { facades, actuals } from '../../bablr-vm-strategy-parse/lib/facades.js';
|
|
3
|
+
import { getPrototypeOf } from '@bablr/helpers/object';
|
|
4
|
+
import { actuals as nodeActuals } from './node.js';
|
|
5
|
+
|
|
6
|
+
export const ContextFacade = class BABLRContextFacade {
|
|
7
|
+
get languages() {
|
|
8
|
+
return actuals.get(this).languages;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get grammars() {
|
|
12
|
+
return actuals.get(this).grammars;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get productionEnhancer() {
|
|
16
|
+
return actuals.get(this).productionEnhancer;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get agast() {
|
|
20
|
+
return actuals.get(this).agast;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getPreviousTag(token) {
|
|
24
|
+
return actuals.get(this).agast.getPreviousTag(token);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
allTagsFor(range) {
|
|
28
|
+
return actuals.get(this).agast.allTagsFor(range);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
ownTagsFor(range) {
|
|
32
|
+
return actuals.get(this).agast.ownTagsFor(range);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getCooked(node) {
|
|
36
|
+
return actuals.get(this).agast.getCooked(actuals.get(node));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
reifyExpression(value) {
|
|
40
|
+
return actuals.get(this).agast.reifyExpression(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
sourceTextFor(node) {
|
|
44
|
+
return actuals.get(this).agast.sourceTextFor(nodeActuals.get(node));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
unbox(value) {
|
|
48
|
+
return actuals.get(this).agast.unbox(value);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const Context = class BABLRContext {
|
|
53
|
+
static from(agastContext, language, productionEnhancer) {
|
|
54
|
+
return new Context(agastContext, buildDependentLanguages(language), productionEnhancer);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
constructor(agastContext, languages, productionEnhancer) {
|
|
58
|
+
this.agast = agastContext;
|
|
59
|
+
this.languages = languages;
|
|
60
|
+
this.productionEnhancer = productionEnhancer;
|
|
61
|
+
|
|
62
|
+
this.grammars = new WeakMap();
|
|
63
|
+
this.facade = new ContextFacade();
|
|
64
|
+
|
|
65
|
+
for (const { 1: language } of this.languages) {
|
|
66
|
+
let { prototype } = language.grammar;
|
|
67
|
+
while (prototype && prototype !== Object.prototype) {
|
|
68
|
+
prototype = getPrototypeOf(prototype);
|
|
69
|
+
}
|
|
70
|
+
this.grammars.set(language, new language.grammar());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
facades.set(this, this.facade);
|
|
74
|
+
}
|
|
75
|
+
};
|
package/lib/index.js
CHANGED
package/lib/node.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { parsePath } from '@bablr/agast-helpers/path';
|
|
2
|
+
import { ReferenceTag } from '@bablr/agast-helpers/symbols';
|
|
3
|
+
import {
|
|
4
|
+
buildGapTag,
|
|
5
|
+
buildStubNode,
|
|
6
|
+
get,
|
|
7
|
+
getCloseTag,
|
|
8
|
+
getOpenTag,
|
|
9
|
+
} from '@bablr/agast-helpers/tree';
|
|
10
|
+
import * as btree from '@bablr/agast-helpers/btree';
|
|
11
|
+
|
|
12
|
+
const { hasOwn } = Object;
|
|
13
|
+
|
|
14
|
+
export const contexts = new WeakMap();
|
|
15
|
+
export const actuals = new WeakMap();
|
|
16
|
+
// eslint-disable-next-line no-undef
|
|
17
|
+
export const transparentFacades = new WeakSet();
|
|
18
|
+
|
|
19
|
+
export const NodeFacade = class BABLRNodeFacade {
|
|
20
|
+
static wrap(node, context, transparent) {
|
|
21
|
+
if (!node || !context) throw new Error();
|
|
22
|
+
return node && new NodeFacade(node, context, transparent);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor(node, context, transparent) {
|
|
26
|
+
actuals.set(this, node);
|
|
27
|
+
contexts.set(this, context);
|
|
28
|
+
if (transparent) {
|
|
29
|
+
transparentFacades.add(this);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get isTransparent() {
|
|
34
|
+
return transparentFacades.has(this);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get children() {
|
|
38
|
+
const node = actuals.get(this);
|
|
39
|
+
const isTransparent = transparentFacades.has(this);
|
|
40
|
+
return {
|
|
41
|
+
*[Symbol.iterator]() {
|
|
42
|
+
if (isTransparent) {
|
|
43
|
+
yield* btree.traverse(node.children);
|
|
44
|
+
} else {
|
|
45
|
+
for (const child of btree.traverse(node.children)) {
|
|
46
|
+
const interpolated = false; // TODO
|
|
47
|
+
if (!interpolated) {
|
|
48
|
+
yield child;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get flags() {
|
|
57
|
+
return actuals.get(this).flags;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get language() {
|
|
61
|
+
return actuals.get(this).language;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get type() {
|
|
65
|
+
return actuals.get(this).type;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get attributes() {
|
|
69
|
+
return actuals.get(this).attributes;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get openTag() {
|
|
73
|
+
return getOpenTag(actuals.get(this));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get closeTag() {
|
|
77
|
+
return getCloseTag(actuals.get(this));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get(path) {
|
|
81
|
+
const context = contexts.get(this);
|
|
82
|
+
const node = get(actuals.get(this), path);
|
|
83
|
+
const isTransparent = transparentFacades.has(this);
|
|
84
|
+
|
|
85
|
+
const ref = node && context.agast.getPreviousTag(btree.getAt(0, node.children));
|
|
86
|
+
const node_ =
|
|
87
|
+
(ref && ref.type === ReferenceTag && !ref.value.hasGap) || isTransparent
|
|
88
|
+
? node
|
|
89
|
+
: buildStubNode(buildGapTag());
|
|
90
|
+
|
|
91
|
+
return node && NodeFacade.wrap(node_, context, isTransparent);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
has(path) {
|
|
95
|
+
return hasOwn(actuals.get(this).properties, parsePath(path).name);
|
|
96
|
+
}
|
|
97
|
+
};
|
package/lib/source.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WeakStackFrame } from '@bablr/weak-stack';
|
|
2
2
|
import { maybeWait, getStreamIterator, emptyStreamIterator } from '@bablr/agast-helpers/stream';
|
|
3
|
-
import { facades, actuals } from '
|
|
3
|
+
import { facades, actuals } from '../../bablr-vm-strategy-parse/lib/facades.js';
|
|
4
4
|
|
|
5
5
|
// Queue item instances are shared between all forks.
|
|
6
6
|
class QueueItem {
|
package/lib/spans.js
CHANGED
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReferenceTag } from '@bablr/agast-helpers/symbols';
|
|
2
2
|
import { getOpenTag } from '@bablr/agast-helpers/tree';
|
|
3
3
|
|
|
4
4
|
export function updateSpans(ctx, s, node, phase) {
|
|
5
|
+
const { flags, attributes } = node;
|
|
6
|
+
|
|
7
|
+
const openTag = getOpenTag(node);
|
|
8
|
+
|
|
9
|
+
const ref = ctx.agast.getPreviousTag(openTag);
|
|
10
|
+
|
|
11
|
+
const intrinsic = ref.type === ReferenceTag && !ref.hasGap;
|
|
12
|
+
|
|
5
13
|
switch (phase) {
|
|
6
14
|
case 'open': {
|
|
7
|
-
const {
|
|
8
|
-
const { span: innerSpan, balanced, balancedSpan, balancer, openSpan } = attributes || {};
|
|
15
|
+
const { balancedSpan, span: innerSpan, balanced, balancer, openSpan } = attributes || {};
|
|
9
16
|
|
|
10
|
-
if (!
|
|
17
|
+
if (!intrinsic && (balancer || balanced)) {
|
|
11
18
|
throw new Error('balanced tokens must be instrinsic');
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
if (
|
|
15
|
-
if (s.path && balanced) {
|
|
16
|
-
s.spans = s.spans.push({
|
|
17
|
-
type: 'Lexical',
|
|
18
|
-
name: balancedSpan || s.span.name,
|
|
19
|
-
path: s.path,
|
|
20
|
-
guard: balanced,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
if (innerSpan) {
|
|
24
|
-
throw new Error();
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
21
|
+
if (balancedSpan && !balanced) throw new Error();
|
|
28
22
|
|
|
29
23
|
if (openSpan) {
|
|
30
24
|
s.spans = s.spans.push({
|
|
@@ -40,7 +34,7 @@ export function updateSpans(ctx, s, node, phase) {
|
|
|
40
34
|
|
|
41
35
|
if (!s.balanced.size) throw new Error();
|
|
42
36
|
|
|
43
|
-
if (!
|
|
37
|
+
if (!balancedNode.attributes.balanced) {
|
|
44
38
|
throw new Error();
|
|
45
39
|
}
|
|
46
40
|
|
|
@@ -49,10 +43,6 @@ export function updateSpans(ctx, s, node, phase) {
|
|
|
49
43
|
s.spans = s.spans.pop();
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
if (balanced) {
|
|
53
|
-
s.balanced = s.balanced.push(s.nodeForTag(s.result));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
46
|
if (innerSpan) {
|
|
57
47
|
s.spans = s.spans.push({
|
|
58
48
|
type: 'Inner',
|
|
@@ -66,15 +56,16 @@ export function updateSpans(ctx, s, node, phase) {
|
|
|
66
56
|
}
|
|
67
57
|
|
|
68
58
|
case 'close': {
|
|
69
|
-
const { flags, attributes } = node;
|
|
70
59
|
const { balancedSpan, span: innerSpan, closeSpan, balanced } = attributes || {};
|
|
71
60
|
|
|
72
|
-
if (balanced
|
|
61
|
+
if (balanced) {
|
|
62
|
+
s.balanced = s.balanced.push(s.nodeForTag(s.result));
|
|
63
|
+
|
|
73
64
|
s.spans = s.spans.push({
|
|
74
65
|
type: 'Lexical',
|
|
75
66
|
name: balancedSpan || s.span.name,
|
|
76
67
|
path: s.path,
|
|
77
|
-
guard: balanced,
|
|
68
|
+
guard: balanced === true ? null : balanced,
|
|
78
69
|
});
|
|
79
70
|
}
|
|
80
71
|
|
package/lib/state.js
CHANGED
|
@@ -2,9 +2,10 @@ import emptyStack from '@iter-tools/imm-stack';
|
|
|
2
2
|
import { WeakStackFrame } from '@bablr/weak-stack';
|
|
3
3
|
import { getCooked } from '@bablr/agast-helpers/stream';
|
|
4
4
|
import { match, guardWithPattern } from './utils/pattern.js';
|
|
5
|
-
import { facades, actuals } from '
|
|
5
|
+
import { facades, actuals } from '../../bablr-vm-strategy-parse/lib/facades.js';
|
|
6
6
|
import { reifyExpression } from '@bablr/agast-vm-helpers';
|
|
7
|
-
import { EmbeddedNode } from '@bablr/agast-helpers/symbols';
|
|
7
|
+
import { EmbeddedNode, GapTag } from '@bablr/agast-helpers/symbols';
|
|
8
|
+
import { NodeFacade } from './node.js';
|
|
8
9
|
|
|
9
10
|
export const StateFacade = class BABLRStateFacade {
|
|
10
11
|
constructor(state) {
|
|
@@ -15,6 +16,10 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
15
16
|
return State.from(actuals.get(source));
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
get ctx() {
|
|
20
|
+
return actuals.get(this).context;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
get span() {
|
|
19
24
|
return actuals.get(this).span.name;
|
|
20
25
|
}
|
|
@@ -32,11 +37,11 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
get node() {
|
|
35
|
-
return actuals.get(this).node;
|
|
40
|
+
return NodeFacade.wrap(actuals.get(this).node, this.ctx);
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
get parentNode() {
|
|
39
|
-
return actuals.get(this).parentNode;
|
|
44
|
+
return NodeFacade.wrap(actuals.get(this).parentNode, this.ctx);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
get source() {
|
|
@@ -52,7 +57,7 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
nodeForPath(path) {
|
|
55
|
-
return actuals.get(this).nodeForPath(path);
|
|
60
|
+
return NodeFacade.wrap(actuals.get(this).nodeForPath(path), this.ctx);
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
pathForTag(tag) {
|
|
@@ -60,18 +65,25 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
nodeForTag(tag) {
|
|
63
|
-
return actuals.get(this).nodeForTag(tag);
|
|
68
|
+
return NodeFacade.wrap(actuals.get(this).nodeForTag(tag), this.ctx);
|
|
64
69
|
}
|
|
65
70
|
};
|
|
66
71
|
|
|
67
72
|
export const State = class BABLRState extends WeakStackFrame {
|
|
68
|
-
constructor(
|
|
73
|
+
constructor(
|
|
74
|
+
source,
|
|
75
|
+
agast,
|
|
76
|
+
context,
|
|
77
|
+
balanced = emptyStack,
|
|
78
|
+
spans = emptyStack.push({ name: 'Bare' }),
|
|
79
|
+
) {
|
|
69
80
|
super();
|
|
70
81
|
|
|
71
82
|
if (!source || !agast) throw new Error('invalid args to State');
|
|
72
83
|
|
|
73
84
|
this.source = source;
|
|
74
85
|
this.agast = agast;
|
|
86
|
+
this.context = context;
|
|
75
87
|
this.balanced = balanced;
|
|
76
88
|
this.spans = spans;
|
|
77
89
|
|
|
@@ -80,8 +92,8 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
80
92
|
new StateFacade(this);
|
|
81
93
|
}
|
|
82
94
|
|
|
83
|
-
static from(source, agast) {
|
|
84
|
-
return State.create(source, agast);
|
|
95
|
+
static from(source, agast, context) {
|
|
96
|
+
return State.create(source, agast, context);
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
get guardedSource() {
|
|
@@ -116,7 +128,7 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
116
128
|
}
|
|
117
129
|
|
|
118
130
|
get isGap() {
|
|
119
|
-
return this.tag.type ===
|
|
131
|
+
return this.tag.type === GapTag;
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
get speculative() {
|
package/lib/strategy.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import size from 'iter-tools-es/methods/size';
|
|
2
1
|
import { Coroutine } from '@bablr/coroutine';
|
|
3
2
|
import {
|
|
4
3
|
buildCall,
|
|
@@ -8,9 +7,8 @@ import {
|
|
|
8
7
|
buildArrayTag,
|
|
9
8
|
} from '@bablr/agast-helpers/builders';
|
|
10
9
|
import { StreamGenerator } from '@bablr/agast-helpers/stream';
|
|
11
|
-
import { buildTokens } from './utils/token.js';
|
|
12
10
|
import { formatType } from './utils/format.js';
|
|
13
|
-
import { facades } from '
|
|
11
|
+
import { facades } from '../../bablr-vm-strategy-parse/lib/facades.js';
|
|
14
12
|
import { State } from './state.js';
|
|
15
13
|
import { updateSpans } from './spans.js';
|
|
16
14
|
import {
|
|
@@ -23,11 +21,26 @@ import {
|
|
|
23
21
|
NullTag,
|
|
24
22
|
LiteralTag,
|
|
25
23
|
} from '@bablr/agast-helpers/symbols';
|
|
24
|
+
import { NodeFacade } from './node.js';
|
|
25
|
+
import { treeFromStreamSync } from '@bablr/agast-helpers/tree';
|
|
26
|
+
|
|
27
|
+
const getSourceLength = (tags) => {
|
|
28
|
+
let i = 0;
|
|
29
|
+
for (const tag of tags) {
|
|
30
|
+
if (tag.type === LiteralTag) {
|
|
31
|
+
i += tag.value.length;
|
|
32
|
+
} else if (tag.type === GapTag) {
|
|
33
|
+
i += 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return i;
|
|
37
|
+
};
|
|
26
38
|
|
|
27
39
|
const { hasOwn } = Object;
|
|
28
40
|
|
|
29
|
-
export const createBablrStrategy = (rootSource, strategy) => {
|
|
30
|
-
return (
|
|
41
|
+
export const createBablrStrategy = (ctx, rootSource, strategy) => {
|
|
42
|
+
return (agastCtx, agastState) => {
|
|
43
|
+
if (agastCtx !== ctx.agast.facade) throw new Error();
|
|
31
44
|
return new StreamGenerator(__strategy(ctx, rootSource, agastState, strategy));
|
|
32
45
|
};
|
|
33
46
|
};
|
|
@@ -35,9 +48,9 @@ export const createBablrStrategy = (rootSource, strategy) => {
|
|
|
35
48
|
const resolvedLanguages = new WeakMap();
|
|
36
49
|
|
|
37
50
|
const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy) {
|
|
38
|
-
let s = State.from(rootSource, agastState);
|
|
51
|
+
let s = State.from(rootSource, agastState, ctx);
|
|
39
52
|
|
|
40
|
-
let co = new Coroutine(strategy(facades.get(s), ctx));
|
|
53
|
+
let co = new Coroutine(strategy(facades.get(s), facades.get(ctx)));
|
|
41
54
|
|
|
42
55
|
co.advance();
|
|
43
56
|
|
|
@@ -93,7 +106,18 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
93
106
|
case CloseNodeTag: {
|
|
94
107
|
const { node } = s;
|
|
95
108
|
|
|
96
|
-
|
|
109
|
+
if (node.flags.escape) {
|
|
110
|
+
const cooked = node.flags.hasGap
|
|
111
|
+
? null
|
|
112
|
+
: ctx.languages
|
|
113
|
+
.get(node.language)
|
|
114
|
+
.getCooked?.(NodeFacade.wrap(node, ctx, true), s.span.name, facades.get(ctx)) ||
|
|
115
|
+
null;
|
|
116
|
+
|
|
117
|
+
yield buildCall('bindAttribute', 'cooked', cooked);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const closeTag = yield instr;
|
|
97
121
|
|
|
98
122
|
if (s.path) {
|
|
99
123
|
updateSpans(ctx, s, node, 'close');
|
|
@@ -107,7 +131,7 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
107
131
|
}
|
|
108
132
|
}
|
|
109
133
|
|
|
110
|
-
returnValue =
|
|
134
|
+
returnValue = closeTag;
|
|
111
135
|
break;
|
|
112
136
|
}
|
|
113
137
|
|
|
@@ -121,7 +145,7 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
121
145
|
}
|
|
122
146
|
|
|
123
147
|
if (result) {
|
|
124
|
-
let sourceStep = s.source.advance(
|
|
148
|
+
let sourceStep = s.source.advance(getSourceLength(result));
|
|
125
149
|
|
|
126
150
|
if (sourceStep instanceof Promise) {
|
|
127
151
|
sourceStep = yield sourceStep;
|
|
@@ -178,19 +202,17 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
178
202
|
result = yield result;
|
|
179
203
|
}
|
|
180
204
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
returnValue = tokens || null;
|
|
205
|
+
returnValue = result && NodeFacade.wrap(treeFromStreamSync(result), ctx, true);
|
|
184
206
|
break;
|
|
185
207
|
}
|
|
186
208
|
|
|
187
209
|
case 'branch': {
|
|
188
210
|
const baseState = s;
|
|
189
|
-
let { source, agast, balanced, spans, node } = baseState;
|
|
211
|
+
let { source, agast, context, balanced, spans, node } = baseState;
|
|
190
212
|
|
|
191
213
|
agast = yield instr;
|
|
192
214
|
|
|
193
|
-
s = s.push(source.branch(), agast, balanced, spans);
|
|
215
|
+
s = s.push(source.branch(), agast, context, balanced, spans);
|
|
194
216
|
|
|
195
217
|
if (node) {
|
|
196
218
|
resolvedLanguages.set(s.node, resolvedLanguages.get(node));
|
|
@@ -232,7 +254,7 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
232
254
|
|
|
233
255
|
s = s.parent;
|
|
234
256
|
|
|
235
|
-
if (s.path.depth && rejectedState.path.depth
|
|
257
|
+
if (s.path.depth && rejectedState.path.depth >= s.path.depth) {
|
|
236
258
|
// const didShift = rejectedState.node.at(sNodeDepth) === s.node;
|
|
237
259
|
const didShift =
|
|
238
260
|
s.nodeForPath(s.path) && !s.nodeForPath(rejectedState.path.at(s.path.depth));
|
|
@@ -244,7 +266,7 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
244
266
|
);
|
|
245
267
|
const lowNode = s.node || s.parentNode;
|
|
246
268
|
|
|
247
|
-
const { name, isArray } = lowPath.reference?.value || {};
|
|
269
|
+
const { name, isArray, hasGap } = lowPath.reference?.value || {};
|
|
248
270
|
|
|
249
271
|
if (
|
|
250
272
|
!didShift &&
|
|
@@ -252,10 +274,13 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
252
274
|
!(s.result.type === ReferenceTag && s.result.value.name === name)
|
|
253
275
|
) {
|
|
254
276
|
if (isArray) {
|
|
255
|
-
yield buildCall('advance', buildEmbeddedTag(buildReferenceTag(name, true)));
|
|
277
|
+
yield buildCall('advance', buildEmbeddedTag(buildReferenceTag(name, true, hasGap)));
|
|
256
278
|
yield buildCall('advance', buildEmbeddedTag(buildArrayTag()));
|
|
257
279
|
} else {
|
|
258
|
-
yield buildCall(
|
|
280
|
+
yield buildCall(
|
|
281
|
+
'advance',
|
|
282
|
+
buildEmbeddedTag(buildReferenceTag(name, isArray, hasGap)),
|
|
283
|
+
);
|
|
259
284
|
yield buildCall('advance', buildEmbeddedTag(buildNullTag()));
|
|
260
285
|
}
|
|
261
286
|
}
|
|
@@ -269,6 +294,18 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
269
294
|
break;
|
|
270
295
|
}
|
|
271
296
|
|
|
297
|
+
case 'openSpan': {
|
|
298
|
+
let { arguments: { 0: name } = [] } = instr;
|
|
299
|
+
s.spans = s.spans.push({ guard: null, name, path: s.path, type: 'Instruction' });
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
case 'closeSpan': {
|
|
304
|
+
if (s.spans.value.type !== 'Instruction') throw new Error();
|
|
305
|
+
s.spans = s.spans.pop();
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
|
|
272
309
|
case 'write':
|
|
273
310
|
case 'bindAttribute': {
|
|
274
311
|
returnValue = yield instr;
|
package/lib/utils/pattern.js
CHANGED
|
@@ -57,7 +57,7 @@ class GuardedIterator {
|
|
|
57
57
|
const guardMatch = match(pattern, fork.clone());
|
|
58
58
|
|
|
59
59
|
return maybeWait(guardMatch, (guardMatch) => {
|
|
60
|
-
if (guardMatch ||
|
|
60
|
+
if (guardMatch || fork.done) {
|
|
61
61
|
this.done = true;
|
|
62
62
|
return { value: undefined, done: true };
|
|
63
63
|
} else {
|
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.18.0",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
},
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@bablr/agast-helpers": "0.
|
|
16
|
-
"@bablr/agast-vm-helpers": "0.
|
|
15
|
+
"@bablr/agast-helpers": "^0.5.0",
|
|
16
|
+
"@bablr/agast-vm-helpers": "^0.5.0",
|
|
17
17
|
"@bablr/coroutine": "0.1.0",
|
|
18
|
-
"@bablr/helpers": "0.
|
|
19
|
-
"@bablr/regex-vm": "0.
|
|
18
|
+
"@bablr/helpers": "^0.20.0",
|
|
19
|
+
"@bablr/regex-vm": "^0.9.0",
|
|
20
20
|
"@bablr/weak-stack": "0.1.0",
|
|
21
21
|
"@iter-tools/imm-stack": "1.1.0",
|
|
22
22
|
"iter-tools-es": "^7.5.3"
|
package/lib/facades.js
DELETED