@bablr/helpers 0.24.0 → 0.25.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/builders.js +261 -179
- package/lib/decorators.js +0 -11
- package/lib/grammar.js +186 -43
- package/lib/productions.js +38 -54
- package/lib/shorthand.js +1 -1
- package/lib/source.js +17 -10
- package/lib/trivia.js +179 -314
- package/package.json +11 -14
- package/lib/productions.macro.js +0 -84
package/lib/builders.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { interpolateFragment, buildFilledGapFunction } from '@bablr/agast-helpers/template';
|
|
2
|
-
import {
|
|
3
|
-
buildNullNode,
|
|
4
|
-
get,
|
|
5
|
-
getRootArray,
|
|
6
|
-
treeFromStreamSync as treeFromStream,
|
|
7
|
-
} from '@bablr/agast-helpers/tree';
|
|
2
|
+
import { get, isEmpty, treeFromStreamSync as treeFromStream } from '@bablr/agast-helpers/tree';
|
|
8
3
|
import { buildLiteralTag as agastBuildLiteralTag } from '@bablr/agast-helpers/builders';
|
|
9
4
|
import * as t from '@bablr/agast-helpers/shorthand';
|
|
10
5
|
import * as Tags from '@bablr/agast-helpers/tags';
|
|
11
6
|
import * as l from '@bablr/agast-vm-helpers/languages';
|
|
12
7
|
import { concat } from '@bablr/agast-vm-helpers/iterable';
|
|
8
|
+
import { buildNullNode } from '@bablr/agast-helpers/path';
|
|
13
9
|
|
|
14
10
|
const { freeze } = Object;
|
|
15
11
|
const { isArray } = Array;
|
|
@@ -18,7 +14,7 @@ const when = (condition, value) => (condition ? value : { *[Symbol.iterator]() {
|
|
|
18
14
|
|
|
19
15
|
const isString = (val) => typeof val === 'string';
|
|
20
16
|
|
|
21
|
-
export const buildReferenceTag = (name,
|
|
17
|
+
export const buildReferenceTag = (name, flags = t.referenceFlags) => {
|
|
22
18
|
let expressions = [];
|
|
23
19
|
const gap = buildFilledGapFunction(expressions);
|
|
24
20
|
|
|
@@ -27,14 +23,102 @@ export const buildReferenceTag = (name, isArray = false, flags = t.referenceFlag
|
|
|
27
23
|
t.nodeOpen(t.nodeFlags, 'ReferenceTag'),
|
|
28
24
|
t.ref`name`,
|
|
29
25
|
gap(name ? buildIdentifier(name) : buildNullNode()),
|
|
30
|
-
t.ref`openIndexToken`,
|
|
31
|
-
gap(isArray ? buildToken('Punctuator', '[') : buildNullNode()),
|
|
32
|
-
t.ref`closeIndexToken`,
|
|
33
|
-
gap(isArray ? buildToken('Punctuator', ']') : buildNullNode()),
|
|
34
26
|
t.ref`flags`,
|
|
35
27
|
gap(flags ? buildReferenceFlags(flags) : buildNullNode()),
|
|
36
28
|
t.ref`sigilToken`,
|
|
37
|
-
gap(buildToken(
|
|
29
|
+
gap(buildToken(null, ':')),
|
|
30
|
+
t.nodeClose(),
|
|
31
|
+
],
|
|
32
|
+
{ expressions },
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const buildBindingMatcher = (segments) => {
|
|
37
|
+
let expressions = [];
|
|
38
|
+
const gap = buildFilledGapFunction(expressions);
|
|
39
|
+
|
|
40
|
+
return treeFromStream(
|
|
41
|
+
concat(
|
|
42
|
+
[t.nodeOpen(t.nodeFlags, 'BindingMatcher')],
|
|
43
|
+
segments.flatMap((segment) => [t.ref`segments[]`, gap(buildBindingSegment(segment))]),
|
|
44
|
+
[t.nodeClose()],
|
|
45
|
+
),
|
|
46
|
+
{ expressions },
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const buildBindingMatchers = (matchers) => {
|
|
51
|
+
let expressions = [];
|
|
52
|
+
const gap = buildFilledGapFunction(expressions);
|
|
53
|
+
|
|
54
|
+
return treeFromStream(
|
|
55
|
+
concat(
|
|
56
|
+
[t.fragOpen()],
|
|
57
|
+
matchers.flatMap((matcher) => [
|
|
58
|
+
t.ref`bindingMatchers[]`,
|
|
59
|
+
gap(buildBindingMatcher(matcher.segments)),
|
|
60
|
+
]),
|
|
61
|
+
[t.nodeClose()],
|
|
62
|
+
),
|
|
63
|
+
{ expressions },
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const buildBoundNodeMatcher = (bindingMatchers, valueMatcher) => {
|
|
68
|
+
if (valueMatcher.value.name.description === 'BoundNodeMatcher') throw new Error();
|
|
69
|
+
const expressions = [];
|
|
70
|
+
const gap = buildFilledGapFunction(expressions);
|
|
71
|
+
|
|
72
|
+
return treeFromStream(
|
|
73
|
+
(function* () {
|
|
74
|
+
yield t.nodeOpen(t.nodeFlags, 'BoundNodeMatcher');
|
|
75
|
+
if (bindingMatchers.length) {
|
|
76
|
+
yield* interpolateFragment(
|
|
77
|
+
buildBindingMatchers(bindingMatchers),
|
|
78
|
+
t.ref`bindingMatchers`,
|
|
79
|
+
expressions,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
yield t.ref`nodeMatcher`;
|
|
83
|
+
yield gap(valueMatcher);
|
|
84
|
+
yield t.nodeClose();
|
|
85
|
+
})(),
|
|
86
|
+
{ expressions },
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const buildPropertyMatcher = (refMatcher, valueMatcher) => {
|
|
91
|
+
const expressions = [];
|
|
92
|
+
const gap = buildFilledGapFunction(expressions);
|
|
93
|
+
|
|
94
|
+
return treeFromStream(
|
|
95
|
+
(function* () {
|
|
96
|
+
yield t.nodeOpen(t.nodeFlags, 'PropertyMatcher');
|
|
97
|
+
yield t.ref`refMatcher`;
|
|
98
|
+
yield gap(refMatcher || buildNullNode());
|
|
99
|
+
yield t.ref`valueMatcher`;
|
|
100
|
+
yield gap(valueMatcher || buildNullNode());
|
|
101
|
+
yield t.nodeClose();
|
|
102
|
+
})(),
|
|
103
|
+
{ expressions },
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const buildBindingSegment = (segment) => {
|
|
108
|
+
let expressions = [];
|
|
109
|
+
const gap = buildFilledGapFunction(expressions);
|
|
110
|
+
|
|
111
|
+
let { type, name } = segment;
|
|
112
|
+
|
|
113
|
+
return treeFromStream(
|
|
114
|
+
[
|
|
115
|
+
t.nodeOpen(t.nodeFlags, 'BindingSegment'),
|
|
116
|
+
t.ref`openToken`,
|
|
117
|
+
gap(buildToken(null, ':')),
|
|
118
|
+
t.ref`path`,
|
|
119
|
+
gap(type ? buildToken(null, type) : buildIdentifier(name)),
|
|
120
|
+
t.ref`closeToken`,
|
|
121
|
+
gap(buildToken(null, ':')),
|
|
38
122
|
t.nodeClose(),
|
|
39
123
|
],
|
|
40
124
|
{ expressions },
|
|
@@ -47,9 +131,9 @@ export const buildGapTag = () => {
|
|
|
47
131
|
|
|
48
132
|
return treeFromStream(
|
|
49
133
|
[
|
|
50
|
-
t.nodeOpen(t.nodeFlags, '
|
|
134
|
+
t.nodeOpen(t.nodeFlags, 'GapTag'),
|
|
51
135
|
t.ref`sigilToken`,
|
|
52
|
-
gap(buildToken(
|
|
136
|
+
gap(buildToken(null, '<//>')),
|
|
53
137
|
t.nodeClose(),
|
|
54
138
|
],
|
|
55
139
|
{ expressions },
|
|
@@ -64,7 +148,7 @@ export const buildShiftTag = () => {
|
|
|
64
148
|
[
|
|
65
149
|
t.nodeOpen(t.nodeFlags, 'ShiftTag'),
|
|
66
150
|
t.ref`sigilToken`,
|
|
67
|
-
gap(buildToken(
|
|
151
|
+
gap(buildToken(null, '^^^')),
|
|
68
152
|
t.nodeClose(),
|
|
69
153
|
],
|
|
70
154
|
{ expressions },
|
|
@@ -72,17 +156,21 @@ export const buildShiftTag = () => {
|
|
|
72
156
|
};
|
|
73
157
|
|
|
74
158
|
export const buildReferenceFlags = (flags = t.referenceFlags) => {
|
|
75
|
-
const { expression
|
|
159
|
+
const { array, expression, intrinsic, hasGap } = flags;
|
|
76
160
|
let expressions = [];
|
|
77
161
|
const gap = buildFilledGapFunction(expressions);
|
|
78
162
|
|
|
79
163
|
return treeFromStream(
|
|
80
164
|
[
|
|
81
165
|
t.nodeOpen(t.nodeFlags, 'ReferenceFlags'),
|
|
166
|
+
t.ref`arrayToken`,
|
|
167
|
+
gap(array ? buildToken(null, '[]') : buildNullNode()),
|
|
82
168
|
t.ref`expressionToken`,
|
|
83
|
-
gap(expression ? buildToken(
|
|
169
|
+
gap(expression ? buildToken(null, '+') : buildNullNode()),
|
|
170
|
+
t.ref`intrinsicToken`,
|
|
171
|
+
gap(intrinsic ? buildToken(null, '*') : buildNullNode()),
|
|
84
172
|
t.ref`hasGapToken`,
|
|
85
|
-
gap(hasGap ? buildToken(
|
|
173
|
+
gap(hasGap ? buildToken(null, '$') : buildNullNode()),
|
|
86
174
|
t.nodeClose(),
|
|
87
175
|
],
|
|
88
176
|
{ expressions },
|
|
@@ -90,84 +178,113 @@ export const buildReferenceFlags = (flags = t.referenceFlags) => {
|
|
|
90
178
|
};
|
|
91
179
|
|
|
92
180
|
export const buildNodeFlags = (flags = t.nodeFlags) => {
|
|
93
|
-
const { token = null, hasGap = null
|
|
181
|
+
const { token = null, hasGap = null } = flags;
|
|
94
182
|
let expressions = [];
|
|
95
183
|
const gap = buildFilledGapFunction(expressions);
|
|
96
184
|
|
|
185
|
+
let flags_ = { token, hasGap };
|
|
186
|
+
let attributes = flags_;
|
|
187
|
+
|
|
97
188
|
return treeFromStream(
|
|
98
189
|
[
|
|
99
|
-
t.nodeOpen(t.nodeFlags, 'NodeFlags'),
|
|
190
|
+
t.nodeOpen(t.nodeFlags, 'NodeFlags', null, attributes),
|
|
100
191
|
t.ref`tokenToken`,
|
|
101
|
-
gap(token ? buildToken(
|
|
192
|
+
gap(token ? buildToken(null, '*') : buildNullNode()),
|
|
102
193
|
t.ref`hasGapToken`,
|
|
103
|
-
gap(hasGap ? buildToken(
|
|
104
|
-
t.ref`fragmentToken`,
|
|
105
|
-
gap(fragment ? buildToken('Punctuator', '_') : buildNullNode()),
|
|
106
|
-
t.ref`multiFragmentToken`,
|
|
107
|
-
gap(!cover ? buildToken('Punctuator', '_') : buildNullNode()),
|
|
194
|
+
gap(hasGap ? buildToken(null, '$') : buildNullNode()),
|
|
108
195
|
t.nodeClose(),
|
|
109
196
|
],
|
|
110
197
|
{ expressions },
|
|
111
198
|
);
|
|
112
199
|
};
|
|
113
200
|
|
|
114
|
-
export const buildSpamMatcher = (
|
|
115
|
-
return
|
|
201
|
+
export const buildSpamMatcher = (name = null, value = null, attributes = null) => {
|
|
202
|
+
return buildTreeNodeMatcherOpen(buildNodeFlags(t.nodeFlags), null, name, value, attributes);
|
|
116
203
|
};
|
|
117
204
|
|
|
118
|
-
export const
|
|
205
|
+
export const buildTreeNodeMatcherOpen = (flags, type, name, literalValue, attributes = null) => {
|
|
119
206
|
const expressions = [];
|
|
120
207
|
const gap = buildFilledGapFunction(expressions);
|
|
121
208
|
|
|
122
|
-
if (!type) throw new Error();
|
|
209
|
+
if (!type && !name) throw new Error();
|
|
123
210
|
|
|
124
211
|
return treeFromStream(
|
|
125
212
|
(function* () {
|
|
126
|
-
yield t.nodeOpen(t.nodeFlags, '
|
|
213
|
+
yield t.nodeOpen(t.nodeFlags, 'TreeNodeMatcherOpen');
|
|
127
214
|
yield t.ref`openToken`;
|
|
128
|
-
yield gap(buildToken(
|
|
215
|
+
yield gap(buildToken(null, '<'));
|
|
129
216
|
yield t.ref`flags`;
|
|
130
217
|
yield gap(flags);
|
|
131
218
|
yield t.ref`type`;
|
|
132
|
-
yield gap(typeof type === 'string' ?
|
|
219
|
+
yield gap(typeof type === 'string' ? buildToken(null, type) : type);
|
|
220
|
+
yield t.ref`name`;
|
|
221
|
+
yield gap(typeof name === 'string' ? buildIdentifier(name) : name);
|
|
133
222
|
|
|
134
|
-
yield* when(literalValue, [t.ref`#`, ...buildSpace().tags]);
|
|
223
|
+
yield* when(literalValue, [t.ref`#`, ...Tags.traverse(buildSpace().value.tags)]);
|
|
135
224
|
|
|
136
225
|
yield t.ref`literalValue`;
|
|
137
226
|
yield gap(literalValue ? buildString(literalValue) : buildNullNode());
|
|
138
227
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (rootArr.length) {
|
|
228
|
+
if (!isEmpty(attributes)) {
|
|
142
229
|
yield t.ref`#`;
|
|
143
|
-
yield* buildSpace().tags;
|
|
230
|
+
yield* buildSpace().value.tags;
|
|
144
231
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
145
232
|
}
|
|
146
233
|
|
|
147
234
|
yield t.ref`selfClosingToken`;
|
|
148
|
-
yield gap(buildToken(
|
|
235
|
+
yield gap(buildToken(null, '/'));
|
|
149
236
|
yield t.ref`closeToken`;
|
|
150
|
-
yield gap(buildToken(
|
|
237
|
+
yield gap(buildToken(null, '>'));
|
|
151
238
|
yield t.nodeClose();
|
|
152
239
|
})(),
|
|
153
240
|
{ expressions },
|
|
154
241
|
);
|
|
155
242
|
};
|
|
156
243
|
|
|
157
|
-
export const
|
|
244
|
+
export const buildTreeNodeMatcher = (open, children) => {
|
|
158
245
|
const expressions = [];
|
|
159
246
|
const gap = buildFilledGapFunction(expressions);
|
|
160
247
|
|
|
248
|
+
let children_ = children;
|
|
249
|
+
|
|
250
|
+
if (children_) {
|
|
251
|
+
throw new Error('not implemented');
|
|
252
|
+
// if (isArray(children_)) {
|
|
253
|
+
// children_ = buildTreeNodeMatcherChildren(children_);
|
|
254
|
+
// }
|
|
255
|
+
}
|
|
256
|
+
|
|
161
257
|
return treeFromStream(
|
|
162
|
-
|
|
258
|
+
(function* () {
|
|
259
|
+
yield t.nodeOpen(t.nodeFlags, 'TreeNodeMatcher');
|
|
260
|
+
yield t.ref`open`;
|
|
261
|
+
yield gap(open);
|
|
262
|
+
if (!isEmpty(children_)) {
|
|
263
|
+
yield* interpolateFragment(children_, t.ref`children[]`, expressions);
|
|
264
|
+
}
|
|
265
|
+
yield t.nodeClose();
|
|
266
|
+
})(),
|
|
163
267
|
{ expressions },
|
|
164
268
|
);
|
|
165
269
|
};
|
|
166
270
|
|
|
167
|
-
export const buildReferenceMatcher = (type, name,
|
|
271
|
+
export const buildReferenceMatcher = (type = '.', name, flags) => {
|
|
168
272
|
const expressions = [];
|
|
169
273
|
const gap = buildFilledGapFunction(expressions);
|
|
170
274
|
|
|
275
|
+
if (isString(flags)) {
|
|
276
|
+
let array = flags.includes('[');
|
|
277
|
+
let intrinsic = flags.includes('*');
|
|
278
|
+
let hasGap = flags.includes('$');
|
|
279
|
+
let expression = flags.includes('+');
|
|
280
|
+
|
|
281
|
+
return buildReferenceMatcher(
|
|
282
|
+
type,
|
|
283
|
+
name,
|
|
284
|
+
buildReferenceFlags({ array, intrinsic, hasGap, expression }),
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
171
288
|
return treeFromStream(
|
|
172
289
|
(function* () {
|
|
173
290
|
yield t.nodeOpen(t.nodeFlags, 'ReferenceMatcher');
|
|
@@ -175,56 +292,31 @@ export const buildReferenceMatcher = (type, name, isArray, flags) => {
|
|
|
175
292
|
yield gap(type && buildKeyword(type));
|
|
176
293
|
yield t.ref`name`;
|
|
177
294
|
yield gap(name && buildIdentifier(name));
|
|
178
|
-
yield* (function* () {
|
|
179
|
-
if (isArray) {
|
|
180
|
-
yield t.ref`openIndexToken`;
|
|
181
|
-
yield gap(buildToken('Punctuator', '['));
|
|
182
|
-
yield t.ref`closeIndexToken`;
|
|
183
|
-
yield gap(buildToken('Punctuator', ']'));
|
|
184
|
-
}
|
|
185
|
-
})();
|
|
186
295
|
yield t.ref`flags`;
|
|
187
296
|
yield gap(flags);
|
|
188
297
|
yield t.ref`sigilToken`;
|
|
189
|
-
yield gap(buildToken(
|
|
298
|
+
yield gap(buildToken(null, ':'));
|
|
190
299
|
yield t.ref`#`;
|
|
191
|
-
yield* Tags.traverse(buildSpace().tags);
|
|
192
|
-
yield t.nodeClose();
|
|
193
|
-
})(),
|
|
194
|
-
{ expressions },
|
|
195
|
-
);
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
export const buildFragmentMatcher = (flags = buildNodeFlags({ fragment: true, cover: true })) => {
|
|
199
|
-
const expressions = [];
|
|
200
|
-
const gap = buildFilledGapFunction(expressions);
|
|
201
|
-
|
|
202
|
-
if (!flags) throw new Error();
|
|
203
|
-
|
|
204
|
-
return treeFromStream(
|
|
205
|
-
(function* () {
|
|
206
|
-
yield t.nodeOpen(t.fragmentFlags, 'FragmentMatcher');
|
|
207
|
-
yield t.ref`openToken`;
|
|
208
|
-
yield gap(buildToken('Punctuator', '<'));
|
|
209
|
-
yield t.ref`flags`;
|
|
210
|
-
yield gap(flags);
|
|
211
|
-
yield t.ref`closeToken`;
|
|
212
|
-
yield gap(buildToken('Punctuator', '/>'));
|
|
300
|
+
yield* Tags.traverse(buildSpace().value.tags);
|
|
213
301
|
yield t.nodeClose();
|
|
214
302
|
})(),
|
|
215
303
|
{ expressions },
|
|
216
304
|
);
|
|
217
305
|
};
|
|
218
306
|
|
|
219
|
-
export const buildToken = (
|
|
220
|
-
return treeFromStream([
|
|
307
|
+
export const buildToken = (name, value, attributes = {}) => {
|
|
308
|
+
return treeFromStream([
|
|
309
|
+
t.nodeOpen(t.tokenFlags, name, null, attributes),
|
|
310
|
+
t.lit(value),
|
|
311
|
+
t.nodeClose(),
|
|
312
|
+
]);
|
|
221
313
|
};
|
|
222
314
|
|
|
223
315
|
export const buildPunctuator = (value, attributes = {}) => {
|
|
224
|
-
return buildToken(
|
|
316
|
+
return buildToken(null, value, attributes);
|
|
225
317
|
};
|
|
226
318
|
|
|
227
|
-
export const buildOpenNodeTag = (flags,
|
|
319
|
+
export const buildOpenNodeTag = (flags, name = null, attributes) => {
|
|
228
320
|
const expressions = [];
|
|
229
321
|
const gap = buildFilledGapFunction(expressions);
|
|
230
322
|
|
|
@@ -234,10 +326,9 @@ export const buildOpenNodeTag = (flags, type = null, attributes) => {
|
|
|
234
326
|
yield gap(buildPunctuator('<'));
|
|
235
327
|
yield t.ref`flags`;
|
|
236
328
|
yield gap(buildNodeFlags(flags));
|
|
237
|
-
yield t.ref`
|
|
238
|
-
yield gap(
|
|
239
|
-
|
|
240
|
-
yield* when(rootArr.length, [t.ref`#`, gap(buildSpace())]);
|
|
329
|
+
yield t.ref`name`;
|
|
330
|
+
yield gap(name ? buildIdentifier(name) : buildNullNode());
|
|
331
|
+
yield* when(!isEmpty(attributes), [t.ref`#`, gap(buildSpace())]);
|
|
241
332
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
242
333
|
yield t.ref`closeToken`;
|
|
243
334
|
yield gap(buildPunctuator('>'));
|
|
@@ -254,20 +345,20 @@ export const buildDoctypeTag = (attributes) => {
|
|
|
254
345
|
(function* () {
|
|
255
346
|
yield t.nodeOpen(t.nodeFlags, 'DoctypeTag');
|
|
256
347
|
yield t.ref`openToken`;
|
|
257
|
-
yield gap(buildPunctuator('
|
|
348
|
+
yield gap(buildPunctuator('<!'));
|
|
258
349
|
yield t.ref`version`;
|
|
259
350
|
yield gap(buildToken('PositiveInteger', '0'));
|
|
260
351
|
yield t.ref`versionSeparator`;
|
|
261
|
-
yield gap(buildPunctuator('
|
|
352
|
+
yield gap(buildPunctuator(':'));
|
|
262
353
|
yield t.ref`doctype`;
|
|
263
354
|
yield gap(buildKeyword('cstml'));
|
|
264
355
|
yield t.nodeClose();
|
|
265
356
|
|
|
266
|
-
yield* when(
|
|
357
|
+
yield* when(!isEmpty(attributes), [t.ref`#`, ...buildSpace().value.tags]);
|
|
267
358
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
268
359
|
|
|
269
360
|
yield t.ref`closeToken`;
|
|
270
|
-
yield gap(buildToken(
|
|
361
|
+
yield gap(buildToken(null, '>'));
|
|
271
362
|
})(),
|
|
272
363
|
{ expressions },
|
|
273
364
|
);
|
|
@@ -285,19 +376,15 @@ export const buildIdentifierPath = (path) => {
|
|
|
285
376
|
return treeFromStream(
|
|
286
377
|
(function* () {
|
|
287
378
|
yield t.nodeOpen(t.nodeFlags, 'IdentifierPath');
|
|
288
|
-
yield t.ref`segments[]`;
|
|
289
|
-
yield t.arr();
|
|
290
|
-
yield t.ref`separatorTokens[]`;
|
|
291
|
-
yield t.arr();
|
|
292
379
|
|
|
293
380
|
yield* path_
|
|
294
|
-
.flatMap((
|
|
381
|
+
.flatMap((segment) => [
|
|
295
382
|
t.ref`segments[]`,
|
|
296
|
-
gap(buildIdentifier(name)),
|
|
297
|
-
t.ref
|
|
298
|
-
gap(buildToken(
|
|
383
|
+
gap(segment.type ? buildPunctuator(segment.type) : buildIdentifier(segment.name)),
|
|
384
|
+
t.ref`#separatorTokens`,
|
|
385
|
+
gap(buildToken(null, '.')),
|
|
299
386
|
])
|
|
300
|
-
.slice(0, -
|
|
387
|
+
.slice(0, -2);
|
|
301
388
|
|
|
302
389
|
yield t.nodeClose();
|
|
303
390
|
})(),
|
|
@@ -319,9 +406,9 @@ export const buildCloseNodeTag = () => {
|
|
|
319
406
|
[
|
|
320
407
|
t.nodeOpen(t.nodeFlags, 'CloseNodeTag'),
|
|
321
408
|
t.ref`openToken`,
|
|
322
|
-
gap(buildToken(
|
|
409
|
+
gap(buildToken(null, '</')),
|
|
323
410
|
t.ref`closeToken`,
|
|
324
|
-
gap(buildToken(
|
|
411
|
+
gap(buildToken(null, '>')),
|
|
325
412
|
t.nodeClose(),
|
|
326
413
|
],
|
|
327
414
|
{ expressions },
|
|
@@ -369,7 +456,7 @@ export const buildIdentifier = (name) => {
|
|
|
369
456
|
yield t.nodeOpen(t.nodeFlags, 'Identifier');
|
|
370
457
|
|
|
371
458
|
yield t.ref`openToken`;
|
|
372
|
-
yield gap(buildToken(
|
|
459
|
+
yield gap(buildToken(null, '`'));
|
|
373
460
|
yield t.ref`content`;
|
|
374
461
|
yield t.nodeOpen(t.tokenFlags, 'IdentifierContent');
|
|
375
462
|
|
|
@@ -388,9 +475,9 @@ export const buildIdentifier = (name) => {
|
|
|
388
475
|
let value = buildKeyword(chr);
|
|
389
476
|
|
|
390
477
|
yield t.ref`@`;
|
|
391
|
-
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', { cooked: chr });
|
|
478
|
+
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', null, { cooked: chr });
|
|
392
479
|
yield t.ref`escape`;
|
|
393
|
-
yield gap(buildToken(
|
|
480
|
+
yield gap(buildToken(null, '\\'));
|
|
394
481
|
yield t.ref`value`;
|
|
395
482
|
yield gap(value);
|
|
396
483
|
yield t.nodeClose();
|
|
@@ -405,7 +492,7 @@ export const buildIdentifier = (name) => {
|
|
|
405
492
|
yield t.nodeClose();
|
|
406
493
|
|
|
407
494
|
yield t.ref`closeToken`;
|
|
408
|
-
yield gap(buildToken(
|
|
495
|
+
yield gap(buildToken(null, '`'));
|
|
409
496
|
yield t.nodeClose();
|
|
410
497
|
})(),
|
|
411
498
|
{ expressions },
|
|
@@ -418,7 +505,7 @@ export const buildIdentifierContent = (value) => {
|
|
|
418
505
|
};
|
|
419
506
|
|
|
420
507
|
export const buildKeyword = (name) => {
|
|
421
|
-
return buildToken(
|
|
508
|
+
return buildToken(null, name);
|
|
422
509
|
};
|
|
423
510
|
|
|
424
511
|
export const buildCall = (verb, args) => {
|
|
@@ -448,7 +535,7 @@ export const buildProperty = (key, value) => {
|
|
|
448
535
|
yield t.ref`key`;
|
|
449
536
|
yield gap(key);
|
|
450
537
|
yield t.ref`mapOperator`;
|
|
451
|
-
yield gap(buildToken(
|
|
538
|
+
yield gap(buildToken(null, ':'));
|
|
452
539
|
yield t.ref`#`;
|
|
453
540
|
yield gap(buildSpace());
|
|
454
541
|
yield t.ref`value`;
|
|
@@ -478,7 +565,7 @@ export const buildInteger = (value, base = 10) => {
|
|
|
478
565
|
|
|
479
566
|
return treeFromStream(
|
|
480
567
|
concat(
|
|
481
|
-
[t.nodeOpen(t.nodeFlags, 'Integer')
|
|
568
|
+
[t.nodeOpen(t.nodeFlags, 'Integer')],
|
|
482
569
|
digits.flatMap((digit) => [t.ref`digits[]`, gap(buildDigit(digit))]),
|
|
483
570
|
[t.nodeClose()],
|
|
484
571
|
),
|
|
@@ -504,9 +591,9 @@ export const buildInfinity = (value) => {
|
|
|
504
591
|
[
|
|
505
592
|
t.nodeOpen(t.nodeFlags, 'Infinity'),
|
|
506
593
|
t.ref`sign`,
|
|
507
|
-
gap(buildToken(
|
|
594
|
+
gap(buildToken(null, sign)),
|
|
508
595
|
t.ref`value`,
|
|
509
|
-
gap(buildToken(
|
|
596
|
+
gap(buildToken(null, 'Infinity')),
|
|
510
597
|
t.nodeClose(),
|
|
511
598
|
],
|
|
512
599
|
{ expressions },
|
|
@@ -533,11 +620,11 @@ export const buildString = (value) => {
|
|
|
533
620
|
[
|
|
534
621
|
t.nodeOpen(t.nodeFlags, 'String'),
|
|
535
622
|
t.ref`openToken`,
|
|
536
|
-
gap(buildToken(
|
|
623
|
+
gap(buildToken(null, '"')),
|
|
537
624
|
t.ref`content`,
|
|
538
625
|
gap(buildToken('StringContent', value)),
|
|
539
626
|
t.ref`closeToken`,
|
|
540
|
-
gap(buildToken(
|
|
627
|
+
gap(buildToken(null, '"')),
|
|
541
628
|
t.nodeClose(),
|
|
542
629
|
],
|
|
543
630
|
{ expressions },
|
|
@@ -551,7 +638,7 @@ export const buildString = (value) => {
|
|
|
551
638
|
(function* () {
|
|
552
639
|
yield t.nodeOpen(t.nodeFlags, 'String');
|
|
553
640
|
yield t.ref`openToken`;
|
|
554
|
-
const tok = buildToken(
|
|
641
|
+
const tok = buildToken(null, "'");
|
|
555
642
|
yield gap(tok);
|
|
556
643
|
yield t.ref`content`;
|
|
557
644
|
yield t.nodeOpen(t.tokenFlags, 'StringContent');
|
|
@@ -586,8 +673,6 @@ export const buildString = (value) => {
|
|
|
586
673
|
t.nodeOpen(t.nodeFlags, 'EscapeCode'),
|
|
587
674
|
t.ref`sigilToken`,
|
|
588
675
|
gap(buildKeyword(escapables[chr])),
|
|
589
|
-
t.ref`digits[]`,
|
|
590
|
-
t.arr(),
|
|
591
676
|
t.nodeClose(),
|
|
592
677
|
],
|
|
593
678
|
{ expressions },
|
|
@@ -602,8 +687,6 @@ export const buildString = (value) => {
|
|
|
602
687
|
t.nodeOpen(t.nodeFlags, 'EscapeCode'),
|
|
603
688
|
t.ref`sigilToken`,
|
|
604
689
|
gap(buildKeyword('u')),
|
|
605
|
-
t.ref`digits[]`,
|
|
606
|
-
t.arr(),
|
|
607
690
|
[...hexDigits].flatMap((digit) => [t.ref`digits[]`, gap(buildDigit(digit))]),
|
|
608
691
|
t.nodeClose(),
|
|
609
692
|
],
|
|
@@ -614,9 +697,9 @@ export const buildString = (value) => {
|
|
|
614
697
|
}
|
|
615
698
|
|
|
616
699
|
yield t.ref`@`;
|
|
617
|
-
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', { cooked: chr });
|
|
700
|
+
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', null, { cooked: chr });
|
|
618
701
|
yield t.ref`escape`;
|
|
619
|
-
yield gap(buildToken(
|
|
702
|
+
yield gap(buildToken(null, '\\'));
|
|
620
703
|
yield t.ref`value`;
|
|
621
704
|
yield gap(value);
|
|
622
705
|
yield t.nodeClose();
|
|
@@ -643,7 +726,7 @@ export const buildString = (value) => {
|
|
|
643
726
|
|
|
644
727
|
yield t.nodeClose();
|
|
645
728
|
yield t.ref`closeToken`;
|
|
646
|
-
yield gap(buildToken(
|
|
729
|
+
yield gap(buildToken(null, "'"));
|
|
647
730
|
yield t.nodeClose();
|
|
648
731
|
})(),
|
|
649
732
|
{ expressions },
|
|
@@ -658,7 +741,7 @@ export const buildBoolean = (value) => {
|
|
|
658
741
|
[
|
|
659
742
|
t.nodeOpen(t.nodeFlags, 'Boolean'),
|
|
660
743
|
t.ref`sigilToken`,
|
|
661
|
-
gap(buildToken(
|
|
744
|
+
gap(buildToken(null, value ? 'true' : 'false')),
|
|
662
745
|
t.nodeClose(),
|
|
663
746
|
],
|
|
664
747
|
{ expressions },
|
|
@@ -673,7 +756,7 @@ export const buildNull = () => {
|
|
|
673
756
|
[
|
|
674
757
|
t.nodeOpen(t.nodeFlags, 'Null'),
|
|
675
758
|
t.ref`sigilToken`,
|
|
676
|
-
gap(buildToken(
|
|
759
|
+
gap(buildToken(null, 'null')),
|
|
677
760
|
t.nodeClose(),
|
|
678
761
|
],
|
|
679
762
|
{ expressions },
|
|
@@ -688,7 +771,7 @@ export const buildUndefined = () => {
|
|
|
688
771
|
[
|
|
689
772
|
t.nodeOpen(t.nodeFlags, 'Undefined'),
|
|
690
773
|
t.ref`sigilToken`,
|
|
691
|
-
gap(buildToken(
|
|
774
|
+
gap(buildToken(null, 'undefined')),
|
|
692
775
|
t.nodeClose(),
|
|
693
776
|
],
|
|
694
777
|
{ expressions },
|
|
@@ -703,7 +786,7 @@ export const buildNullTag = () => {
|
|
|
703
786
|
[
|
|
704
787
|
t.nodeOpen(t.nodeFlags, 'NullTag'),
|
|
705
788
|
t.ref`sigilToken`,
|
|
706
|
-
gap(buildToken(
|
|
789
|
+
gap(buildToken(null, 'null')),
|
|
707
790
|
t.nodeClose(),
|
|
708
791
|
],
|
|
709
792
|
{ expressions },
|
|
@@ -718,10 +801,14 @@ export const buildArray = (elements) => {
|
|
|
718
801
|
(function* () {
|
|
719
802
|
yield t.nodeOpen(t.nodeFlags, 'Array');
|
|
720
803
|
yield t.ref`openToken`;
|
|
721
|
-
yield gap(buildToken(
|
|
722
|
-
yield* interpolateFragment(
|
|
804
|
+
yield gap(buildToken(null, '['));
|
|
805
|
+
yield* interpolateFragment(
|
|
806
|
+
isArray(elements) ? buildArrayElements(elements) : elements,
|
|
807
|
+
t.ref`elements[]`,
|
|
808
|
+
expressions,
|
|
809
|
+
);
|
|
723
810
|
yield t.ref`closeToken`;
|
|
724
|
-
yield gap(buildToken(
|
|
811
|
+
yield gap(buildToken(null, ']'));
|
|
725
812
|
yield t.nodeClose();
|
|
726
813
|
})(),
|
|
727
814
|
{ expressions },
|
|
@@ -732,28 +819,24 @@ export const buildArrayElements = (values) => {
|
|
|
732
819
|
const expressions = [];
|
|
733
820
|
return treeFromStream(
|
|
734
821
|
(function* () {
|
|
735
|
-
yield t.
|
|
736
|
-
yield
|
|
737
|
-
yield* buildCommaSeparatedList(values, t.ref`.[]`, expressions);
|
|
822
|
+
yield t.fragOpen();
|
|
823
|
+
yield* buildSeparatedList(',', values, t.ref`elements[]`, expressions);
|
|
738
824
|
yield t.nodeClose();
|
|
739
825
|
})(),
|
|
740
826
|
{ expressions },
|
|
741
827
|
);
|
|
742
828
|
};
|
|
743
829
|
|
|
744
|
-
export function*
|
|
830
|
+
export function* buildSeparatedList(separator, values, ref, expressions) {
|
|
745
831
|
const gap = buildFilledGapFunction(expressions);
|
|
746
832
|
|
|
747
|
-
if (!ref.value.
|
|
748
|
-
|
|
749
|
-
yield freeze({ ...ref });
|
|
750
|
-
yield t.arr();
|
|
833
|
+
if (!ref.value.flags.array) throw new Error();
|
|
751
834
|
|
|
752
835
|
let first = true;
|
|
753
836
|
for (const value of values) {
|
|
754
837
|
if (!first) {
|
|
755
|
-
yield t.buildReferenceTag('#');
|
|
756
|
-
yield gap(buildToken(
|
|
838
|
+
yield t.buildReferenceTag('#', 'separatorTokens');
|
|
839
|
+
yield gap(buildToken(null, separator));
|
|
757
840
|
}
|
|
758
841
|
yield freeze({ ...ref });
|
|
759
842
|
yield gap(value || buildNullNode());
|
|
@@ -766,8 +849,8 @@ export const buildObjectProperties = (properties) => {
|
|
|
766
849
|
|
|
767
850
|
return treeFromStream(
|
|
768
851
|
concat(
|
|
769
|
-
[t.doctype({
|
|
770
|
-
|
|
852
|
+
[t.doctype({ 'bablr-lang': l.Instruction }), t.fragOpen(t.nodeFlags)],
|
|
853
|
+
buildSeparatedList(',', properties, t.ref`properties[]`, expressions),
|
|
771
854
|
[t.nodeClose()],
|
|
772
855
|
),
|
|
773
856
|
{ expressions },
|
|
@@ -782,12 +865,16 @@ export const buildObject = (properties) => {
|
|
|
782
865
|
(function* () {
|
|
783
866
|
yield t.nodeOpen(t.nodeFlags, 'Object');
|
|
784
867
|
yield t.ref`openToken`;
|
|
785
|
-
yield gap(buildToken(
|
|
868
|
+
yield gap(buildToken(null, '{'));
|
|
786
869
|
|
|
787
|
-
yield* interpolateFragment(
|
|
870
|
+
yield* interpolateFragment(
|
|
871
|
+
isArray(properties) ? buildObjectProperties(properties) : properties,
|
|
872
|
+
t.ref`properties[]`,
|
|
873
|
+
expressions,
|
|
874
|
+
);
|
|
788
875
|
|
|
789
876
|
yield t.ref`closeToken`;
|
|
790
|
-
yield gap(buildToken(
|
|
877
|
+
yield gap(buildToken(null, '}'));
|
|
791
878
|
yield t.nodeClose();
|
|
792
879
|
})(),
|
|
793
880
|
{ expressions },
|
|
@@ -802,14 +889,14 @@ export const buildPattern = (alternatives, flags) => {
|
|
|
802
889
|
(function* () {
|
|
803
890
|
yield t.nodeOpen(t.nodeFlags, 'Pattern');
|
|
804
891
|
yield t.ref`openToken`;
|
|
805
|
-
yield gap(buildToken(
|
|
892
|
+
yield gap(buildToken(null, '/'));
|
|
806
893
|
|
|
807
894
|
yield* interpolateFragment(alternatives, t.ref`alternatives[]`, expressions);
|
|
808
895
|
|
|
809
896
|
yield t.ref`closeToken`;
|
|
810
|
-
yield gap(buildToken(
|
|
897
|
+
yield gap(buildToken(null, '/'));
|
|
811
898
|
yield t.ref`flags`;
|
|
812
|
-
yield gap(flags ||
|
|
899
|
+
yield gap(flags || buildRegexFlags());
|
|
813
900
|
yield t.nodeClose();
|
|
814
901
|
})(),
|
|
815
902
|
{ expressions },
|
|
@@ -824,12 +911,12 @@ export const buildRegexGroup = (alternatives, flags) => {
|
|
|
824
911
|
(function* () {
|
|
825
912
|
yield t.nodeOpen(t.nodeFlags, 'Group');
|
|
826
913
|
yield t.ref`openToken`;
|
|
827
|
-
yield gap(buildToken(
|
|
914
|
+
yield gap(buildToken(null, '(?:'));
|
|
828
915
|
|
|
829
916
|
yield* interpolateFragment(alternatives, t.ref`alternatives[]`, expressions);
|
|
830
917
|
|
|
831
918
|
yield t.ref`closeToken`;
|
|
832
|
-
yield gap(buildToken(
|
|
919
|
+
yield gap(buildToken(null, ')'));
|
|
833
920
|
yield t.ref`flags`;
|
|
834
921
|
yield gap(flags || buildReferenceFlags());
|
|
835
922
|
yield t.nodeClose();
|
|
@@ -856,9 +943,9 @@ export const buildRegexFlags = (flags = '') => {
|
|
|
856
943
|
yield t.nodeOpen(t.nodeFlags, 'Flags');
|
|
857
944
|
|
|
858
945
|
for (const { 0: name, 1: chr } of Object.entries(flagCharacters)) {
|
|
859
|
-
yield t.buildReferenceTag(name + 'Token');
|
|
946
|
+
yield t.buildReferenceTag(null, name + 'Token');
|
|
860
947
|
|
|
861
|
-
yield gap(flags.includes(chr) ? buildToken(
|
|
948
|
+
yield gap(flags.includes(chr) ? buildToken(null, chr) : buildNullNode());
|
|
862
949
|
}
|
|
863
950
|
yield t.nodeClose();
|
|
864
951
|
})(),
|
|
@@ -885,18 +972,13 @@ export const buildAlternatives = (alternatives = []) => {
|
|
|
885
972
|
|
|
886
973
|
return treeFromStream(
|
|
887
974
|
(function* () {
|
|
888
|
-
yield t.
|
|
889
|
-
yield t.nodeOpen(t.nodeFlags);
|
|
890
|
-
yield t.ref`.[]`;
|
|
891
|
-
yield t.arr();
|
|
892
|
-
yield t.ref`separatorTokens[]`;
|
|
893
|
-
yield t.arr();
|
|
975
|
+
yield t.fragOpen();
|
|
894
976
|
|
|
895
977
|
yield* alternatives
|
|
896
978
|
.flatMap((alt) => [
|
|
897
|
-
t.ref
|
|
979
|
+
t.ref`alternatives[]`,
|
|
898
980
|
gap(alt),
|
|
899
|
-
t.ref
|
|
981
|
+
t.ref`#separatorTokens`,
|
|
900
982
|
gap(buildPunctuator('|')),
|
|
901
983
|
])
|
|
902
984
|
.slice(0, -2);
|
|
@@ -915,9 +997,9 @@ export const buildRegexGap = () => {
|
|
|
915
997
|
[
|
|
916
998
|
t.nodeOpen(t.nodeFlags, 'Gap'),
|
|
917
999
|
t.ref`escapeToken`,
|
|
918
|
-
gap(buildToken(
|
|
1000
|
+
gap(buildToken(null, '\\')),
|
|
919
1001
|
t.ref`value`,
|
|
920
|
-
gap(buildToken(
|
|
1002
|
+
gap(buildToken(null, 'g')),
|
|
921
1003
|
t.nodeClose(),
|
|
922
1004
|
],
|
|
923
1005
|
{ expressions },
|
|
@@ -930,14 +1012,33 @@ export const buildElements = (elements) => {
|
|
|
930
1012
|
|
|
931
1013
|
return treeFromStream(
|
|
932
1014
|
concat(
|
|
933
|
-
[t.doctype({
|
|
934
|
-
elements.flatMap((el) => [t.ref
|
|
1015
|
+
[t.doctype({ 'bablr-lang': l.Instruction }), t.fragOpen()],
|
|
1016
|
+
elements.flatMap((el) => [t.ref`elements[]+`, gap(el)]),
|
|
935
1017
|
[t.nodeClose()],
|
|
936
1018
|
),
|
|
937
1019
|
{ expressions },
|
|
938
1020
|
);
|
|
939
1021
|
};
|
|
940
1022
|
|
|
1023
|
+
export const buildCharacterClass = (elements, negate = false) => {
|
|
1024
|
+
const expressions = [];
|
|
1025
|
+
const gap = buildFilledGapFunction(expressions);
|
|
1026
|
+
|
|
1027
|
+
return treeFromStream(
|
|
1028
|
+
(function* () {
|
|
1029
|
+
yield t.nodeOpen(t.nodeFlags, 'CharacterClass', null, { negate });
|
|
1030
|
+
yield t.ref`openToken`;
|
|
1031
|
+
yield gap(buildToken(null, '['));
|
|
1032
|
+
|
|
1033
|
+
yield* interpolateFragment(elements, t.ref`elements[]`, expressions);
|
|
1034
|
+
yield t.ref`closeToken`;
|
|
1035
|
+
yield gap(buildToken(null, ']'));
|
|
1036
|
+
yield t.nodeClose();
|
|
1037
|
+
})(),
|
|
1038
|
+
{ expressions },
|
|
1039
|
+
);
|
|
1040
|
+
};
|
|
1041
|
+
|
|
941
1042
|
export const buildJSExpressionDeep = (expr) => {
|
|
942
1043
|
if (expr === null) {
|
|
943
1044
|
return buildNull();
|
|
@@ -990,13 +1091,13 @@ export const buildTaggedString = (tag, content) => {
|
|
|
990
1091
|
[
|
|
991
1092
|
t.buildOpenNodeTag(t.nodeFlags, 'SpamexString'),
|
|
992
1093
|
t.buildReferenceTag('sigilToken'),
|
|
993
|
-
gap(buildToken(
|
|
1094
|
+
gap(buildToken(null, tag)),
|
|
994
1095
|
t.buildReferenceTag('openToken'),
|
|
995
|
-
gap(buildToken(
|
|
1096
|
+
gap(buildToken(null, "'")),
|
|
996
1097
|
t.buildReferenceTag('content'),
|
|
997
1098
|
gap(content),
|
|
998
1099
|
t.buildReferenceTag('closeToken'),
|
|
999
|
-
gap(buildToken(
|
|
1100
|
+
gap(buildToken(null, "'")),
|
|
1000
1101
|
t.buildCloseNodeTag(),
|
|
1001
1102
|
],
|
|
1002
1103
|
{ expressions },
|
|
@@ -1011,25 +1112,6 @@ export const buildRegexString = (content) => {
|
|
|
1011
1112
|
return buildTaggedString('re', content);
|
|
1012
1113
|
};
|
|
1013
1114
|
|
|
1014
|
-
export const buildPropertyMatcher = (refMatcher, bindingMatcher, nodeMatcher) => {
|
|
1015
|
-
const expressions = [];
|
|
1016
|
-
const gap = buildFilledGapFunction(expressions);
|
|
1017
|
-
|
|
1018
|
-
return treeFromStream(
|
|
1019
|
-
[
|
|
1020
|
-
t.nodeOpen(t.nodeFlags, 'PropertyMatcher'),
|
|
1021
|
-
t.ref`refMatcher`,
|
|
1022
|
-
gap(refMatcher || buildNullNode()),
|
|
1023
|
-
t.ref`bindingMatcher`,
|
|
1024
|
-
gap(bindingMatcher || buildNullNode()),
|
|
1025
|
-
t.ref`nodeMatcher`,
|
|
1026
|
-
gap(nodeMatcher),
|
|
1027
|
-
t.nodeClose(),
|
|
1028
|
-
],
|
|
1029
|
-
{ expressions },
|
|
1030
|
-
);
|
|
1031
|
-
};
|
|
1032
|
-
|
|
1033
1115
|
export const buildGapNodeMatcher = () => {
|
|
1034
1116
|
return buildToken('GapNodeMatcher', '<//>');
|
|
1035
1117
|
};
|