@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/node.js
CHANGED
|
@@ -4,17 +4,20 @@ import {
|
|
|
4
4
|
buildOpenNodeTag,
|
|
5
5
|
buildReferenceTag,
|
|
6
6
|
buildStubNode,
|
|
7
|
-
isFragmentNode,
|
|
8
7
|
isNullNode,
|
|
9
8
|
parseReference,
|
|
10
|
-
referenceFlags,
|
|
11
9
|
} from '@bablr/agast-helpers/tree';
|
|
12
10
|
import { getStreamIterator } from '@bablr/agast-helpers/stream';
|
|
13
11
|
import { agast } from '@bablr/agast-vm';
|
|
14
|
-
import * as
|
|
12
|
+
import * as sumtree from '@bablr/agast-helpers/sumtree';
|
|
15
13
|
import { Pump } from './utils/pump.js';
|
|
16
14
|
import { OpenNodeTag, ReferenceTag } from '@bablr/agast-helpers/symbols';
|
|
17
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
buildFullRange,
|
|
17
|
+
get,
|
|
18
|
+
getProperties,
|
|
19
|
+
getPropertyChildrenIndex,
|
|
20
|
+
} from '@bablr/agast-helpers/path';
|
|
18
21
|
import { isArray } from '@bablr/helpers/object';
|
|
19
22
|
|
|
20
23
|
export const states = new WeakMap();
|
|
@@ -22,18 +25,35 @@ export const internalStates = new WeakMap();
|
|
|
22
25
|
|
|
23
26
|
const { hasOwn } = Object;
|
|
24
27
|
|
|
25
|
-
const buildFullRange = (node) => {
|
|
26
|
-
const sum = btree.getSum(node.children);
|
|
27
|
-
return sum ? [0, sum - 1] : null;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
28
|
export const FragmentFacade = class BABLRFragmentFacade {
|
|
29
|
+
static wrapNode(
|
|
30
|
+
node,
|
|
31
|
+
context,
|
|
32
|
+
transparent = false,
|
|
33
|
+
childrenIndexRange = null,
|
|
34
|
+
dotPropertyReference = null,
|
|
35
|
+
dotPropertyIndex = null,
|
|
36
|
+
) {
|
|
37
|
+
return (
|
|
38
|
+
node &&
|
|
39
|
+
new FragmentFacade(
|
|
40
|
+
node,
|
|
41
|
+
context,
|
|
42
|
+
transparent,
|
|
43
|
+
false,
|
|
44
|
+
childrenIndexRange,
|
|
45
|
+
dotPropertyReference,
|
|
46
|
+
dotPropertyIndex,
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
31
51
|
static wrap(
|
|
32
52
|
node,
|
|
33
53
|
context,
|
|
34
54
|
transparent = false,
|
|
35
|
-
childrenIndexRange =
|
|
36
|
-
|
|
55
|
+
childrenIndexRange = null,
|
|
56
|
+
dotPropertyReference = null,
|
|
37
57
|
dotPropertyIndex = null,
|
|
38
58
|
) {
|
|
39
59
|
return (
|
|
@@ -42,53 +62,86 @@ export const FragmentFacade = class BABLRFragmentFacade {
|
|
|
42
62
|
node,
|
|
43
63
|
context,
|
|
44
64
|
transparent,
|
|
65
|
+
true,
|
|
45
66
|
childrenIndexRange,
|
|
46
|
-
|
|
67
|
+
dotPropertyReference,
|
|
47
68
|
dotPropertyIndex,
|
|
48
69
|
)
|
|
49
70
|
);
|
|
50
71
|
}
|
|
51
72
|
|
|
52
|
-
constructor(
|
|
73
|
+
constructor(
|
|
74
|
+
node,
|
|
75
|
+
context,
|
|
76
|
+
transparent = false,
|
|
77
|
+
isFragmentNode = true,
|
|
78
|
+
childrenIndexRange = null,
|
|
79
|
+
dotPropertyReference = null,
|
|
80
|
+
dotPropertyIndex = null,
|
|
81
|
+
) {
|
|
82
|
+
if (!node) throw new Error();
|
|
83
|
+
|
|
53
84
|
if (childrenIndexRange && (childrenIndexRange[0] == null || !childrenIndexRange[1] == null)) {
|
|
54
85
|
throw new Error();
|
|
55
86
|
}
|
|
56
87
|
|
|
57
88
|
if (!context) throw new Error();
|
|
58
89
|
|
|
59
|
-
if (
|
|
90
|
+
if (dotPropertyReference && !hasOwn(node.properties, dotPropertyReference.value.name))
|
|
91
|
+
throw new Error();
|
|
92
|
+
|
|
93
|
+
if (isArray(dotPropertyReference?.value.isArray && dotPropertyIndex == null)) throw new Error();
|
|
94
|
+
|
|
95
|
+
let resolvedNode = node;
|
|
96
|
+
let fragmentNode = node;
|
|
97
|
+
|
|
98
|
+
if (dotPropertyReference) {
|
|
99
|
+
let { name, isArray, flags } = dotPropertyReference.value;
|
|
60
100
|
|
|
61
|
-
|
|
101
|
+
let dotReference = buildReferenceTag(name, isArray, flags, dotPropertyIndex);
|
|
102
|
+
|
|
103
|
+
resolvedNode = get(dotReference, fragmentNode);
|
|
104
|
+
}
|
|
62
105
|
|
|
63
106
|
states.set(this, {
|
|
64
107
|
context,
|
|
65
108
|
openTag: buildOpenNodeTag(),
|
|
66
109
|
closeTag: buildCloseNodeTag(),
|
|
67
|
-
node,
|
|
110
|
+
node: resolvedNode,
|
|
111
|
+
fragmentNode: node,
|
|
68
112
|
transparent,
|
|
113
|
+
isFragmentNode,
|
|
69
114
|
childrenIndexRange,
|
|
70
|
-
|
|
115
|
+
dotPropertyReference,
|
|
71
116
|
dotPropertyIndex,
|
|
72
117
|
});
|
|
73
118
|
}
|
|
74
119
|
|
|
120
|
+
get dotPropertyName() {
|
|
121
|
+
return states.get(this).dotPropertyReference?.value.name;
|
|
122
|
+
}
|
|
123
|
+
|
|
75
124
|
get isTransparent() {
|
|
76
125
|
return states.get(this).transparent;
|
|
77
126
|
}
|
|
78
127
|
|
|
79
|
-
get
|
|
80
|
-
|
|
128
|
+
get isNull() {
|
|
129
|
+
let { node } = states.get(this);
|
|
130
|
+
return isNullNode(node);
|
|
81
131
|
}
|
|
82
132
|
|
|
83
133
|
get children() {
|
|
84
|
-
|
|
134
|
+
let { node, isFragmentNode, transparent, childrenIndexRange } = states.get(this);
|
|
135
|
+
|
|
136
|
+
childrenIndexRange =
|
|
137
|
+
isFragmentNode || !childrenIndexRange ? buildFullRange(node) : childrenIndexRange;
|
|
85
138
|
|
|
86
139
|
return {
|
|
87
140
|
*[Symbol.iterator]() {
|
|
88
141
|
for (let i = childrenIndexRange[0]; i <= childrenIndexRange[1]; i++) {
|
|
89
142
|
const interpolated = false; // TODO
|
|
90
143
|
if (!interpolated || transparent) {
|
|
91
|
-
yield
|
|
144
|
+
yield sumtree.getAt(i, node.children);
|
|
92
145
|
}
|
|
93
146
|
}
|
|
94
147
|
},
|
|
@@ -103,7 +156,7 @@ export const FragmentFacade = class BABLRFragmentFacade {
|
|
|
103
156
|
if (childrenIndexRange[0] > childrenIndexRange[1]) throw new Error();
|
|
104
157
|
|
|
105
158
|
for (let i = childrenIndexRange[0]; i <= childrenIndexRange[1]; i++) {
|
|
106
|
-
let tag =
|
|
159
|
+
let tag = sumtree.getAt(i, node.children);
|
|
107
160
|
if (tag.type === ReferenceTag) {
|
|
108
161
|
const { name, isArray } = tag.value;
|
|
109
162
|
let resolvedTagName = name === '.' ? dotPropertyName : name;
|
|
@@ -124,75 +177,120 @@ export const FragmentFacade = class BABLRFragmentFacade {
|
|
|
124
177
|
}
|
|
125
178
|
|
|
126
179
|
get language() {
|
|
127
|
-
let { node } = states.get(this);
|
|
180
|
+
let { node, isFragmentNode } = states.get(this);
|
|
128
181
|
|
|
129
|
-
return node.language;
|
|
182
|
+
return isFragmentNode ? null : node.language;
|
|
130
183
|
}
|
|
131
184
|
|
|
132
185
|
get type() {
|
|
133
|
-
let { node } = states.get(this);
|
|
186
|
+
let { node, isFragmentNode } = states.get(this);
|
|
134
187
|
|
|
135
|
-
return node.type;
|
|
188
|
+
return isFragmentNode ? null : node.type;
|
|
136
189
|
}
|
|
137
190
|
|
|
138
191
|
get attributes() {
|
|
139
|
-
let { node } = states.get(this);
|
|
192
|
+
let { node, isFragmentNode } = states.get(this);
|
|
140
193
|
|
|
141
|
-
return node.attributes;
|
|
194
|
+
return isFragmentNode ? {} : node.attributes;
|
|
142
195
|
}
|
|
143
196
|
|
|
144
197
|
get openTag() {
|
|
145
|
-
const
|
|
146
|
-
const { children } = state.node;
|
|
198
|
+
const { node, openTag, isFragmentNode } = states.get(this);
|
|
147
199
|
|
|
148
|
-
return
|
|
200
|
+
return isFragmentNode ? openTag : sumtree.getAt(0, node.children);
|
|
149
201
|
}
|
|
150
202
|
|
|
151
203
|
get closeTag() {
|
|
152
|
-
const
|
|
153
|
-
const { children } = state.node;
|
|
204
|
+
const { node, closeTag, isFragmentNode } = states.get(this);
|
|
154
205
|
|
|
155
|
-
return
|
|
206
|
+
return isFragmentNode
|
|
207
|
+
? closeTag
|
|
208
|
+
: sumtree.getAt(sumtree.getSize(node.children) - 1, node.children);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
merge(targetFragment) {
|
|
212
|
+
let {
|
|
213
|
+
fragmentNode,
|
|
214
|
+
context,
|
|
215
|
+
transparent,
|
|
216
|
+
isFragmentNode,
|
|
217
|
+
childrenIndexRange,
|
|
218
|
+
dotPropertyReference,
|
|
219
|
+
dotPropertyIndex,
|
|
220
|
+
} = states.get(this);
|
|
221
|
+
const { fragmentNode: targetFragmentNode, childrenIndexRange: targetChildrenIndexRange } =
|
|
222
|
+
states.get(targetFragment);
|
|
223
|
+
if (fragmentNode === targetFragmentNode) {
|
|
224
|
+
// TODO restrict what is legal here
|
|
225
|
+
|
|
226
|
+
return new FragmentFacade(
|
|
227
|
+
fragmentNode,
|
|
228
|
+
context,
|
|
229
|
+
transparent,
|
|
230
|
+
isFragmentNode,
|
|
231
|
+
targetChildrenIndexRange,
|
|
232
|
+
dotPropertyReference,
|
|
233
|
+
dotPropertyIndex,
|
|
234
|
+
);
|
|
235
|
+
} else {
|
|
236
|
+
throw new Error('not implemented');
|
|
237
|
+
}
|
|
156
238
|
}
|
|
157
239
|
|
|
158
240
|
get(path) {
|
|
159
241
|
let {
|
|
160
|
-
node,
|
|
242
|
+
node: ownNode,
|
|
243
|
+
fragmentNode,
|
|
161
244
|
context,
|
|
162
245
|
transparent,
|
|
163
|
-
|
|
246
|
+
isFragmentNode,
|
|
247
|
+
childrenIndexRange,
|
|
248
|
+
dotPropertyReference: dotReference,
|
|
164
249
|
dotPropertyIndex: dotIndex,
|
|
165
250
|
} = states.get(this);
|
|
166
|
-
// let { path: nodePath } = internalStates.get(node);
|
|
167
251
|
const parsedRef = parseReference(path);
|
|
168
|
-
// const resolvedPath = resolvePath(node, path);
|
|
169
|
-
// const childNode = getAtPath(resolvedPath, node);
|
|
170
252
|
|
|
171
|
-
|
|
253
|
+
let node = fragmentNode;
|
|
172
254
|
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
referenceFlags,
|
|
178
|
-
dotIndex,
|
|
179
|
-
);
|
|
255
|
+
if (parsedRef.value.name !== '.') {
|
|
256
|
+
if (dotReference) {
|
|
257
|
+
fragmentNode = ownNode;
|
|
258
|
+
dotReference = parsedRef;
|
|
180
259
|
|
|
181
|
-
|
|
182
|
-
|
|
260
|
+
isFragmentNode = false;
|
|
261
|
+
} else {
|
|
262
|
+
dotReference = parsedRef;
|
|
263
|
+
dotIndex = parsedRef.value.index;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
let { name, isArray, flags } = parsedRef.value;
|
|
267
|
+
let resolvedReference = buildReferenceTag(name, isArray, flags, dotIndex);
|
|
268
|
+
let refIndex = getPropertyChildrenIndex(fragmentNode, resolvedReference);
|
|
269
|
+
childrenIndexRange = [refIndex, refIndex + 1];
|
|
183
270
|
|
|
184
|
-
|
|
271
|
+
const binding = getProperties(parsedRef, fragmentNode.properties);
|
|
185
272
|
|
|
186
|
-
|
|
273
|
+
if (!binding) return null;
|
|
187
274
|
|
|
188
|
-
|
|
275
|
+
const ref = binding.reference;
|
|
189
276
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
277
|
+
node =
|
|
278
|
+
(ref && ref.type === ReferenceTag && !ref.value.flags.hasGap) || transparent
|
|
279
|
+
? binding.node
|
|
280
|
+
: buildStubNode(buildGapTag());
|
|
281
|
+
}
|
|
194
282
|
|
|
195
|
-
return isNullNode(
|
|
283
|
+
return isNullNode(node)
|
|
284
|
+
? null
|
|
285
|
+
: new FragmentFacade(
|
|
286
|
+
fragmentNode,
|
|
287
|
+
context,
|
|
288
|
+
transparent,
|
|
289
|
+
isFragmentNode,
|
|
290
|
+
childrenIndexRange,
|
|
291
|
+
dotReference,
|
|
292
|
+
dotIndex,
|
|
293
|
+
);
|
|
196
294
|
}
|
|
197
295
|
|
|
198
296
|
has(path) {
|
package/lib/source.js
CHANGED
|
@@ -251,7 +251,9 @@ export const Source = class BABLRSource extends WeakStackFrame {
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
[Symbol.for('@@streamIterator')]() {
|
|
254
|
-
return this.holding ? emptyStreamIterator : this.fork.clone()[
|
|
254
|
+
return (this.holding ? emptyStreamIterator() : this.fork.clone())[
|
|
255
|
+
Symbol.for('@@streamIterator')
|
|
256
|
+
]();
|
|
255
257
|
}
|
|
256
258
|
|
|
257
259
|
formatIndex() {
|