@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/source.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { maybeWait, getStreamIterator } from '@bablr/agast-helpers/stream';
|
|
2
|
-
import { facades, actuals } from './facades.js';
|
|
3
2
|
import { streamIteratorSymbol } from '@bablr/stream-iterator';
|
|
4
3
|
|
|
5
4
|
// Queue item instances are shared between all sources.
|
|
@@ -29,9 +28,9 @@ class Exchange {
|
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
allocateSource(source) {
|
|
32
|
-
const { head = this.tail, exchange = this, index,
|
|
31
|
+
const { head = this.tail, exchange = this, index, prevValue } = source || {};
|
|
33
32
|
++this.sources;
|
|
34
|
-
return new Source(head, exchange, index,
|
|
33
|
+
return new Source(head, exchange, index, prevValue);
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
releaseSource(source) {
|
|
@@ -71,7 +70,7 @@ class SourceIterator {
|
|
|
71
70
|
static from(source) {
|
|
72
71
|
const { exchange } = source;
|
|
73
72
|
return source.done
|
|
74
|
-
?
|
|
73
|
+
? new SourceIterator(source)
|
|
75
74
|
: new SourceIterator(exchange.allocateSource(source));
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -82,10 +81,10 @@ class SourceIterator {
|
|
|
82
81
|
next() {
|
|
83
82
|
const source = sources.get(this);
|
|
84
83
|
if (!source.done) {
|
|
85
|
-
const {
|
|
84
|
+
const { head } = source;
|
|
86
85
|
source.advance();
|
|
87
86
|
return maybeWait(source.head.step, () => {
|
|
88
|
-
return
|
|
87
|
+
return head.step;
|
|
89
88
|
});
|
|
90
89
|
} else {
|
|
91
90
|
return { value: undefined, done: true };
|
|
@@ -107,58 +106,23 @@ class SourceIterator {
|
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
108
|
|
|
110
|
-
export const SourceFacade = class BABLRSourceFacade {
|
|
111
|
-
static from(iterable) {
|
|
112
|
-
return facades.get(Source.from(iterable));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
constructor(source) {
|
|
116
|
-
facades.set(source, this);
|
|
117
|
-
|
|
118
|
-
Object.freeze(this);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
[streamIteratorSymbol]() {
|
|
122
|
-
return actuals.get(this)[streamIteratorSymbol]();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
get done() {
|
|
126
|
-
return actuals.get(this).done;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
get value() {
|
|
130
|
-
return actuals.get(this).value;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
get index() {
|
|
134
|
-
return actuals.get(this).index;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
get atGap() {
|
|
138
|
-
return actuals.get(this).atGap;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
109
|
export const Source = class BABLRSource {
|
|
143
110
|
static from(iterable) {
|
|
144
111
|
const exchange = Exchange.from(iterable);
|
|
145
112
|
return exchange.allocateSource();
|
|
146
113
|
}
|
|
147
114
|
|
|
148
|
-
constructor(head, exchange, index = -1,
|
|
115
|
+
constructor(head, exchange, index = -1, prevValue = undefined) {
|
|
149
116
|
if (!head || !exchange) throw new Error();
|
|
150
117
|
|
|
151
118
|
this.head = head;
|
|
152
119
|
this.exchange = exchange;
|
|
153
120
|
this.index = index;
|
|
154
|
-
this.holding = holding;
|
|
155
121
|
this.prevValue = prevValue;
|
|
156
|
-
|
|
157
|
-
new SourceFacade(this);
|
|
158
122
|
}
|
|
159
123
|
|
|
160
124
|
get value() {
|
|
161
|
-
return this.
|
|
125
|
+
return this.head.step?.value;
|
|
162
126
|
}
|
|
163
127
|
|
|
164
128
|
get done() {
|
|
@@ -166,25 +130,12 @@ export const Source = class BABLRSource {
|
|
|
166
130
|
}
|
|
167
131
|
|
|
168
132
|
get atGap() {
|
|
169
|
-
return
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
shift() {
|
|
173
|
-
this.holding = true;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
unshift() {
|
|
177
|
-
this.holding = false;
|
|
133
|
+
return !this.done && this.value == null;
|
|
178
134
|
}
|
|
179
135
|
|
|
180
136
|
advance(n = 1) {
|
|
181
137
|
let { exchange } = this;
|
|
182
138
|
|
|
183
|
-
if (this.holding) {
|
|
184
|
-
this.holding = false;
|
|
185
|
-
n--;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
139
|
return new Array(n).fill(null).reduce((acc) => {
|
|
189
140
|
return maybeWait(acc, () => {
|
|
190
141
|
if (this.done) {
|
|
@@ -202,6 +153,7 @@ export const Source = class BABLRSource {
|
|
|
202
153
|
this.head = head = nextItem;
|
|
203
154
|
this.prevValue = value;
|
|
204
155
|
|
|
156
|
+
// TODO what if head.step is a promise?
|
|
205
157
|
if (head.step?.done) {
|
|
206
158
|
exchange.releaseSource(this);
|
|
207
159
|
}
|
|
@@ -235,7 +187,6 @@ export const Source = class BABLRSource {
|
|
|
235
187
|
accept(source) {
|
|
236
188
|
this.head = source.head;
|
|
237
189
|
this.index = source.index;
|
|
238
|
-
this.holding = source.holding;
|
|
239
190
|
this.prevValue = source.prevValue;
|
|
240
191
|
|
|
241
192
|
source.release();
|
package/lib/spans.js
CHANGED
|
@@ -1,85 +1,46 @@
|
|
|
1
1
|
import { ReferenceTag } from '@bablr/agast-helpers/symbols';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import * as BTree from '@bablr/agast-helpers/btree';
|
|
3
|
+
|
|
4
|
+
const popSpan = (s) => {
|
|
5
|
+
s.spans = s.spans.pop();
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const pushSpan = (s, type, name, guard) => {
|
|
9
|
+
let isSubspan = name[0] === '.';
|
|
10
|
+
let topFrame = s.spans.value;
|
|
11
|
+
|
|
12
|
+
// if (isSubspan) {
|
|
13
|
+
// let buildGuard = () => {
|
|
14
|
+
// return buildPattern();
|
|
15
|
+
// };
|
|
16
|
+
// let name_ = topFrame.name + name;
|
|
17
|
+
// let subframes = BTree.push(topFrame.subframes, topFrame);
|
|
18
|
+
// let guard_ = guard;
|
|
19
|
+
|
|
20
|
+
// s.spans = s.spans.push({ type, name: name_, guard: guard_, subframes });
|
|
21
|
+
// } else {
|
|
22
|
+
s.spans = s.spans.push({ type, name, guard, subframes: BTree.fromValues([]) });
|
|
23
|
+
// }
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function updateSpans(m, phase) {
|
|
4
27
|
const { state: s } = m;
|
|
5
|
-
const { attributes } = node;
|
|
6
28
|
const refPath = m.reference;
|
|
7
29
|
|
|
8
30
|
if (refPath && refPath.tag.type !== ReferenceTag) throw new Error();
|
|
9
31
|
|
|
10
|
-
const intrinsic = !refPath || (refPath.tag.type === ReferenceTag && !refPath.tag.value.hasGap);
|
|
11
|
-
|
|
12
32
|
switch (phase) {
|
|
13
33
|
case 'open': {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (!intrinsic && (balancer || balanced)) {
|
|
17
|
-
throw new Error('balanced tokens must be instrinsic');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (balancedSpan && !balanced) throw new Error();
|
|
21
|
-
|
|
22
|
-
if (openSpan) {
|
|
23
|
-
s.spans = s.spans.push({
|
|
24
|
-
type: 'Explicit',
|
|
25
|
-
name: openSpan,
|
|
26
|
-
guard: null,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (innerSpan) {
|
|
31
|
-
s.spans = s.spans.push({
|
|
32
|
-
type: 'Inner',
|
|
33
|
-
name: innerSpan,
|
|
34
|
-
guard: null,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (m.language !== m.parent.language) {
|
|
39
|
-
s.spans = s.spans.push({ name: 'Bare' });
|
|
34
|
+
if (m.language !== m.parent?.language) {
|
|
35
|
+
pushSpan(s, 'Explicit', 'Bare', null);
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
break;
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
case 'close': {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (balanced) {
|
|
49
|
-
s.balanced = s.balanced.push(node);
|
|
50
|
-
|
|
51
|
-
s.spans = s.spans.push({
|
|
52
|
-
type: 'Lexical',
|
|
53
|
-
name: balancedSpan || s.span.name,
|
|
54
|
-
guard: balanced === true ? null : balanced,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (balancer) {
|
|
59
|
-
const balancedNode = s.balanced.value;
|
|
60
|
-
|
|
61
|
-
if (!s.balanced.size) throw new Error();
|
|
62
|
-
|
|
63
|
-
if (!balancedNode.attributes.balanced) {
|
|
64
|
-
throw new Error();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
s.balanced = s.balanced.pop();
|
|
68
|
-
|
|
69
|
-
s.spans = s.spans.pop();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (closeSpan) {
|
|
73
|
-
if (s.spans.value.type !== 'Explicit') throw new Error();
|
|
74
|
-
s.spans = s.spans.pop();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (innerSpan) {
|
|
78
|
-
s.spans = s.spans.pop();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (m.language !== m.parent.language) {
|
|
82
|
-
s.spans = s.spans.pop();
|
|
42
|
+
if (m.language !== m.parent?.language) {
|
|
43
|
+
popSpan(s);
|
|
83
44
|
}
|
|
84
45
|
|
|
85
46
|
break;
|