@bablr/helpers 0.22.0 → 0.23.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 +156 -202
- package/lib/decorators.js +0 -3
- package/lib/enhancers.js +3 -6
- package/lib/grammar.js +17 -35
- package/lib/index.js +0 -1
- package/lib/object.js +14 -10
- package/lib/productions.js +8 -6
- package/lib/productions.macro.js +7 -6
- package/lib/source.js +1 -1
- package/lib/tree.js +1 -3
- package/lib/trivia.js +208 -24
- package/package.json +7 -8
- package/lib/stream.js +0 -86
package/lib/builders.js
CHANGED
|
@@ -2,46 +2,39 @@
|
|
|
2
2
|
import { interpolateFragment, buildFilledGapFunction } from '@bablr/agast-helpers/template';
|
|
3
3
|
import {
|
|
4
4
|
buildNullNode,
|
|
5
|
-
|
|
5
|
+
getRootArray,
|
|
6
6
|
treeFromStreamSync as treeFromStream,
|
|
7
7
|
} from '@bablr/agast-helpers/tree';
|
|
8
8
|
import { buildLiteralTag as agastBuildLiteralTag } from '@bablr/agast-helpers/builders';
|
|
9
9
|
import * as t from '@bablr/agast-helpers/shorthand';
|
|
10
|
-
import * as sumtree from '@bablr/agast-helpers/
|
|
10
|
+
import * as sumtree from '@bablr/agast-helpers/children';
|
|
11
11
|
import * as l from '@bablr/agast-vm-helpers/languages';
|
|
12
12
|
import { concat } from '@bablr/agast-vm-helpers/iterable';
|
|
13
13
|
|
|
14
|
-
const {
|
|
14
|
+
const { freeze } = Object;
|
|
15
15
|
const { isArray } = Array;
|
|
16
16
|
|
|
17
17
|
const when = (condition, value) => (condition ? value : { *[Symbol.iterator]() {} });
|
|
18
18
|
|
|
19
19
|
const isString = (val) => typeof val === 'string';
|
|
20
20
|
|
|
21
|
-
export const buildReferenceTag = (
|
|
22
|
-
name,
|
|
23
|
-
isArray = false,
|
|
24
|
-
flags = t.referenceFlags,
|
|
25
|
-
index = null,
|
|
26
|
-
) => {
|
|
21
|
+
export const buildReferenceTag = (name, isArray = false, flags = t.referenceFlags) => {
|
|
27
22
|
let expressions = [];
|
|
28
23
|
const gap = buildFilledGapFunction(expressions);
|
|
29
24
|
|
|
30
25
|
return treeFromStream(
|
|
31
26
|
[
|
|
32
|
-
t.nodeOpen(t.nodeFlags,
|
|
27
|
+
t.nodeOpen(t.nodeFlags, 'ReferenceTag'),
|
|
33
28
|
t.ref`name`,
|
|
34
29
|
gap(name ? buildIdentifier(name) : buildNullNode()),
|
|
35
30
|
t.ref`openIndexToken`,
|
|
36
|
-
gap(isArray ? buildToken(
|
|
37
|
-
t.ref`index`,
|
|
38
|
-
gap(index || buildNullNode()),
|
|
31
|
+
gap(isArray ? buildToken('Punctuator', '[') : buildNullNode()),
|
|
39
32
|
t.ref`closeIndexToken`,
|
|
40
|
-
gap(isArray ? buildToken(
|
|
33
|
+
gap(isArray ? buildToken('Punctuator', ']') : buildNullNode()),
|
|
41
34
|
t.ref`flags`,
|
|
42
35
|
gap(flags ? buildReferenceFlags(flags) : buildNullNode()),
|
|
43
36
|
t.ref`sigilToken`,
|
|
44
|
-
gap(buildToken(
|
|
37
|
+
gap(buildToken('Punctuator', ':')),
|
|
45
38
|
t.nodeClose(),
|
|
46
39
|
],
|
|
47
40
|
{ expressions },
|
|
@@ -54,9 +47,9 @@ export const buildGapTag = () => {
|
|
|
54
47
|
|
|
55
48
|
return treeFromStream(
|
|
56
49
|
[
|
|
57
|
-
t.nodeOpen(t.nodeFlags,
|
|
50
|
+
t.nodeOpen(t.nodeFlags, 'ShiftTag'),
|
|
58
51
|
t.ref`sigilToken`,
|
|
59
|
-
gap(buildToken(
|
|
52
|
+
gap(buildToken('Punctuator', '<//>')),
|
|
60
53
|
t.nodeClose(),
|
|
61
54
|
],
|
|
62
55
|
{ expressions },
|
|
@@ -69,9 +62,9 @@ export const buildShiftTag = () => {
|
|
|
69
62
|
|
|
70
63
|
return treeFromStream(
|
|
71
64
|
[
|
|
72
|
-
t.nodeOpen(t.nodeFlags,
|
|
65
|
+
t.nodeOpen(t.nodeFlags, 'ShiftTag'),
|
|
73
66
|
t.ref`sigilToken`,
|
|
74
|
-
gap(buildToken(
|
|
67
|
+
gap(buildToken('Punctuator', '^^^')),
|
|
75
68
|
t.nodeClose(),
|
|
76
69
|
],
|
|
77
70
|
{ expressions },
|
|
@@ -85,11 +78,11 @@ export const buildReferenceFlags = (flags = t.referenceFlags) => {
|
|
|
85
78
|
|
|
86
79
|
return treeFromStream(
|
|
87
80
|
[
|
|
88
|
-
t.nodeOpen(t.nodeFlags,
|
|
81
|
+
t.nodeOpen(t.nodeFlags, 'ReferenceFlags'),
|
|
89
82
|
t.ref`expressionToken`,
|
|
90
|
-
gap(expression ? buildToken(
|
|
83
|
+
gap(expression ? buildToken('Punctuator', '+') : buildNullNode()),
|
|
91
84
|
t.ref`hasGapToken`,
|
|
92
|
-
gap(hasGap ? buildToken(
|
|
85
|
+
gap(hasGap ? buildToken('Punctuator', '$') : buildNullNode()),
|
|
93
86
|
t.nodeClose(),
|
|
94
87
|
],
|
|
95
88
|
{ expressions },
|
|
@@ -97,17 +90,21 @@ export const buildReferenceFlags = (flags = t.referenceFlags) => {
|
|
|
97
90
|
};
|
|
98
91
|
|
|
99
92
|
export const buildNodeFlags = (flags = t.nodeFlags) => {
|
|
100
|
-
const { token = null, hasGap = null } = flags;
|
|
93
|
+
const { token = null, hasGap = null, fragment = null, cover = null } = flags;
|
|
101
94
|
let expressions = [];
|
|
102
95
|
const gap = buildFilledGapFunction(expressions);
|
|
103
96
|
|
|
104
97
|
return treeFromStream(
|
|
105
98
|
[
|
|
106
|
-
t.nodeOpen(t.nodeFlags,
|
|
107
|
-
t.ref`
|
|
108
|
-
gap(token ? buildToken(
|
|
99
|
+
t.nodeOpen(t.nodeFlags, 'NodeFlags'),
|
|
100
|
+
t.ref`tokenToken`,
|
|
101
|
+
gap(token ? buildToken('Punctuator', '*') : buildNullNode()),
|
|
109
102
|
t.ref`hasGapToken`,
|
|
110
|
-
gap(hasGap ? buildToken(
|
|
103
|
+
gap(hasGap ? buildToken('Punctuator', '$') : buildNullNode()),
|
|
104
|
+
t.ref`fragmentToken`,
|
|
105
|
+
gap(fragment ? buildToken('Punctuator', '_') : buildNullNode()),
|
|
106
|
+
t.ref`coverFragmentToken`,
|
|
107
|
+
gap(cover ? buildToken('Punctuator', '_') : buildNullNode()),
|
|
111
108
|
t.nodeClose(),
|
|
112
109
|
],
|
|
113
110
|
{ expressions },
|
|
@@ -115,10 +112,10 @@ export const buildNodeFlags = (flags = t.nodeFlags) => {
|
|
|
115
112
|
};
|
|
116
113
|
|
|
117
114
|
export const buildSpamMatcher = (type = null, value = null, attributes = null) => {
|
|
118
|
-
return buildOpenNodeMatcher(t.nodeFlags, null, type, value, attributes);
|
|
115
|
+
return buildOpenNodeMatcher(buildNodeFlags(t.nodeFlags), null, type, value, attributes);
|
|
119
116
|
};
|
|
120
117
|
|
|
121
|
-
export const buildOpenNodeMatcher = (flags,
|
|
118
|
+
export const buildOpenNodeMatcher = (flags, type, intrinsicValue, attributes = null) => {
|
|
122
119
|
const expressions = [];
|
|
123
120
|
const gap = buildFilledGapFunction(expressions);
|
|
124
121
|
|
|
@@ -126,48 +123,33 @@ export const buildOpenNodeMatcher = (flags, language, type, intrinsicValue, attr
|
|
|
126
123
|
|
|
127
124
|
if (!type) throw new Error();
|
|
128
125
|
|
|
129
|
-
if (isString(language)) {
|
|
130
|
-
language_ = language;
|
|
131
|
-
} else {
|
|
132
|
-
let lArr = isString(language) ? language : language ? [...language] : [];
|
|
133
|
-
|
|
134
|
-
language_ = lArr.length === 0 ? null : lArr;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
126
|
return treeFromStream(
|
|
138
127
|
(function* () {
|
|
139
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
128
|
+
yield t.nodeOpen(t.nodeFlags, 'OpenNodeMatcher');
|
|
140
129
|
yield t.ref`openToken`;
|
|
141
|
-
yield gap(buildToken(
|
|
130
|
+
yield gap(buildToken('Punctuator', '<'));
|
|
142
131
|
yield t.ref`flags`;
|
|
143
|
-
yield gap(
|
|
144
|
-
yield t.ref`language`;
|
|
145
|
-
yield gap(language_ ? buildLanguage(language_) : buildNullNode());
|
|
146
|
-
yield t.ref`languageSeparator`;
|
|
147
|
-
yield gap(language_ && type ? buildToken(l.CSTML, 'Punctuator', ':') : buildNullNode());
|
|
132
|
+
yield gap(flags);
|
|
148
133
|
yield t.ref`type`;
|
|
149
|
-
yield gap(
|
|
150
|
-
typeof type === 'string'
|
|
151
|
-
? ['.', '#', '@'].includes(type)
|
|
152
|
-
? buildKeyword(type)
|
|
153
|
-
: buildIdentifier(type)
|
|
154
|
-
: type,
|
|
155
|
-
);
|
|
134
|
+
yield gap(typeof type === 'string' ? buildIdentifier(type) : type);
|
|
156
135
|
|
|
157
136
|
yield* when(intrinsicValue, [t.ref`#`, ...buildSpace().children]);
|
|
158
137
|
|
|
159
138
|
yield t.ref`intrinsicValue`;
|
|
160
139
|
yield gap(intrinsicValue ? buildString(intrinsicValue) : buildNullNode());
|
|
161
140
|
|
|
162
|
-
|
|
163
|
-
|
|
141
|
+
let rootArr = getRootArray(attributes);
|
|
142
|
+
|
|
143
|
+
if (rootArr.length) {
|
|
144
|
+
yield t.ref`#`;
|
|
145
|
+
yield* buildSpace().children;
|
|
164
146
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
165
147
|
}
|
|
166
148
|
|
|
167
149
|
yield t.ref`selfClosingTagToken`;
|
|
168
|
-
yield gap(buildToken(
|
|
150
|
+
yield gap(buildToken('Punctuator', '/'));
|
|
169
151
|
yield t.ref`closeToken`;
|
|
170
|
-
yield gap(buildToken(
|
|
152
|
+
yield gap(buildToken('Punctuator', '>'));
|
|
171
153
|
yield t.nodeClose();
|
|
172
154
|
})(),
|
|
173
155
|
{ expressions },
|
|
@@ -179,32 +161,34 @@ export const buildBasicNodeMatcher = (open) => {
|
|
|
179
161
|
const gap = buildFilledGapFunction(expressions);
|
|
180
162
|
|
|
181
163
|
return treeFromStream(
|
|
182
|
-
[t.nodeOpen(t.nodeFlags,
|
|
164
|
+
[t.nodeOpen(t.nodeFlags, 'BasicNodeMatcher'), t.ref`open`, gap(open), t.nodeClose()],
|
|
183
165
|
{ expressions },
|
|
184
166
|
);
|
|
185
167
|
};
|
|
186
168
|
|
|
187
|
-
export const buildReferenceMatcher = (name, isArray, flags) => {
|
|
169
|
+
export const buildReferenceMatcher = (type, name, isArray, flags) => {
|
|
188
170
|
const expressions = [];
|
|
189
171
|
const gap = buildFilledGapFunction(expressions);
|
|
190
172
|
|
|
191
173
|
return treeFromStream(
|
|
192
174
|
(function* () {
|
|
193
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
175
|
+
yield t.nodeOpen(t.nodeFlags, 'ReferenceMatcher');
|
|
176
|
+
yield t.ref`type`;
|
|
177
|
+
yield gap(type && buildKeyword(type));
|
|
194
178
|
yield t.ref`name`;
|
|
195
|
-
yield gap(
|
|
179
|
+
yield gap(name && buildIdentifier(name));
|
|
196
180
|
yield* (function* () {
|
|
197
181
|
if (isArray) {
|
|
198
182
|
yield t.ref`openIndexToken`;
|
|
199
|
-
yield gap(buildToken(
|
|
183
|
+
yield gap(buildToken('Punctuator', '['));
|
|
200
184
|
yield t.ref`closeIndexToken`;
|
|
201
|
-
yield gap(buildToken(
|
|
185
|
+
yield gap(buildToken('Punctuator', ']'));
|
|
202
186
|
}
|
|
203
187
|
})();
|
|
204
188
|
yield t.ref`flags`;
|
|
205
189
|
yield gap(flags);
|
|
206
190
|
yield t.ref`sigilToken`;
|
|
207
|
-
yield gap(buildToken(
|
|
191
|
+
yield gap(buildToken('Punctuator', ':'));
|
|
208
192
|
yield t.ref`#`;
|
|
209
193
|
yield* sumtree.traverse(buildSpace().children);
|
|
210
194
|
yield t.nodeClose();
|
|
@@ -213,61 +197,52 @@ export const buildReferenceMatcher = (name, isArray, flags) => {
|
|
|
213
197
|
);
|
|
214
198
|
};
|
|
215
199
|
|
|
216
|
-
export const buildFragmentMatcher = (flags) => {
|
|
200
|
+
export const buildFragmentMatcher = (flags = buildNodeFlags({ fragment: true })) => {
|
|
217
201
|
const expressions = [];
|
|
218
202
|
const gap = buildFilledGapFunction(expressions);
|
|
219
203
|
|
|
204
|
+
if (!flags) throw new Error();
|
|
205
|
+
|
|
220
206
|
return treeFromStream(
|
|
221
207
|
(function* () {
|
|
222
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
208
|
+
yield t.nodeOpen(t.nodeFlags, 'FragmentMatcher');
|
|
223
209
|
yield t.ref`openToken`;
|
|
224
|
-
yield gap(buildToken(
|
|
210
|
+
yield gap(buildToken('Punctuator', '<'));
|
|
225
211
|
yield t.ref`flags`;
|
|
226
212
|
yield gap(flags);
|
|
227
|
-
yield t.ref`#`;
|
|
228
|
-
yield* sumtree.traverse(buildSpace().children);
|
|
229
213
|
yield t.ref`closeToken`;
|
|
230
|
-
yield gap(buildToken(
|
|
214
|
+
yield gap(buildToken('Punctuator', '/>'));
|
|
231
215
|
yield t.nodeClose();
|
|
232
216
|
})(),
|
|
233
217
|
{ expressions },
|
|
234
218
|
);
|
|
235
219
|
};
|
|
236
220
|
|
|
237
|
-
export const buildToken = (
|
|
238
|
-
return treeFromStream([
|
|
239
|
-
t.nodeOpen(t.tokenFlags, language, type, attributes),
|
|
240
|
-
t.lit(value),
|
|
241
|
-
t.nodeClose(),
|
|
242
|
-
]);
|
|
221
|
+
export const buildToken = (type, value, attributes = {}) => {
|
|
222
|
+
return treeFromStream([t.nodeOpen(t.tokenFlags, type, attributes), t.lit(value), t.nodeClose()]);
|
|
243
223
|
};
|
|
244
224
|
|
|
245
|
-
export const buildPunctuator = (
|
|
246
|
-
return buildToken(
|
|
225
|
+
export const buildPunctuator = (value, attributes = {}) => {
|
|
226
|
+
return buildToken('Punctuator', value, attributes);
|
|
247
227
|
};
|
|
248
228
|
|
|
249
|
-
export const buildOpenNodeTag = (flags,
|
|
229
|
+
export const buildOpenNodeTag = (flags, type = null, attributes) => {
|
|
250
230
|
const expressions = [];
|
|
251
231
|
const gap = buildFilledGapFunction(expressions);
|
|
252
232
|
|
|
253
|
-
let language_ = !language || language.length === 0 ? null : language;
|
|
254
|
-
|
|
255
233
|
return treeFromStream(
|
|
256
234
|
(function* () {
|
|
257
235
|
yield t.ref`openToken`;
|
|
258
|
-
yield gap(buildPunctuator(
|
|
236
|
+
yield gap(buildPunctuator('<'));
|
|
259
237
|
yield t.ref`flags`;
|
|
260
238
|
yield gap(buildNodeFlags(flags));
|
|
261
|
-
yield t.ref`language`;
|
|
262
|
-
yield gap(language_ && type ? buildLanguage(language_) : buildNullNode());
|
|
263
|
-
yield t.ref`languageSeparator`;
|
|
264
|
-
yield gap(language_ && type ? buildPunctuator(l.CSTML, ':') : buildNullNode());
|
|
265
239
|
yield t.ref`type`;
|
|
266
240
|
yield gap(type ? buildIdentifier(type) : buildNullNode());
|
|
267
|
-
|
|
241
|
+
let rootArr = getRootArray(attributes);
|
|
242
|
+
yield* when(rootArr.length, [t.ref`#`, gap(buildSpace())]);
|
|
268
243
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
269
244
|
yield t.ref`closeToken`;
|
|
270
|
-
yield gap(buildPunctuator(
|
|
245
|
+
yield gap(buildPunctuator('>'));
|
|
271
246
|
})(),
|
|
272
247
|
{ expressions },
|
|
273
248
|
);
|
|
@@ -279,22 +254,22 @@ export const buildDoctypeTag = (attributes) => {
|
|
|
279
254
|
|
|
280
255
|
return treeFromStream(
|
|
281
256
|
(function* () {
|
|
282
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
257
|
+
yield t.nodeOpen(t.nodeFlags, 'DoctypeTag');
|
|
283
258
|
yield t.ref`openToken`;
|
|
284
|
-
yield gap(buildPunctuator(
|
|
259
|
+
yield gap(buildPunctuator('Punctuator', '<!'));
|
|
285
260
|
yield t.ref`version`;
|
|
286
|
-
yield gap(buildToken(
|
|
261
|
+
yield gap(buildToken('PositiveInteger', '0'));
|
|
287
262
|
yield t.ref`versionSeparator`;
|
|
288
|
-
yield gap(buildPunctuator(
|
|
263
|
+
yield gap(buildPunctuator('Punctuator', ':'));
|
|
289
264
|
yield t.ref`doctype`;
|
|
290
|
-
yield gap(buildKeyword(
|
|
265
|
+
yield gap(buildKeyword('cstml'));
|
|
291
266
|
yield t.nodeClose();
|
|
292
267
|
|
|
293
|
-
yield* when(attributes.
|
|
268
|
+
yield* when(getRootArray(attributes).length, [t.ref`#`, ...buildSpace().children]);
|
|
294
269
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
295
270
|
|
|
296
271
|
yield t.ref`closeToken`;
|
|
297
|
-
yield gap(buildToken(
|
|
272
|
+
yield gap(buildToken('Punctuator', '>'));
|
|
298
273
|
})(),
|
|
299
274
|
{ expressions },
|
|
300
275
|
);
|
|
@@ -311,7 +286,7 @@ export const buildIdentifierPath = (path) => {
|
|
|
311
286
|
|
|
312
287
|
return treeFromStream(
|
|
313
288
|
(function* () {
|
|
314
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
289
|
+
yield t.nodeOpen(t.nodeFlags, 'IdentifierPath');
|
|
315
290
|
yield t.ref`segments[]`;
|
|
316
291
|
yield t.arr();
|
|
317
292
|
yield t.ref`separatorTokens[]`;
|
|
@@ -322,7 +297,7 @@ export const buildIdentifierPath = (path) => {
|
|
|
322
297
|
t.ref`segments[]`,
|
|
323
298
|
gap(buildIdentifier(name)),
|
|
324
299
|
t.ref`separatorTokens[]`,
|
|
325
|
-
gap(buildToken(
|
|
300
|
+
gap(buildToken('Punctuator', '.')),
|
|
326
301
|
])
|
|
327
302
|
.slice(0, -1);
|
|
328
303
|
|
|
@@ -338,23 +313,17 @@ export const buildLanguage = (language) => {
|
|
|
338
313
|
: buildIdentifierPath(language);
|
|
339
314
|
};
|
|
340
315
|
|
|
341
|
-
export const buildCloseNodeTag = (
|
|
316
|
+
export const buildCloseNodeTag = () => {
|
|
342
317
|
const expressions = [];
|
|
343
318
|
const gap = buildFilledGapFunction(expressions);
|
|
344
319
|
|
|
345
320
|
return treeFromStream(
|
|
346
321
|
[
|
|
347
|
-
t.nodeOpen(t.nodeFlags,
|
|
322
|
+
t.nodeOpen(t.nodeFlags, 'CloseNodeTag'),
|
|
348
323
|
t.ref`openToken`,
|
|
349
|
-
gap(buildToken(
|
|
350
|
-
t.ref`language`,
|
|
351
|
-
t.gap(language ? buildLanguage(language) : buildNullNode()),
|
|
352
|
-
t.ref`languageSeparator`,
|
|
353
|
-
gap(language && type ? buildToken(l.CSTML, 'Punctuator', ':') : buildNullNode()),
|
|
354
|
-
t.ref`type`,
|
|
355
|
-
gap(type ? buildIdentifier(type) : buildNullNode()),
|
|
324
|
+
gap(buildToken('Punctuator', '</')),
|
|
356
325
|
t.ref`closeToken`,
|
|
357
|
-
gap(buildToken(
|
|
326
|
+
gap(buildToken('Punctuator', '>')),
|
|
358
327
|
t.nodeClose(),
|
|
359
328
|
],
|
|
360
329
|
{ expressions },
|
|
@@ -363,7 +332,7 @@ export const buildCloseNodeTag = (type, language) => {
|
|
|
363
332
|
|
|
364
333
|
export const buildLiteralTag = (value) => {
|
|
365
334
|
return treeFromStream([
|
|
366
|
-
t.nodeOpen(t.nodeFlags,
|
|
335
|
+
t.nodeOpen(t.nodeFlags, 'LiteralTag'),
|
|
367
336
|
t.ref`value`,
|
|
368
337
|
t.lit(value),
|
|
369
338
|
t.nodeClose(),
|
|
@@ -377,7 +346,7 @@ export const buildTerminalProps = (matcher) => {
|
|
|
377
346
|
};
|
|
378
347
|
|
|
379
348
|
export const buildSpace = () => {
|
|
380
|
-
return buildToken(
|
|
349
|
+
return buildToken('Space', ' ');
|
|
381
350
|
};
|
|
382
351
|
|
|
383
352
|
export const buildIdentifier = (name) => {
|
|
@@ -388,7 +357,7 @@ export const buildIdentifier = (name) => {
|
|
|
388
357
|
|
|
389
358
|
return treeFromStream(
|
|
390
359
|
[
|
|
391
|
-
t.nodeOpen(t.nodeFlags,
|
|
360
|
+
t.nodeOpen(t.nodeFlags, 'Identifier'),
|
|
392
361
|
t.ref`content`,
|
|
393
362
|
gap(buildIdentifierContent(name)),
|
|
394
363
|
t.nodeClose(),
|
|
@@ -398,11 +367,11 @@ export const buildIdentifier = (name) => {
|
|
|
398
367
|
};
|
|
399
368
|
|
|
400
369
|
export const buildIdentifierContent = (value) => {
|
|
401
|
-
return buildToken(
|
|
370
|
+
return buildToken('IdentifierContent', value);
|
|
402
371
|
};
|
|
403
372
|
|
|
404
373
|
export const buildKeyword = (name) => {
|
|
405
|
-
return buildToken(
|
|
374
|
+
return buildToken('Keyword', name);
|
|
406
375
|
};
|
|
407
376
|
|
|
408
377
|
export const buildCall = (verb, args) => {
|
|
@@ -411,7 +380,7 @@ export const buildCall = (verb, args) => {
|
|
|
411
380
|
|
|
412
381
|
return treeFromStream(
|
|
413
382
|
[
|
|
414
|
-
t.nodeOpen(t.nodeFlags,
|
|
383
|
+
t.nodeOpen(t.nodeFlags, 'Call'),
|
|
415
384
|
t.ref`verb`,
|
|
416
385
|
gap(verb),
|
|
417
386
|
t.ref`arguments`,
|
|
@@ -428,11 +397,11 @@ export const buildProperty = (key, value) => {
|
|
|
428
397
|
|
|
429
398
|
return treeFromStream(
|
|
430
399
|
(function* () {
|
|
431
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
400
|
+
yield t.nodeOpen(t.nodeFlags, 'Property');
|
|
432
401
|
yield t.ref`key`;
|
|
433
402
|
yield gap(key);
|
|
434
403
|
yield t.ref`mapOperator`;
|
|
435
|
-
yield gap(buildToken(
|
|
404
|
+
yield gap(buildToken('Punctuator', ':'));
|
|
436
405
|
yield t.ref`#`;
|
|
437
406
|
yield gap(buildSpace());
|
|
438
407
|
yield t.ref`value`;
|
|
@@ -451,7 +420,7 @@ const escapables = {
|
|
|
451
420
|
};
|
|
452
421
|
|
|
453
422
|
export const buildDigit = (value) => {
|
|
454
|
-
return buildToken(
|
|
423
|
+
return buildToken('Digit', value);
|
|
455
424
|
};
|
|
456
425
|
|
|
457
426
|
export const buildInteger = (value, base = 10) => {
|
|
@@ -462,7 +431,7 @@ export const buildInteger = (value, base = 10) => {
|
|
|
462
431
|
|
|
463
432
|
return treeFromStream(
|
|
464
433
|
concat(
|
|
465
|
-
[t.nodeOpen(t.nodeFlags,
|
|
434
|
+
[t.nodeOpen(t.nodeFlags, 'Integer'), t.ref`digits[]`, t.arr()],
|
|
466
435
|
digits.flatMap((digit) => [t.ref`digits[]`, gap(buildDigit(digit))]),
|
|
467
436
|
[t.nodeClose()],
|
|
468
437
|
),
|
|
@@ -486,11 +455,11 @@ export const buildInfinity = (value) => {
|
|
|
486
455
|
|
|
487
456
|
return treeFromStream(
|
|
488
457
|
[
|
|
489
|
-
t.nodeOpen(t.nodeFlags,
|
|
458
|
+
t.nodeOpen(t.nodeFlags, 'Infinity'),
|
|
490
459
|
t.ref`sign`,
|
|
491
|
-
gap(buildToken(
|
|
460
|
+
gap(buildToken('Punctuator', sign)),
|
|
492
461
|
t.ref`value`,
|
|
493
|
-
gap(buildToken(
|
|
462
|
+
gap(buildToken('Keyword', 'Infinity')),
|
|
494
463
|
t.nodeClose(),
|
|
495
464
|
],
|
|
496
465
|
{ expressions },
|
|
@@ -506,6 +475,7 @@ export const buildNumber = (value) => {
|
|
|
506
475
|
};
|
|
507
476
|
|
|
508
477
|
export const buildString = (value) => {
|
|
478
|
+
if (value == null) throw new Error();
|
|
509
479
|
const pieces = isArray(value) ? value : [value];
|
|
510
480
|
let lit = '';
|
|
511
481
|
|
|
@@ -514,13 +484,13 @@ export const buildString = (value) => {
|
|
|
514
484
|
const gap = buildFilledGapFunction(expressions);
|
|
515
485
|
return treeFromStream(
|
|
516
486
|
[
|
|
517
|
-
t.nodeOpen(t.nodeFlags,
|
|
487
|
+
t.nodeOpen(t.nodeFlags, 'String'),
|
|
518
488
|
t.ref`openToken`,
|
|
519
|
-
gap(buildToken(
|
|
489
|
+
gap(buildToken('Punctuator', '"')),
|
|
520
490
|
t.ref`content`,
|
|
521
|
-
gap(buildToken(
|
|
491
|
+
gap(buildToken('StringContent', value)),
|
|
522
492
|
t.ref`closeToken`,
|
|
523
|
-
gap(buildToken(
|
|
493
|
+
gap(buildToken('Punctuator', '"')),
|
|
524
494
|
t.nodeClose(),
|
|
525
495
|
],
|
|
526
496
|
{ expressions },
|
|
@@ -532,12 +502,12 @@ export const buildString = (value) => {
|
|
|
532
502
|
|
|
533
503
|
return treeFromStream(
|
|
534
504
|
(function* () {
|
|
535
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
505
|
+
yield t.nodeOpen(t.nodeFlags, 'String');
|
|
536
506
|
yield t.ref`openToken`;
|
|
537
|
-
const tok = buildToken(
|
|
507
|
+
const tok = buildToken('Punctuator', "'");
|
|
538
508
|
yield gap(tok);
|
|
539
509
|
yield t.ref`content`;
|
|
540
|
-
yield t.nodeOpen(t.tokenFlags,
|
|
510
|
+
yield t.nodeOpen(t.tokenFlags, 'StringContent');
|
|
541
511
|
|
|
542
512
|
for (const piece of pieces) {
|
|
543
513
|
if (isString(piece)) {
|
|
@@ -566,7 +536,7 @@ export const buildString = (value) => {
|
|
|
566
536
|
|
|
567
537
|
value = treeFromStream(
|
|
568
538
|
[
|
|
569
|
-
t.nodeOpen(t.nodeFlags,
|
|
539
|
+
t.nodeOpen(t.nodeFlags, 'EscapeCode'),
|
|
570
540
|
t.ref`sigilToken`,
|
|
571
541
|
gap(buildKeyword(escapables[chr])),
|
|
572
542
|
t.ref`digits[]`,
|
|
@@ -582,7 +552,7 @@ export const buildString = (value) => {
|
|
|
582
552
|
|
|
583
553
|
value = treeFromStream(
|
|
584
554
|
[
|
|
585
|
-
t.nodeOpen(t.nodeFlags,
|
|
555
|
+
t.nodeOpen(t.nodeFlags, 'EscapeCode'),
|
|
586
556
|
t.ref`sigilToken`,
|
|
587
557
|
gap(buildKeyword('u')),
|
|
588
558
|
t.ref`digits[]`,
|
|
@@ -597,9 +567,9 @@ export const buildString = (value) => {
|
|
|
597
567
|
}
|
|
598
568
|
|
|
599
569
|
yield t.ref`@`;
|
|
600
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
570
|
+
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', { cooked: chr });
|
|
601
571
|
yield t.ref`escape`;
|
|
602
|
-
yield gap(buildToken(
|
|
572
|
+
yield gap(buildToken('Punctuator', '\\'));
|
|
603
573
|
yield t.ref`value`;
|
|
604
574
|
yield gap(value);
|
|
605
575
|
yield t.nodeClose();
|
|
@@ -626,7 +596,7 @@ export const buildString = (value) => {
|
|
|
626
596
|
|
|
627
597
|
yield t.nodeClose();
|
|
628
598
|
yield t.ref`closeToken`;
|
|
629
|
-
yield gap(buildToken(
|
|
599
|
+
yield gap(buildToken('Punctuator', "'"));
|
|
630
600
|
yield t.nodeClose();
|
|
631
601
|
})(),
|
|
632
602
|
{ expressions },
|
|
@@ -639,9 +609,9 @@ export const buildBoolean = (value) => {
|
|
|
639
609
|
|
|
640
610
|
return treeFromStream(
|
|
641
611
|
[
|
|
642
|
-
t.nodeOpen(t.nodeFlags,
|
|
612
|
+
t.nodeOpen(t.nodeFlags, 'Boolean'),
|
|
643
613
|
t.ref`sigilToken`,
|
|
644
|
-
gap(buildToken(
|
|
614
|
+
gap(buildToken('Keyword', value ? 'true' : 'false')),
|
|
645
615
|
t.nodeClose(),
|
|
646
616
|
],
|
|
647
617
|
{ expressions },
|
|
@@ -654,9 +624,9 @@ export const buildNull = () => {
|
|
|
654
624
|
|
|
655
625
|
return treeFromStream(
|
|
656
626
|
[
|
|
657
|
-
t.nodeOpen(t.nodeFlags,
|
|
627
|
+
t.nodeOpen(t.nodeFlags, 'Null'),
|
|
658
628
|
t.ref`sigilToken`,
|
|
659
|
-
gap(buildToken(
|
|
629
|
+
gap(buildToken('Keyword', 'null')),
|
|
660
630
|
t.nodeClose(),
|
|
661
631
|
],
|
|
662
632
|
{ expressions },
|
|
@@ -669,9 +639,9 @@ export const buildNullTag = () => {
|
|
|
669
639
|
|
|
670
640
|
return treeFromStream(
|
|
671
641
|
[
|
|
672
|
-
t.nodeOpen(t.nodeFlags,
|
|
642
|
+
t.nodeOpen(t.nodeFlags, 'NullTag'),
|
|
673
643
|
t.ref`sigilToken`,
|
|
674
|
-
gap(buildToken(
|
|
644
|
+
gap(buildToken('Keyword', 'null')),
|
|
675
645
|
t.nodeClose(),
|
|
676
646
|
],
|
|
677
647
|
{ expressions },
|
|
@@ -684,12 +654,12 @@ export const buildArray = (elements) => {
|
|
|
684
654
|
|
|
685
655
|
return treeFromStream(
|
|
686
656
|
(function* () {
|
|
687
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
657
|
+
yield t.nodeOpen(t.nodeFlags, 'Array');
|
|
688
658
|
yield t.ref`openToken`;
|
|
689
|
-
yield gap(buildToken(
|
|
659
|
+
yield gap(buildToken('Punctuator', '['));
|
|
690
660
|
yield* interpolateFragment(elements, t.ref`elements[]`, expressions);
|
|
691
661
|
yield t.ref`closeToken`;
|
|
692
|
-
yield gap(buildToken(
|
|
662
|
+
yield gap(buildToken('Punctuator', ']'));
|
|
693
663
|
yield t.nodeClose();
|
|
694
664
|
})(),
|
|
695
665
|
{ expressions },
|
|
@@ -720,7 +690,7 @@ export function* buildSpaceSeparatedList(values, ref, expressions) {
|
|
|
720
690
|
let first = true;
|
|
721
691
|
for (const value of values) {
|
|
722
692
|
if (!first) {
|
|
723
|
-
yield t.buildReferenceTag('#'
|
|
693
|
+
yield t.buildReferenceTag('#');
|
|
724
694
|
yield gap(buildSpace());
|
|
725
695
|
}
|
|
726
696
|
yield freeze({ ...ref });
|
|
@@ -748,14 +718,14 @@ export const buildObject = (properties) => {
|
|
|
748
718
|
|
|
749
719
|
return treeFromStream(
|
|
750
720
|
(function* () {
|
|
751
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
721
|
+
yield t.nodeOpen(t.nodeFlags, 'Object');
|
|
752
722
|
yield t.ref`openToken`;
|
|
753
|
-
yield gap(buildToken(
|
|
723
|
+
yield gap(buildToken('Punctuator', '{'));
|
|
754
724
|
|
|
755
725
|
yield* interpolateFragment(properties, t.ref`properties[]`, expressions);
|
|
756
726
|
|
|
757
727
|
yield t.ref`closeToken`;
|
|
758
|
-
yield gap(buildToken(
|
|
728
|
+
yield gap(buildToken('Punctuator', '}'));
|
|
759
729
|
yield t.nodeClose();
|
|
760
730
|
})(),
|
|
761
731
|
{ expressions },
|
|
@@ -768,14 +738,36 @@ export const buildPattern = (alternatives, flags) => {
|
|
|
768
738
|
|
|
769
739
|
return treeFromStream(
|
|
770
740
|
(function* () {
|
|
771
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
741
|
+
yield t.nodeOpen(t.nodeFlags, 'Pattern');
|
|
772
742
|
yield t.ref`openToken`;
|
|
773
|
-
yield gap(buildToken(
|
|
743
|
+
yield gap(buildToken('Punctuator', '/'));
|
|
774
744
|
|
|
775
745
|
yield* interpolateFragment(alternatives, t.ref`alternatives[]`, expressions);
|
|
776
746
|
|
|
777
747
|
yield t.ref`closeToken`;
|
|
778
|
-
yield gap(buildToken(
|
|
748
|
+
yield gap(buildToken('Punctuator', '/'));
|
|
749
|
+
yield t.ref`flags`;
|
|
750
|
+
yield gap(flags || buildReferenceFlags());
|
|
751
|
+
yield t.nodeClose();
|
|
752
|
+
})(),
|
|
753
|
+
{ expressions },
|
|
754
|
+
);
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
export const buildRegexGroup = (alternatives, flags) => {
|
|
758
|
+
const expressions = [];
|
|
759
|
+
const gap = buildFilledGapFunction(expressions);
|
|
760
|
+
|
|
761
|
+
return treeFromStream(
|
|
762
|
+
(function* () {
|
|
763
|
+
yield t.nodeOpen(t.nodeFlags, 'Group');
|
|
764
|
+
yield t.ref`openToken`;
|
|
765
|
+
yield gap(buildToken('Punctuator', '('));
|
|
766
|
+
|
|
767
|
+
yield* interpolateFragment(alternatives, t.ref`alternatives[]`, expressions);
|
|
768
|
+
|
|
769
|
+
yield t.ref`closeToken`;
|
|
770
|
+
yield gap(buildToken('Punctuator', ')'));
|
|
779
771
|
yield t.ref`flags`;
|
|
780
772
|
yield gap(flags || buildReferenceFlags());
|
|
781
773
|
yield t.nodeClose();
|
|
@@ -799,12 +791,12 @@ export const buildRegexFlags = (flags = '') => {
|
|
|
799
791
|
|
|
800
792
|
return treeFromStream(
|
|
801
793
|
(function* () {
|
|
802
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
794
|
+
yield t.nodeOpen(t.nodeFlags, 'Flags');
|
|
803
795
|
|
|
804
796
|
for (const { 0: name, 1: chr } of Object.entries(flagCharacters)) {
|
|
805
797
|
yield t.buildReferenceTag(name + 'Token');
|
|
806
798
|
|
|
807
|
-
yield gap(flags.includes(chr) ? buildToken(
|
|
799
|
+
yield gap(flags.includes(chr) ? buildToken('Punctuator', chr) : buildNullNode());
|
|
808
800
|
}
|
|
809
801
|
yield t.nodeClose();
|
|
810
802
|
})(),
|
|
@@ -817,7 +809,7 @@ export const buildAlternative = (elements) => {
|
|
|
817
809
|
|
|
818
810
|
return treeFromStream(
|
|
819
811
|
concat(
|
|
820
|
-
[t.nodeOpen(t.nodeFlags,
|
|
812
|
+
[t.nodeOpen(t.nodeFlags, 'Alternative')],
|
|
821
813
|
interpolateFragment(elements, t.ref`elements[]+`, expressions),
|
|
822
814
|
[t.nodeClose()],
|
|
823
815
|
),
|
|
@@ -831,7 +823,7 @@ export const buildAlternatives = (alternatives = []) => {
|
|
|
831
823
|
|
|
832
824
|
return treeFromStream(
|
|
833
825
|
(function* () {
|
|
834
|
-
yield t.doctype({ bablrLanguage: l.
|
|
826
|
+
yield t.doctype({ bablrLanguage: l.Instruction });
|
|
835
827
|
yield t.nodeOpen(t.nodeFlags);
|
|
836
828
|
yield t.ref`.[]`;
|
|
837
829
|
yield t.arr();
|
|
@@ -843,7 +835,7 @@ export const buildAlternatives = (alternatives = []) => {
|
|
|
843
835
|
t.ref`.[]`,
|
|
844
836
|
gap(alt),
|
|
845
837
|
t.ref`separatorTokens[]`,
|
|
846
|
-
gap(buildPunctuator(
|
|
838
|
+
gap(buildPunctuator('|')),
|
|
847
839
|
])
|
|
848
840
|
.slice(0, -2);
|
|
849
841
|
|
|
@@ -859,11 +851,11 @@ export const buildRegexGap = () => {
|
|
|
859
851
|
|
|
860
852
|
return treeFromStream(
|
|
861
853
|
[
|
|
862
|
-
t.nodeOpen(t.nodeFlags,
|
|
854
|
+
t.nodeOpen(t.nodeFlags, 'Gap'),
|
|
863
855
|
t.ref`escapeToken`,
|
|
864
|
-
gap(buildToken(
|
|
856
|
+
gap(buildToken('Punctuator', '\\')),
|
|
865
857
|
t.ref`value`,
|
|
866
|
-
gap(buildToken(
|
|
858
|
+
gap(buildToken('Keyword', 'g')),
|
|
867
859
|
t.nodeClose(),
|
|
868
860
|
],
|
|
869
861
|
{ expressions },
|
|
@@ -876,7 +868,7 @@ export const buildElements = (elements) => {
|
|
|
876
868
|
|
|
877
869
|
return treeFromStream(
|
|
878
870
|
concat(
|
|
879
|
-
[t.doctype({ bablrLanguage: l.
|
|
871
|
+
[t.doctype({ bablrLanguage: l.Instruction }), t.nodeOpen(t.nodeFlags), t.ref`.[]+`, t.arr()],
|
|
880
872
|
elements.flatMap((el) => [t.ref`.[]+`, gap(el)]),
|
|
881
873
|
[t.nodeClose()],
|
|
882
874
|
),
|
|
@@ -884,61 +876,21 @@ export const buildElements = (elements) => {
|
|
|
884
876
|
);
|
|
885
877
|
};
|
|
886
878
|
|
|
887
|
-
export const buildExpression = (expr) => {
|
|
888
|
-
throw new Error('unimplemented');
|
|
889
|
-
|
|
890
|
-
if (isNull(expr)) return buildNullTag();
|
|
891
|
-
|
|
892
|
-
switch (typeof expr) {
|
|
893
|
-
case 'symbol':
|
|
894
|
-
case 'boolean':
|
|
895
|
-
return buildBoolean(expr);
|
|
896
|
-
case 'string':
|
|
897
|
-
return buildString(expr);
|
|
898
|
-
case 'number':
|
|
899
|
-
return buildInteger(expr);
|
|
900
|
-
case 'object': {
|
|
901
|
-
switch (getPrototypeOf(expr)) {
|
|
902
|
-
case Array.prototype:
|
|
903
|
-
return buildArray(buildArrayElements(expr));
|
|
904
|
-
case Object.prototype:
|
|
905
|
-
if (
|
|
906
|
-
hasOwn(expr, 'type') &&
|
|
907
|
-
hasOwn(expr, 'language') &&
|
|
908
|
-
hasOwn(expr, 'children') &&
|
|
909
|
-
hasOwn(expr, 'properties')
|
|
910
|
-
) {
|
|
911
|
-
return expr;
|
|
912
|
-
}
|
|
913
|
-
return buildObject(
|
|
914
|
-
buildObjectProperties(
|
|
915
|
-
Object.entries(expr).map((e) => buildProperty(buildIdentifier(e[0]), e[1])),
|
|
916
|
-
),
|
|
917
|
-
);
|
|
918
|
-
default:
|
|
919
|
-
throw new Error();
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
default:
|
|
923
|
-
throw new Error();
|
|
924
|
-
}
|
|
925
|
-
};
|
|
926
|
-
|
|
927
879
|
export const buildTaggedString = (tag, content) => {
|
|
928
880
|
const expressions = [];
|
|
929
881
|
const gap = buildFilledGapFunction(expressions);
|
|
930
882
|
|
|
931
883
|
return treeFromStream(
|
|
932
884
|
[
|
|
933
|
-
t.buildOpenNodeTag(t.nodeFlags,
|
|
885
|
+
t.buildOpenNodeTag(t.nodeFlags, 'SpamexString'),
|
|
934
886
|
t.buildReferenceTag('sigilToken'),
|
|
935
|
-
gap(buildToken(
|
|
887
|
+
gap(buildToken('Keyword', tag)),
|
|
936
888
|
t.buildReferenceTag('openToken'),
|
|
937
|
-
gap(buildToken(
|
|
889
|
+
gap(buildToken('Punctuator', "'")),
|
|
938
890
|
t.buildReferenceTag('content'),
|
|
939
891
|
gap(content),
|
|
940
892
|
t.buildReferenceTag('closeToken'),
|
|
941
|
-
gap(buildToken(
|
|
893
|
+
gap(buildToken('Punctuator', "'")),
|
|
942
894
|
t.buildCloseNodeTag(),
|
|
943
895
|
],
|
|
944
896
|
{ expressions },
|
|
@@ -953,15 +905,17 @@ export const buildRegexString = (content) => {
|
|
|
953
905
|
return buildTaggedString('re', content);
|
|
954
906
|
};
|
|
955
907
|
|
|
956
|
-
export const buildPropertyMatcher = (refMatcher, nodeMatcher) => {
|
|
908
|
+
export const buildPropertyMatcher = (refMatcher, bindingMatcher, nodeMatcher) => {
|
|
957
909
|
const expressions = [];
|
|
958
910
|
const gap = buildFilledGapFunction(expressions);
|
|
959
911
|
|
|
960
912
|
return treeFromStream(
|
|
961
913
|
[
|
|
962
|
-
t.nodeOpen(t.nodeFlags,
|
|
914
|
+
t.nodeOpen(t.nodeFlags, 'PropertyMatcher'),
|
|
963
915
|
t.ref`refMatcher`,
|
|
964
916
|
gap(refMatcher || buildNullNode()),
|
|
917
|
+
t.ref`bindingMatcher`,
|
|
918
|
+
gap(bindingMatcher || buildNullNode()),
|
|
965
919
|
t.ref`nodeMatcher`,
|
|
966
920
|
gap(nodeMatcher),
|
|
967
921
|
t.nodeClose(),
|
|
@@ -971,5 +925,5 @@ export const buildPropertyMatcher = (refMatcher, nodeMatcher) => {
|
|
|
971
925
|
};
|
|
972
926
|
|
|
973
927
|
export const buildGapNodeMatcher = () => {
|
|
974
|
-
return buildToken(
|
|
928
|
+
return buildToken('GapNodeMatcher', '<//>');
|
|
975
929
|
};
|