@bablr/bablr-vm 0.13.3 → 0.15.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/README.md +1 -1
- package/lib/source.js +7 -3
- package/lib/spans.js +1 -1
- package/lib/state.js +19 -4
- package/lib/strategy.js +55 -65
- package/package.json +4 -4
package/README.md
CHANGED
package/lib/source.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WeakStackFrame } from '@bablr/weak-stack';
|
|
2
|
-
import { maybeWait, getStreamIterator } from '@bablr/agast-helpers/stream';
|
|
2
|
+
import { maybeWait, getStreamIterator, emptyStreamIterator } from '@bablr/agast-helpers/stream';
|
|
3
3
|
import { facades, actuals } from './facades.js';
|
|
4
4
|
|
|
5
5
|
// Queue item instances are shared between all forks.
|
|
@@ -168,6 +168,10 @@ export const SourceFacade = class BABLRSourceFacade {
|
|
|
168
168
|
return actuals.get(this).done;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
get value() {
|
|
172
|
+
return actuals.get(this).value;
|
|
173
|
+
}
|
|
174
|
+
|
|
171
175
|
get index() {
|
|
172
176
|
return actuals.get(this).index;
|
|
173
177
|
}
|
|
@@ -197,7 +201,7 @@ export const Source = class BABLRSource extends WeakStackFrame {
|
|
|
197
201
|
}
|
|
198
202
|
|
|
199
203
|
get value() {
|
|
200
|
-
return this.fork.value;
|
|
204
|
+
return this.holding ? null : this.fork.value;
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
get done() {
|
|
@@ -247,7 +251,7 @@ export const Source = class BABLRSource extends WeakStackFrame {
|
|
|
247
251
|
}
|
|
248
252
|
|
|
249
253
|
[Symbol.for('@@streamIterator')]() {
|
|
250
|
-
return this.fork.clone()[Symbol.for('@@streamIterator')]();
|
|
254
|
+
return this.holding ? emptyStreamIterator : this.fork.clone()[Symbol.for('@@streamIterator')]();
|
|
251
255
|
}
|
|
252
256
|
|
|
253
257
|
formatIndex() {
|
package/lib/spans.js
CHANGED
package/lib/state.js
CHANGED
|
@@ -33,6 +33,10 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
33
33
|
return actuals.get(this).node;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
get parentNode() {
|
|
37
|
+
return actuals.get(this).parentNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
36
40
|
get source() {
|
|
37
41
|
return facades.get(actuals.get(this).source);
|
|
38
42
|
}
|
|
@@ -40,6 +44,10 @@ export const StateFacade = class BABLRStateFacade {
|
|
|
40
44
|
get depth() {
|
|
41
45
|
return actuals.get(this).depth;
|
|
42
46
|
}
|
|
47
|
+
|
|
48
|
+
get status() {
|
|
49
|
+
return actuals.get(this).status;
|
|
50
|
+
}
|
|
43
51
|
};
|
|
44
52
|
|
|
45
53
|
export const State = class BABLRState extends WeakStackFrame {
|
|
@@ -53,6 +61,8 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
53
61
|
this.balanced = balanced;
|
|
54
62
|
this.spans = spans;
|
|
55
63
|
|
|
64
|
+
this.status = 'active';
|
|
65
|
+
|
|
56
66
|
new StateFacade(this);
|
|
57
67
|
}
|
|
58
68
|
|
|
@@ -79,6 +89,10 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
79
89
|
return this.agast.node;
|
|
80
90
|
}
|
|
81
91
|
|
|
92
|
+
get parentNode() {
|
|
93
|
+
return this.agast.parentNode;
|
|
94
|
+
}
|
|
95
|
+
|
|
82
96
|
get holding() {
|
|
83
97
|
return this.agast.holding;
|
|
84
98
|
}
|
|
@@ -100,10 +114,11 @@ export const State = class BABLRState extends WeakStackFrame {
|
|
|
100
114
|
let { guard } = span;
|
|
101
115
|
|
|
102
116
|
if (pattern?.intrinsicValue) {
|
|
103
|
-
if (pattern.type === 'OpenNodeTag') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
// if (pattern.type === 'OpenNodeTag') {
|
|
118
|
+
|
|
119
|
+
// // TODO differntiate better between self-closing tags and matchers
|
|
120
|
+
// pattern = pattern.value;
|
|
121
|
+
// }
|
|
107
122
|
|
|
108
123
|
({ guard } = span);
|
|
109
124
|
|
package/lib/strategy.js
CHANGED
|
@@ -60,38 +60,33 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
case 'OpenNodeTag': {
|
|
63
|
-
const { intrinsicValue } = terminal.value;
|
|
63
|
+
const { type, intrinsicValue } = terminal.value;
|
|
64
64
|
|
|
65
65
|
const openTag = yield sourceInstr;
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
if (type) {
|
|
68
|
+
let intrinsicResult = intrinsicValue && s.guardedMatch(terminal.value);
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
updateSpans(ctx, s, intrinsicValue ? ctx.nodeForTag(openTag) : s.node, 'open');
|
|
74
|
-
|
|
75
|
-
if (intrinsicValue) {
|
|
76
|
-
if (!intrinsicResult) {
|
|
77
|
-
throw new Error('advance failed to match an intrinsic node');
|
|
70
|
+
if (intrinsicResult instanceof Promise) {
|
|
71
|
+
intrinsicResult = yield intrinsicResult;
|
|
78
72
|
}
|
|
79
73
|
|
|
80
|
-
|
|
74
|
+
updateSpans(ctx, s, ctx.nodeForTag(openTag), 'open');
|
|
81
75
|
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
if (intrinsicValue) {
|
|
77
|
+
if (!intrinsicResult) {
|
|
78
|
+
throw new Error('advance failed to match an intrinsic node');
|
|
79
|
+
}
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
}
|
|
81
|
+
const sourceStep = s.source.advance(intrinsicResult.length);
|
|
88
82
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
if (sourceStep instanceof Promise) {
|
|
84
|
+
yield sourceStep;
|
|
85
|
+
}
|
|
92
86
|
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
updateSpans(ctx, s, ctx.nodeForTag(openTag), 'close');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
95
90
|
|
|
96
91
|
returnValue = openTag;
|
|
97
92
|
break;
|
|
@@ -104,16 +99,7 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
104
99
|
|
|
105
100
|
if (s.path) {
|
|
106
101
|
updateSpans(ctx, s, node, 'close');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
returnValue = endTag;
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
case 'CloseFragmentTag': {
|
|
114
|
-
returnValue = yield sourceInstr;
|
|
115
|
-
|
|
116
|
-
if (!s.path) {
|
|
102
|
+
} else {
|
|
117
103
|
if (!s.source.done) {
|
|
118
104
|
throw new Error('Parser failed to consume input');
|
|
119
105
|
}
|
|
@@ -122,6 +108,8 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
122
108
|
throw new Error('Parser did not match all balanced nodes');
|
|
123
109
|
}
|
|
124
110
|
}
|
|
111
|
+
|
|
112
|
+
returnValue = endTag;
|
|
125
113
|
break;
|
|
126
114
|
}
|
|
127
115
|
|
|
@@ -150,10 +138,14 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
150
138
|
|
|
151
139
|
case 'Gap': {
|
|
152
140
|
if (s.source.value == null && !s.source.done) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
141
|
+
if (s.source.holding) {
|
|
142
|
+
s.source.unshift();
|
|
143
|
+
} else {
|
|
144
|
+
const sourceStep = s.source.advance(1);
|
|
145
|
+
|
|
146
|
+
if (sourceStep instanceof Promise) {
|
|
147
|
+
yield sourceStep;
|
|
148
|
+
}
|
|
157
149
|
}
|
|
158
150
|
|
|
159
151
|
returnValue = yield sourceInstr;
|
|
@@ -163,6 +155,13 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
163
155
|
break;
|
|
164
156
|
}
|
|
165
157
|
|
|
158
|
+
case 'Shift': {
|
|
159
|
+
s.source.shift();
|
|
160
|
+
|
|
161
|
+
returnValue = yield sourceInstr;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
|
|
166
165
|
default: {
|
|
167
166
|
returnValue = yield sourceInstr;
|
|
168
167
|
break;
|
|
@@ -185,22 +184,6 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
185
184
|
break;
|
|
186
185
|
}
|
|
187
186
|
|
|
188
|
-
case 'shift': {
|
|
189
|
-
s.source.shift();
|
|
190
|
-
|
|
191
|
-
yield sourceInstr;
|
|
192
|
-
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
case 'unshift': {
|
|
197
|
-
s.source.unshift();
|
|
198
|
-
|
|
199
|
-
yield sourceInstr;
|
|
200
|
-
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
187
|
case 'branch': {
|
|
205
188
|
const baseState = s;
|
|
206
189
|
let { source, agast, balanced, spans, node } = baseState;
|
|
@@ -209,7 +192,9 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
209
192
|
|
|
210
193
|
s = s.push(source.branch(), agast, balanced, spans);
|
|
211
194
|
|
|
212
|
-
|
|
195
|
+
if (node) {
|
|
196
|
+
resolvedLanguages.set(s.node, resolvedLanguages.get(node));
|
|
197
|
+
}
|
|
213
198
|
|
|
214
199
|
returnValue = facades.get(s);
|
|
215
200
|
break;
|
|
@@ -218,6 +203,8 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
218
203
|
case 'accept': {
|
|
219
204
|
const accepted = s;
|
|
220
205
|
|
|
206
|
+
s.status = 'accepted';
|
|
207
|
+
|
|
221
208
|
const agastState = yield sourceInstr;
|
|
222
209
|
|
|
223
210
|
s = s.parent;
|
|
@@ -239,27 +226,29 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
239
226
|
case 'reject': {
|
|
240
227
|
const rejectedState = s;
|
|
241
228
|
|
|
229
|
+
s.status = 'rejected';
|
|
230
|
+
|
|
242
231
|
yield sourceInstr;
|
|
243
232
|
|
|
244
233
|
s = s.parent;
|
|
245
234
|
|
|
246
|
-
if (rejectedState.path.depth > s.path.depth) {
|
|
235
|
+
if (s.path.depth && rejectedState.path.depth > s.path.depth) {
|
|
236
|
+
// const didShift = rejectedState.node.at(sNodeDepth) === s.node;
|
|
237
|
+
const didShift =
|
|
238
|
+
ctx.nodeForPath(s.path) && !ctx.nodeForPath(rejectedState.path.at(s.path.depth));
|
|
247
239
|
const lowPath = rejectedState.path.at(
|
|
248
|
-
Math.min(s.path.depth + 1, rejectedState.path.depth),
|
|
240
|
+
Math.min(s.path.depth + (didShift ? 0 : 1), rejectedState.path.depth),
|
|
249
241
|
);
|
|
242
|
+
const lowNode = s.node || s.parentNode;
|
|
250
243
|
|
|
251
|
-
|
|
252
|
-
const { name, isArray } = lowPath.reference?.value || {};
|
|
253
|
-
|
|
254
|
-
if (s.node.depth === s.path.depth && !s.node.resolver.counters.has(name)) {
|
|
255
|
-
if (!lowPath.openTag?.value.flags.trivia && !lowPath.openTag?.value.flags.escape) {
|
|
256
|
-
yield buildCall('advance', buildReference(name, isArray));
|
|
257
|
-
}
|
|
244
|
+
const { name, isArray } = lowPath.reference?.value || {};
|
|
258
245
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
246
|
+
if (!didShift && !lowNode.resolver.counters.has(name)) {
|
|
247
|
+
if (!lowNode.openTag?.value.flags.trivia && !lowNode.openTag?.value.flags.escape) {
|
|
248
|
+
yield buildCall('advance', buildReference(name, isArray));
|
|
262
249
|
}
|
|
250
|
+
|
|
251
|
+
yield buildCall('advance', buildNull());
|
|
263
252
|
}
|
|
264
253
|
}
|
|
265
254
|
|
|
@@ -271,6 +260,7 @@ const __strategy = function* bablrStrategy(ctx, rootSource, agastState, strategy
|
|
|
271
260
|
break;
|
|
272
261
|
}
|
|
273
262
|
|
|
263
|
+
case 'write':
|
|
274
264
|
case 'bindAttribute': {
|
|
275
265
|
returnValue = yield sourceInstr;
|
|
276
266
|
break;
|
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.15.0",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -12,10 +12,10 @@
|
|
|
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.2.0",
|
|
16
|
+
"@bablr/agast-vm-helpers": "0.2.0",
|
|
17
17
|
"@bablr/coroutine": "0.1.0",
|
|
18
|
-
"@bablr/helpers": "0.
|
|
18
|
+
"@bablr/helpers": "0.17.0",
|
|
19
19
|
"@bablr/regex-vm": "0.5.1",
|
|
20
20
|
"@bablr/weak-stack": "0.1.0",
|
|
21
21
|
"@iter-tools/imm-stack": "1.1.0",
|