@bablr/helpers 0.22.1 → 0.24.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 -201
- 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 +13 -11
- package/lib/productions.macro.js +13 -17
- package/lib/source.js +1 -1
- package/lib/tree.js +1 -3
- package/lib/trivia.js +213 -33
- package/package.json +8 -9
- package/lib/stream.js +0 -86
package/lib/builders.js
CHANGED
|
@@ -1,47 +1,40 @@
|
|
|
1
|
-
// import { i } from '@bablr/boot/shorthand.macro';
|
|
2
1
|
import { interpolateFragment, buildFilledGapFunction } from '@bablr/agast-helpers/template';
|
|
3
2
|
import {
|
|
4
3
|
buildNullNode,
|
|
5
|
-
|
|
4
|
+
get,
|
|
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
|
|
10
|
+
import * as Tags from '@bablr/agast-helpers/tags';
|
|
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`multiFragmentToken`,
|
|
107
|
+
gap(!cover ? buildToken('Punctuator', '_') : buildNullNode()),
|
|
111
108
|
t.nodeClose(),
|
|
112
109
|
],
|
|
113
110
|
{ expressions },
|
|
@@ -115,59 +112,42 @@ 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, literalValue, attributes = null) => {
|
|
122
119
|
const expressions = [];
|
|
123
120
|
const gap = buildFilledGapFunction(expressions);
|
|
124
121
|
|
|
125
|
-
let language_;
|
|
126
|
-
|
|
127
122
|
if (!type) throw new Error();
|
|
128
123
|
|
|
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
124
|
return treeFromStream(
|
|
138
125
|
(function* () {
|
|
139
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
126
|
+
yield t.nodeOpen(t.nodeFlags, 'OpenNodeMatcher');
|
|
140
127
|
yield t.ref`openToken`;
|
|
141
|
-
yield gap(buildToken(
|
|
128
|
+
yield gap(buildToken('Punctuator', '<'));
|
|
142
129
|
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());
|
|
130
|
+
yield gap(flags);
|
|
148
131
|
yield t.ref`type`;
|
|
149
|
-
yield gap(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
? buildKeyword(type)
|
|
153
|
-
: buildIdentifier(type)
|
|
154
|
-
: type,
|
|
155
|
-
);
|
|
132
|
+
yield gap(typeof type === 'string' ? buildIdentifier(type) : type);
|
|
133
|
+
|
|
134
|
+
yield* when(literalValue, [t.ref`#`, ...buildSpace().tags]);
|
|
156
135
|
|
|
157
|
-
yield
|
|
136
|
+
yield t.ref`literalValue`;
|
|
137
|
+
yield gap(literalValue ? buildString(literalValue) : buildNullNode());
|
|
158
138
|
|
|
159
|
-
|
|
160
|
-
yield gap(intrinsicValue ? buildString(intrinsicValue) : buildNullNode());
|
|
139
|
+
let rootArr = getRootArray(attributes);
|
|
161
140
|
|
|
162
|
-
|
|
163
|
-
|
|
141
|
+
if (rootArr.length) {
|
|
142
|
+
yield t.ref`#`;
|
|
143
|
+
yield* buildSpace().tags;
|
|
164
144
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
165
145
|
}
|
|
166
146
|
|
|
167
|
-
yield t.ref`
|
|
168
|
-
yield gap(buildToken(
|
|
147
|
+
yield t.ref`selfClosingToken`;
|
|
148
|
+
yield gap(buildToken('Punctuator', '/'));
|
|
169
149
|
yield t.ref`closeToken`;
|
|
170
|
-
yield gap(buildToken(
|
|
150
|
+
yield gap(buildToken('Punctuator', '>'));
|
|
171
151
|
yield t.nodeClose();
|
|
172
152
|
})(),
|
|
173
153
|
{ expressions },
|
|
@@ -179,95 +159,88 @@ export const buildBasicNodeMatcher = (open) => {
|
|
|
179
159
|
const gap = buildFilledGapFunction(expressions);
|
|
180
160
|
|
|
181
161
|
return treeFromStream(
|
|
182
|
-
[t.nodeOpen(t.nodeFlags,
|
|
162
|
+
[t.nodeOpen(t.nodeFlags, 'BasicNodeMatcher'), t.ref`open`, gap(open), t.nodeClose()],
|
|
183
163
|
{ expressions },
|
|
184
164
|
);
|
|
185
165
|
};
|
|
186
166
|
|
|
187
|
-
export const buildReferenceMatcher = (name, isArray, flags) => {
|
|
167
|
+
export const buildReferenceMatcher = (type, name, isArray, flags) => {
|
|
188
168
|
const expressions = [];
|
|
189
169
|
const gap = buildFilledGapFunction(expressions);
|
|
190
170
|
|
|
191
171
|
return treeFromStream(
|
|
192
172
|
(function* () {
|
|
193
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
173
|
+
yield t.nodeOpen(t.nodeFlags, 'ReferenceMatcher');
|
|
174
|
+
yield t.ref`type`;
|
|
175
|
+
yield gap(type && buildKeyword(type));
|
|
194
176
|
yield t.ref`name`;
|
|
195
|
-
yield gap(
|
|
177
|
+
yield gap(name && buildIdentifier(name));
|
|
196
178
|
yield* (function* () {
|
|
197
179
|
if (isArray) {
|
|
198
180
|
yield t.ref`openIndexToken`;
|
|
199
|
-
yield gap(buildToken(
|
|
181
|
+
yield gap(buildToken('Punctuator', '['));
|
|
200
182
|
yield t.ref`closeIndexToken`;
|
|
201
|
-
yield gap(buildToken(
|
|
183
|
+
yield gap(buildToken('Punctuator', ']'));
|
|
202
184
|
}
|
|
203
185
|
})();
|
|
204
186
|
yield t.ref`flags`;
|
|
205
187
|
yield gap(flags);
|
|
206
188
|
yield t.ref`sigilToken`;
|
|
207
|
-
yield gap(buildToken(
|
|
189
|
+
yield gap(buildToken('Punctuator', ':'));
|
|
208
190
|
yield t.ref`#`;
|
|
209
|
-
yield*
|
|
191
|
+
yield* Tags.traverse(buildSpace().tags);
|
|
210
192
|
yield t.nodeClose();
|
|
211
193
|
})(),
|
|
212
194
|
{ expressions },
|
|
213
195
|
);
|
|
214
196
|
};
|
|
215
197
|
|
|
216
|
-
export const buildFragmentMatcher = (flags) => {
|
|
198
|
+
export const buildFragmentMatcher = (flags = buildNodeFlags({ fragment: true, cover: true })) => {
|
|
217
199
|
const expressions = [];
|
|
218
200
|
const gap = buildFilledGapFunction(expressions);
|
|
219
201
|
|
|
202
|
+
if (!flags) throw new Error();
|
|
203
|
+
|
|
220
204
|
return treeFromStream(
|
|
221
205
|
(function* () {
|
|
222
|
-
yield t.nodeOpen(t.
|
|
206
|
+
yield t.nodeOpen(t.fragmentFlags, 'FragmentMatcher');
|
|
223
207
|
yield t.ref`openToken`;
|
|
224
|
-
yield gap(buildToken(
|
|
208
|
+
yield gap(buildToken('Punctuator', '<'));
|
|
225
209
|
yield t.ref`flags`;
|
|
226
210
|
yield gap(flags);
|
|
227
|
-
yield t.ref`#`;
|
|
228
|
-
yield* sumtree.traverse(buildSpace().children);
|
|
229
211
|
yield t.ref`closeToken`;
|
|
230
|
-
yield gap(buildToken(
|
|
212
|
+
yield gap(buildToken('Punctuator', '/>'));
|
|
231
213
|
yield t.nodeClose();
|
|
232
214
|
})(),
|
|
233
215
|
{ expressions },
|
|
234
216
|
);
|
|
235
217
|
};
|
|
236
218
|
|
|
237
|
-
export const buildToken = (
|
|
238
|
-
return treeFromStream([
|
|
239
|
-
t.nodeOpen(t.tokenFlags, language, type, attributes),
|
|
240
|
-
t.lit(value),
|
|
241
|
-
t.nodeClose(),
|
|
242
|
-
]);
|
|
219
|
+
export const buildToken = (type, value, attributes = {}) => {
|
|
220
|
+
return treeFromStream([t.nodeOpen(t.tokenFlags, type, attributes), t.lit(value), t.nodeClose()]);
|
|
243
221
|
};
|
|
244
222
|
|
|
245
|
-
export const buildPunctuator = (
|
|
246
|
-
return buildToken(
|
|
223
|
+
export const buildPunctuator = (value, attributes = {}) => {
|
|
224
|
+
return buildToken('Punctuator', value, attributes);
|
|
247
225
|
};
|
|
248
226
|
|
|
249
|
-
export const buildOpenNodeTag = (flags,
|
|
227
|
+
export const buildOpenNodeTag = (flags, type = null, attributes) => {
|
|
250
228
|
const expressions = [];
|
|
251
229
|
const gap = buildFilledGapFunction(expressions);
|
|
252
230
|
|
|
253
|
-
let language_ = !language || language.length === 0 ? null : language;
|
|
254
|
-
|
|
255
231
|
return treeFromStream(
|
|
256
232
|
(function* () {
|
|
257
233
|
yield t.ref`openToken`;
|
|
258
|
-
yield gap(buildPunctuator(
|
|
234
|
+
yield gap(buildPunctuator('<'));
|
|
259
235
|
yield t.ref`flags`;
|
|
260
236
|
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
237
|
yield t.ref`type`;
|
|
266
238
|
yield gap(type ? buildIdentifier(type) : buildNullNode());
|
|
267
|
-
|
|
239
|
+
let rootArr = getRootArray(attributes);
|
|
240
|
+
yield* when(rootArr.length, [t.ref`#`, gap(buildSpace())]);
|
|
268
241
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
269
242
|
yield t.ref`closeToken`;
|
|
270
|
-
yield gap(buildPunctuator(
|
|
243
|
+
yield gap(buildPunctuator('>'));
|
|
271
244
|
})(),
|
|
272
245
|
{ expressions },
|
|
273
246
|
);
|
|
@@ -279,22 +252,22 @@ export const buildDoctypeTag = (attributes) => {
|
|
|
279
252
|
|
|
280
253
|
return treeFromStream(
|
|
281
254
|
(function* () {
|
|
282
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
255
|
+
yield t.nodeOpen(t.nodeFlags, 'DoctypeTag');
|
|
283
256
|
yield t.ref`openToken`;
|
|
284
|
-
yield gap(buildPunctuator(
|
|
257
|
+
yield gap(buildPunctuator('Punctuator', '<!'));
|
|
285
258
|
yield t.ref`version`;
|
|
286
|
-
yield gap(buildToken(
|
|
259
|
+
yield gap(buildToken('PositiveInteger', '0'));
|
|
287
260
|
yield t.ref`versionSeparator`;
|
|
288
|
-
yield gap(buildPunctuator(
|
|
261
|
+
yield gap(buildPunctuator('Punctuator', ':'));
|
|
289
262
|
yield t.ref`doctype`;
|
|
290
|
-
yield gap(buildKeyword(
|
|
263
|
+
yield gap(buildKeyword('cstml'));
|
|
291
264
|
yield t.nodeClose();
|
|
292
265
|
|
|
293
|
-
yield* when(attributes.
|
|
266
|
+
yield* when(getRootArray(attributes).length, [t.ref`#`, ...buildSpace().tags]);
|
|
294
267
|
yield* interpolateFragment(attributes, t.ref`attributes[]`, expressions);
|
|
295
268
|
|
|
296
269
|
yield t.ref`closeToken`;
|
|
297
|
-
yield gap(buildToken(
|
|
270
|
+
yield gap(buildToken('Punctuator', '>'));
|
|
298
271
|
})(),
|
|
299
272
|
{ expressions },
|
|
300
273
|
);
|
|
@@ -311,7 +284,7 @@ export const buildIdentifierPath = (path) => {
|
|
|
311
284
|
|
|
312
285
|
return treeFromStream(
|
|
313
286
|
(function* () {
|
|
314
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
287
|
+
yield t.nodeOpen(t.nodeFlags, 'IdentifierPath');
|
|
315
288
|
yield t.ref`segments[]`;
|
|
316
289
|
yield t.arr();
|
|
317
290
|
yield t.ref`separatorTokens[]`;
|
|
@@ -322,7 +295,7 @@ export const buildIdentifierPath = (path) => {
|
|
|
322
295
|
t.ref`segments[]`,
|
|
323
296
|
gap(buildIdentifier(name)),
|
|
324
297
|
t.ref`separatorTokens[]`,
|
|
325
|
-
gap(buildToken(
|
|
298
|
+
gap(buildToken('Punctuator', '.')),
|
|
326
299
|
])
|
|
327
300
|
.slice(0, -1);
|
|
328
301
|
|
|
@@ -338,23 +311,17 @@ export const buildLanguage = (language) => {
|
|
|
338
311
|
: buildIdentifierPath(language);
|
|
339
312
|
};
|
|
340
313
|
|
|
341
|
-
export const buildCloseNodeTag = (
|
|
314
|
+
export const buildCloseNodeTag = () => {
|
|
342
315
|
const expressions = [];
|
|
343
316
|
const gap = buildFilledGapFunction(expressions);
|
|
344
317
|
|
|
345
318
|
return treeFromStream(
|
|
346
319
|
[
|
|
347
|
-
t.nodeOpen(t.nodeFlags,
|
|
320
|
+
t.nodeOpen(t.nodeFlags, 'CloseNodeTag'),
|
|
348
321
|
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()),
|
|
322
|
+
gap(buildToken('Punctuator', '</')),
|
|
356
323
|
t.ref`closeToken`,
|
|
357
|
-
gap(buildToken(
|
|
324
|
+
gap(buildToken('Punctuator', '>')),
|
|
358
325
|
t.nodeClose(),
|
|
359
326
|
],
|
|
360
327
|
{ expressions },
|
|
@@ -363,7 +330,7 @@ export const buildCloseNodeTag = (type, language) => {
|
|
|
363
330
|
|
|
364
331
|
export const buildLiteralTag = (value) => {
|
|
365
332
|
return treeFromStream([
|
|
366
|
-
t.nodeOpen(t.nodeFlags,
|
|
333
|
+
t.nodeOpen(t.nodeFlags, 'LiteralTag'),
|
|
367
334
|
t.ref`value`,
|
|
368
335
|
t.lit(value),
|
|
369
336
|
t.nodeClose(),
|
|
@@ -371,38 +338,87 @@ export const buildLiteralTag = (value) => {
|
|
|
371
338
|
};
|
|
372
339
|
|
|
373
340
|
export const buildTerminalProps = (matcher) => {
|
|
374
|
-
const
|
|
341
|
+
const value = get('value', matcher);
|
|
342
|
+
const attributes = get('attributes', matcher);
|
|
375
343
|
|
|
376
344
|
return buildObject({ value, attributes });
|
|
377
345
|
};
|
|
378
346
|
|
|
379
347
|
export const buildSpace = () => {
|
|
380
|
-
return buildToken(
|
|
348
|
+
return buildToken('Space', ' ');
|
|
381
349
|
};
|
|
382
350
|
|
|
383
351
|
export const buildIdentifier = (name) => {
|
|
384
|
-
|
|
385
|
-
|
|
352
|
+
let unquoted = /^[a-zA-Z\u{80}-\u{10ffff}][a-zA-Z0-9_\u{80}-\u{10ffff}-]*$/uy.test(name);
|
|
386
353
|
const expressions = [];
|
|
387
354
|
const gap = buildFilledGapFunction(expressions);
|
|
388
355
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
356
|
+
if (unquoted) {
|
|
357
|
+
return treeFromStream(
|
|
358
|
+
[
|
|
359
|
+
t.nodeOpen(t.nodeFlags, 'Identifier'),
|
|
360
|
+
t.ref`content`,
|
|
361
|
+
gap(buildIdentifierContent(name)),
|
|
362
|
+
t.nodeClose(),
|
|
363
|
+
],
|
|
364
|
+
{ expressions },
|
|
365
|
+
);
|
|
366
|
+
} else {
|
|
367
|
+
return treeFromStream(
|
|
368
|
+
(function* () {
|
|
369
|
+
yield t.nodeOpen(t.nodeFlags, 'Identifier');
|
|
370
|
+
|
|
371
|
+
yield t.ref`openToken`;
|
|
372
|
+
yield gap(buildToken('Punctuator', '`'));
|
|
373
|
+
yield t.ref`content`;
|
|
374
|
+
yield t.nodeOpen(t.tokenFlags, 'IdentifierContent');
|
|
375
|
+
|
|
376
|
+
let lit = '';
|
|
377
|
+
|
|
378
|
+
let pieces = name.split(/[\\`]/g);
|
|
379
|
+
|
|
380
|
+
for (const piece of pieces) {
|
|
381
|
+
if (/[\\`]/y.test(piece)) {
|
|
382
|
+
let chr = piece;
|
|
383
|
+
if (lit) {
|
|
384
|
+
yield agastBuildLiteralTag(lit);
|
|
385
|
+
lit = '';
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
let value = buildKeyword(chr);
|
|
389
|
+
|
|
390
|
+
yield t.ref`@`;
|
|
391
|
+
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', { cooked: chr });
|
|
392
|
+
yield t.ref`escape`;
|
|
393
|
+
yield gap(buildToken('Punctuator', '\\'));
|
|
394
|
+
yield t.ref`value`;
|
|
395
|
+
yield gap(value);
|
|
396
|
+
yield t.nodeClose();
|
|
397
|
+
} else {
|
|
398
|
+
lit += piece;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (lit) yield agastBuildLiteralTag(lit);
|
|
403
|
+
lit = '';
|
|
404
|
+
|
|
405
|
+
yield t.nodeClose();
|
|
406
|
+
|
|
407
|
+
yield t.ref`closeToken`;
|
|
408
|
+
yield gap(buildToken('Punctuator', '`'));
|
|
409
|
+
yield t.nodeClose();
|
|
410
|
+
})(),
|
|
411
|
+
{ expressions },
|
|
412
|
+
);
|
|
413
|
+
}
|
|
398
414
|
};
|
|
399
415
|
|
|
400
416
|
export const buildIdentifierContent = (value) => {
|
|
401
|
-
return buildToken(
|
|
417
|
+
return buildToken('IdentifierContent', value);
|
|
402
418
|
};
|
|
403
419
|
|
|
404
420
|
export const buildKeyword = (name) => {
|
|
405
|
-
return buildToken(
|
|
421
|
+
return buildToken('Keyword', name);
|
|
406
422
|
};
|
|
407
423
|
|
|
408
424
|
export const buildCall = (verb, args) => {
|
|
@@ -411,7 +427,7 @@ export const buildCall = (verb, args) => {
|
|
|
411
427
|
|
|
412
428
|
return treeFromStream(
|
|
413
429
|
[
|
|
414
|
-
t.nodeOpen(t.nodeFlags,
|
|
430
|
+
t.nodeOpen(t.nodeFlags, 'Call'),
|
|
415
431
|
t.ref`verb`,
|
|
416
432
|
gap(verb),
|
|
417
433
|
t.ref`arguments`,
|
|
@@ -428,11 +444,11 @@ export const buildProperty = (key, value) => {
|
|
|
428
444
|
|
|
429
445
|
return treeFromStream(
|
|
430
446
|
(function* () {
|
|
431
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
447
|
+
yield t.nodeOpen(t.nodeFlags, 'Property');
|
|
432
448
|
yield t.ref`key`;
|
|
433
449
|
yield gap(key);
|
|
434
450
|
yield t.ref`mapOperator`;
|
|
435
|
-
yield gap(buildToken(
|
|
451
|
+
yield gap(buildToken('Punctuator', ':'));
|
|
436
452
|
yield t.ref`#`;
|
|
437
453
|
yield gap(buildSpace());
|
|
438
454
|
yield t.ref`value`;
|
|
@@ -451,7 +467,7 @@ const escapables = {
|
|
|
451
467
|
};
|
|
452
468
|
|
|
453
469
|
export const buildDigit = (value) => {
|
|
454
|
-
return buildToken(
|
|
470
|
+
return buildToken('Digit', value);
|
|
455
471
|
};
|
|
456
472
|
|
|
457
473
|
export const buildInteger = (value, base = 10) => {
|
|
@@ -462,7 +478,7 @@ export const buildInteger = (value, base = 10) => {
|
|
|
462
478
|
|
|
463
479
|
return treeFromStream(
|
|
464
480
|
concat(
|
|
465
|
-
[t.nodeOpen(t.nodeFlags,
|
|
481
|
+
[t.nodeOpen(t.nodeFlags, 'Integer'), t.ref`digits[]`, t.arr()],
|
|
466
482
|
digits.flatMap((digit) => [t.ref`digits[]`, gap(buildDigit(digit))]),
|
|
467
483
|
[t.nodeClose()],
|
|
468
484
|
),
|
|
@@ -486,11 +502,11 @@ export const buildInfinity = (value) => {
|
|
|
486
502
|
|
|
487
503
|
return treeFromStream(
|
|
488
504
|
[
|
|
489
|
-
t.nodeOpen(t.nodeFlags,
|
|
505
|
+
t.nodeOpen(t.nodeFlags, 'Infinity'),
|
|
490
506
|
t.ref`sign`,
|
|
491
|
-
gap(buildToken(
|
|
507
|
+
gap(buildToken('Punctuator', sign)),
|
|
492
508
|
t.ref`value`,
|
|
493
|
-
gap(buildToken(
|
|
509
|
+
gap(buildToken('Keyword', 'Infinity')),
|
|
494
510
|
t.nodeClose(),
|
|
495
511
|
],
|
|
496
512
|
{ expressions },
|
|
@@ -506,6 +522,7 @@ export const buildNumber = (value) => {
|
|
|
506
522
|
};
|
|
507
523
|
|
|
508
524
|
export const buildString = (value) => {
|
|
525
|
+
if (value == null) throw new Error();
|
|
509
526
|
const pieces = isArray(value) ? value : [value];
|
|
510
527
|
let lit = '';
|
|
511
528
|
|
|
@@ -514,13 +531,13 @@ export const buildString = (value) => {
|
|
|
514
531
|
const gap = buildFilledGapFunction(expressions);
|
|
515
532
|
return treeFromStream(
|
|
516
533
|
[
|
|
517
|
-
t.nodeOpen(t.nodeFlags,
|
|
534
|
+
t.nodeOpen(t.nodeFlags, 'String'),
|
|
518
535
|
t.ref`openToken`,
|
|
519
|
-
gap(buildToken(
|
|
536
|
+
gap(buildToken('Punctuator', '"')),
|
|
520
537
|
t.ref`content`,
|
|
521
|
-
gap(buildToken(
|
|
538
|
+
gap(buildToken('StringContent', value)),
|
|
522
539
|
t.ref`closeToken`,
|
|
523
|
-
gap(buildToken(
|
|
540
|
+
gap(buildToken('Punctuator', '"')),
|
|
524
541
|
t.nodeClose(),
|
|
525
542
|
],
|
|
526
543
|
{ expressions },
|
|
@@ -532,12 +549,12 @@ export const buildString = (value) => {
|
|
|
532
549
|
|
|
533
550
|
return treeFromStream(
|
|
534
551
|
(function* () {
|
|
535
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
552
|
+
yield t.nodeOpen(t.nodeFlags, 'String');
|
|
536
553
|
yield t.ref`openToken`;
|
|
537
|
-
const tok = buildToken(
|
|
554
|
+
const tok = buildToken('Punctuator', "'");
|
|
538
555
|
yield gap(tok);
|
|
539
556
|
yield t.ref`content`;
|
|
540
|
-
yield t.nodeOpen(t.tokenFlags,
|
|
557
|
+
yield t.nodeOpen(t.tokenFlags, 'StringContent');
|
|
541
558
|
|
|
542
559
|
for (const piece of pieces) {
|
|
543
560
|
if (isString(piece)) {
|
|
@@ -566,7 +583,7 @@ export const buildString = (value) => {
|
|
|
566
583
|
|
|
567
584
|
value = treeFromStream(
|
|
568
585
|
[
|
|
569
|
-
t.nodeOpen(t.nodeFlags,
|
|
586
|
+
t.nodeOpen(t.nodeFlags, 'EscapeCode'),
|
|
570
587
|
t.ref`sigilToken`,
|
|
571
588
|
gap(buildKeyword(escapables[chr])),
|
|
572
589
|
t.ref`digits[]`,
|
|
@@ -582,7 +599,7 @@ export const buildString = (value) => {
|
|
|
582
599
|
|
|
583
600
|
value = treeFromStream(
|
|
584
601
|
[
|
|
585
|
-
t.nodeOpen(t.nodeFlags,
|
|
602
|
+
t.nodeOpen(t.nodeFlags, 'EscapeCode'),
|
|
586
603
|
t.ref`sigilToken`,
|
|
587
604
|
gap(buildKeyword('u')),
|
|
588
605
|
t.ref`digits[]`,
|
|
@@ -597,9 +614,9 @@ export const buildString = (value) => {
|
|
|
597
614
|
}
|
|
598
615
|
|
|
599
616
|
yield t.ref`@`;
|
|
600
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
617
|
+
yield t.nodeOpen(t.nodeFlags, 'EscapeSequence', { cooked: chr });
|
|
601
618
|
yield t.ref`escape`;
|
|
602
|
-
yield gap(buildToken(
|
|
619
|
+
yield gap(buildToken('Punctuator', '\\'));
|
|
603
620
|
yield t.ref`value`;
|
|
604
621
|
yield gap(value);
|
|
605
622
|
yield t.nodeClose();
|
|
@@ -626,7 +643,7 @@ export const buildString = (value) => {
|
|
|
626
643
|
|
|
627
644
|
yield t.nodeClose();
|
|
628
645
|
yield t.ref`closeToken`;
|
|
629
|
-
yield gap(buildToken(
|
|
646
|
+
yield gap(buildToken('Punctuator', "'"));
|
|
630
647
|
yield t.nodeClose();
|
|
631
648
|
})(),
|
|
632
649
|
{ expressions },
|
|
@@ -639,9 +656,9 @@ export const buildBoolean = (value) => {
|
|
|
639
656
|
|
|
640
657
|
return treeFromStream(
|
|
641
658
|
[
|
|
642
|
-
t.nodeOpen(t.nodeFlags,
|
|
659
|
+
t.nodeOpen(t.nodeFlags, 'Boolean'),
|
|
643
660
|
t.ref`sigilToken`,
|
|
644
|
-
gap(buildToken(
|
|
661
|
+
gap(buildToken('Keyword', value ? 'true' : 'false')),
|
|
645
662
|
t.nodeClose(),
|
|
646
663
|
],
|
|
647
664
|
{ expressions },
|
|
@@ -654,9 +671,24 @@ export const buildNull = () => {
|
|
|
654
671
|
|
|
655
672
|
return treeFromStream(
|
|
656
673
|
[
|
|
657
|
-
t.nodeOpen(t.nodeFlags,
|
|
674
|
+
t.nodeOpen(t.nodeFlags, 'Null'),
|
|
675
|
+
t.ref`sigilToken`,
|
|
676
|
+
gap(buildToken('Keyword', 'null')),
|
|
677
|
+
t.nodeClose(),
|
|
678
|
+
],
|
|
679
|
+
{ expressions },
|
|
680
|
+
);
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
export const buildUndefined = () => {
|
|
684
|
+
const expressions = [];
|
|
685
|
+
const gap = buildFilledGapFunction(expressions);
|
|
686
|
+
|
|
687
|
+
return treeFromStream(
|
|
688
|
+
[
|
|
689
|
+
t.nodeOpen(t.nodeFlags, 'Undefined'),
|
|
658
690
|
t.ref`sigilToken`,
|
|
659
|
-
gap(buildToken(
|
|
691
|
+
gap(buildToken('Keyword', 'undefined')),
|
|
660
692
|
t.nodeClose(),
|
|
661
693
|
],
|
|
662
694
|
{ expressions },
|
|
@@ -669,9 +701,9 @@ export const buildNullTag = () => {
|
|
|
669
701
|
|
|
670
702
|
return treeFromStream(
|
|
671
703
|
[
|
|
672
|
-
t.nodeOpen(t.nodeFlags,
|
|
704
|
+
t.nodeOpen(t.nodeFlags, 'NullTag'),
|
|
673
705
|
t.ref`sigilToken`,
|
|
674
|
-
gap(buildToken(
|
|
706
|
+
gap(buildToken('Keyword', 'null')),
|
|
675
707
|
t.nodeClose(),
|
|
676
708
|
],
|
|
677
709
|
{ expressions },
|
|
@@ -684,12 +716,12 @@ export const buildArray = (elements) => {
|
|
|
684
716
|
|
|
685
717
|
return treeFromStream(
|
|
686
718
|
(function* () {
|
|
687
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
719
|
+
yield t.nodeOpen(t.nodeFlags, 'Array');
|
|
688
720
|
yield t.ref`openToken`;
|
|
689
|
-
yield gap(buildToken(
|
|
721
|
+
yield gap(buildToken('Punctuator', '['));
|
|
690
722
|
yield* interpolateFragment(elements, t.ref`elements[]`, expressions);
|
|
691
723
|
yield t.ref`closeToken`;
|
|
692
|
-
yield gap(buildToken(
|
|
724
|
+
yield gap(buildToken('Punctuator', ']'));
|
|
693
725
|
yield t.nodeClose();
|
|
694
726
|
})(),
|
|
695
727
|
{ expressions },
|
|
@@ -702,14 +734,14 @@ export const buildArrayElements = (values) => {
|
|
|
702
734
|
(function* () {
|
|
703
735
|
yield t.doctype({ bablrLanguage: l.Instruction });
|
|
704
736
|
yield t.nodeOpen(t.nodeFlags);
|
|
705
|
-
yield*
|
|
737
|
+
yield* buildCommaSeparatedList(values, t.ref`.[]`, expressions);
|
|
706
738
|
yield t.nodeClose();
|
|
707
739
|
})(),
|
|
708
740
|
{ expressions },
|
|
709
741
|
);
|
|
710
742
|
};
|
|
711
743
|
|
|
712
|
-
export function*
|
|
744
|
+
export function* buildCommaSeparatedList(values, ref, expressions) {
|
|
713
745
|
const gap = buildFilledGapFunction(expressions);
|
|
714
746
|
|
|
715
747
|
if (!ref.value.isArray) throw new Error();
|
|
@@ -720,8 +752,8 @@ export function* buildSpaceSeparatedList(values, ref, expressions) {
|
|
|
720
752
|
let first = true;
|
|
721
753
|
for (const value of values) {
|
|
722
754
|
if (!first) {
|
|
723
|
-
yield t.buildReferenceTag('#'
|
|
724
|
-
yield gap(
|
|
755
|
+
yield t.buildReferenceTag('#');
|
|
756
|
+
yield gap(buildToken('Punctuator', ','));
|
|
725
757
|
}
|
|
726
758
|
yield freeze({ ...ref });
|
|
727
759
|
yield gap(value || buildNullNode());
|
|
@@ -735,7 +767,7 @@ export const buildObjectProperties = (properties) => {
|
|
|
735
767
|
return treeFromStream(
|
|
736
768
|
concat(
|
|
737
769
|
[t.doctype({ bablrLanguage: l.Instruction }), t.nodeOpen(t.nodeFlags)],
|
|
738
|
-
|
|
770
|
+
buildCommaSeparatedList(properties, t.ref`properties[]`, expressions),
|
|
739
771
|
[t.nodeClose()],
|
|
740
772
|
),
|
|
741
773
|
{ expressions },
|
|
@@ -748,14 +780,14 @@ export const buildObject = (properties) => {
|
|
|
748
780
|
|
|
749
781
|
return treeFromStream(
|
|
750
782
|
(function* () {
|
|
751
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
783
|
+
yield t.nodeOpen(t.nodeFlags, 'Object');
|
|
752
784
|
yield t.ref`openToken`;
|
|
753
|
-
yield gap(buildToken(
|
|
785
|
+
yield gap(buildToken('Punctuator', '{'));
|
|
754
786
|
|
|
755
787
|
yield* interpolateFragment(properties, t.ref`properties[]`, expressions);
|
|
756
788
|
|
|
757
789
|
yield t.ref`closeToken`;
|
|
758
|
-
yield gap(buildToken(
|
|
790
|
+
yield gap(buildToken('Punctuator', '}'));
|
|
759
791
|
yield t.nodeClose();
|
|
760
792
|
})(),
|
|
761
793
|
{ expressions },
|
|
@@ -768,14 +800,36 @@ export const buildPattern = (alternatives, flags) => {
|
|
|
768
800
|
|
|
769
801
|
return treeFromStream(
|
|
770
802
|
(function* () {
|
|
771
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
803
|
+
yield t.nodeOpen(t.nodeFlags, 'Pattern');
|
|
804
|
+
yield t.ref`openToken`;
|
|
805
|
+
yield gap(buildToken('Punctuator', '/'));
|
|
806
|
+
|
|
807
|
+
yield* interpolateFragment(alternatives, t.ref`alternatives[]`, expressions);
|
|
808
|
+
|
|
809
|
+
yield t.ref`closeToken`;
|
|
810
|
+
yield gap(buildToken('Punctuator', '/'));
|
|
811
|
+
yield t.ref`flags`;
|
|
812
|
+
yield gap(flags || buildReferenceFlags());
|
|
813
|
+
yield t.nodeClose();
|
|
814
|
+
})(),
|
|
815
|
+
{ expressions },
|
|
816
|
+
);
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
export const buildRegexGroup = (alternatives, flags) => {
|
|
820
|
+
const expressions = [];
|
|
821
|
+
const gap = buildFilledGapFunction(expressions);
|
|
822
|
+
|
|
823
|
+
return treeFromStream(
|
|
824
|
+
(function* () {
|
|
825
|
+
yield t.nodeOpen(t.nodeFlags, 'Group');
|
|
772
826
|
yield t.ref`openToken`;
|
|
773
|
-
yield gap(buildToken(
|
|
827
|
+
yield gap(buildToken('Punctuator', '('));
|
|
774
828
|
|
|
775
829
|
yield* interpolateFragment(alternatives, t.ref`alternatives[]`, expressions);
|
|
776
830
|
|
|
777
831
|
yield t.ref`closeToken`;
|
|
778
|
-
yield gap(buildToken(
|
|
832
|
+
yield gap(buildToken('Punctuator', ')'));
|
|
779
833
|
yield t.ref`flags`;
|
|
780
834
|
yield gap(flags || buildReferenceFlags());
|
|
781
835
|
yield t.nodeClose();
|
|
@@ -799,12 +853,12 @@ export const buildRegexFlags = (flags = '') => {
|
|
|
799
853
|
|
|
800
854
|
return treeFromStream(
|
|
801
855
|
(function* () {
|
|
802
|
-
yield t.nodeOpen(t.nodeFlags,
|
|
856
|
+
yield t.nodeOpen(t.nodeFlags, 'Flags');
|
|
803
857
|
|
|
804
858
|
for (const { 0: name, 1: chr } of Object.entries(flagCharacters)) {
|
|
805
859
|
yield t.buildReferenceTag(name + 'Token');
|
|
806
860
|
|
|
807
|
-
yield gap(flags.includes(chr) ? buildToken(
|
|
861
|
+
yield gap(flags.includes(chr) ? buildToken('Punctuator', chr) : buildNullNode());
|
|
808
862
|
}
|
|
809
863
|
yield t.nodeClose();
|
|
810
864
|
})(),
|
|
@@ -817,7 +871,7 @@ export const buildAlternative = (elements) => {
|
|
|
817
871
|
|
|
818
872
|
return treeFromStream(
|
|
819
873
|
concat(
|
|
820
|
-
[t.nodeOpen(t.nodeFlags,
|
|
874
|
+
[t.nodeOpen(t.nodeFlags, 'Alternative')],
|
|
821
875
|
interpolateFragment(elements, t.ref`elements[]+`, expressions),
|
|
822
876
|
[t.nodeClose()],
|
|
823
877
|
),
|
|
@@ -831,7 +885,7 @@ export const buildAlternatives = (alternatives = []) => {
|
|
|
831
885
|
|
|
832
886
|
return treeFromStream(
|
|
833
887
|
(function* () {
|
|
834
|
-
yield t.doctype({ bablrLanguage: l.
|
|
888
|
+
yield t.doctype({ bablrLanguage: l.Instruction });
|
|
835
889
|
yield t.nodeOpen(t.nodeFlags);
|
|
836
890
|
yield t.ref`.[]`;
|
|
837
891
|
yield t.arr();
|
|
@@ -843,7 +897,7 @@ export const buildAlternatives = (alternatives = []) => {
|
|
|
843
897
|
t.ref`.[]`,
|
|
844
898
|
gap(alt),
|
|
845
899
|
t.ref`separatorTokens[]`,
|
|
846
|
-
gap(buildPunctuator(
|
|
900
|
+
gap(buildPunctuator('|')),
|
|
847
901
|
])
|
|
848
902
|
.slice(0, -2);
|
|
849
903
|
|
|
@@ -859,11 +913,11 @@ export const buildRegexGap = () => {
|
|
|
859
913
|
|
|
860
914
|
return treeFromStream(
|
|
861
915
|
[
|
|
862
|
-
t.nodeOpen(t.nodeFlags,
|
|
916
|
+
t.nodeOpen(t.nodeFlags, 'Gap'),
|
|
863
917
|
t.ref`escapeToken`,
|
|
864
|
-
gap(buildToken(
|
|
918
|
+
gap(buildToken('Punctuator', '\\')),
|
|
865
919
|
t.ref`value`,
|
|
866
|
-
gap(buildToken(
|
|
920
|
+
gap(buildToken('Keyword', 'g')),
|
|
867
921
|
t.nodeClose(),
|
|
868
922
|
],
|
|
869
923
|
{ expressions },
|
|
@@ -876,7 +930,7 @@ export const buildElements = (elements) => {
|
|
|
876
930
|
|
|
877
931
|
return treeFromStream(
|
|
878
932
|
concat(
|
|
879
|
-
[t.doctype({ bablrLanguage: l.
|
|
933
|
+
[t.doctype({ bablrLanguage: l.Instruction }), t.nodeOpen(t.nodeFlags), t.ref`.[]+`, t.arr()],
|
|
880
934
|
elements.flatMap((el) => [t.ref`.[]+`, gap(el)]),
|
|
881
935
|
[t.nodeClose()],
|
|
882
936
|
),
|
|
@@ -884,41 +938,45 @@ export const buildElements = (elements) => {
|
|
|
884
938
|
);
|
|
885
939
|
};
|
|
886
940
|
|
|
887
|
-
export const
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
if (
|
|
941
|
+
export const buildJSExpressionDeep = (expr) => {
|
|
942
|
+
if (expr === null) {
|
|
943
|
+
return buildNull();
|
|
944
|
+
} else if (expr === undefined) {
|
|
945
|
+
return buildUndefined();
|
|
946
|
+
}
|
|
891
947
|
|
|
892
948
|
switch (typeof expr) {
|
|
893
|
-
case 'symbol':
|
|
894
949
|
case 'boolean':
|
|
895
950
|
return buildBoolean(expr);
|
|
951
|
+
|
|
896
952
|
case 'string':
|
|
897
953
|
return buildString(expr);
|
|
954
|
+
|
|
898
955
|
case 'number':
|
|
899
956
|
return buildInteger(expr);
|
|
957
|
+
|
|
900
958
|
case 'object': {
|
|
901
|
-
switch (getPrototypeOf(expr)) {
|
|
959
|
+
switch (Object.getPrototypeOf(expr)) {
|
|
902
960
|
case Array.prototype:
|
|
903
|
-
return buildArray(buildArrayElements(expr));
|
|
961
|
+
return buildArray(buildArrayElements(expr.map((e) => buildJSExpressionDeep(e))));
|
|
962
|
+
|
|
904
963
|
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
964
|
return buildObject(
|
|
914
965
|
buildObjectProperties(
|
|
915
|
-
Object.entries(expr).map((e) =>
|
|
966
|
+
Object.entries(expr).map((e) =>
|
|
967
|
+
buildProperty(
|
|
968
|
+
/^[a-zA-Z_]+$/.test(e[0]) ? buildIdentifier(e[0]) : buildString(e[0]),
|
|
969
|
+
buildJSExpressionDeep(e[1]),
|
|
970
|
+
),
|
|
971
|
+
),
|
|
916
972
|
),
|
|
917
973
|
);
|
|
974
|
+
|
|
918
975
|
default:
|
|
919
976
|
throw new Error();
|
|
920
977
|
}
|
|
921
978
|
}
|
|
979
|
+
|
|
922
980
|
default:
|
|
923
981
|
throw new Error();
|
|
924
982
|
}
|
|
@@ -930,15 +988,15 @@ export const buildTaggedString = (tag, content) => {
|
|
|
930
988
|
|
|
931
989
|
return treeFromStream(
|
|
932
990
|
[
|
|
933
|
-
t.buildOpenNodeTag(t.nodeFlags,
|
|
991
|
+
t.buildOpenNodeTag(t.nodeFlags, 'SpamexString'),
|
|
934
992
|
t.buildReferenceTag('sigilToken'),
|
|
935
|
-
gap(buildToken(
|
|
993
|
+
gap(buildToken('Keyword', tag)),
|
|
936
994
|
t.buildReferenceTag('openToken'),
|
|
937
|
-
gap(buildToken(
|
|
995
|
+
gap(buildToken('Punctuator', "'")),
|
|
938
996
|
t.buildReferenceTag('content'),
|
|
939
997
|
gap(content),
|
|
940
998
|
t.buildReferenceTag('closeToken'),
|
|
941
|
-
gap(buildToken(
|
|
999
|
+
gap(buildToken('Punctuator', "'")),
|
|
942
1000
|
t.buildCloseNodeTag(),
|
|
943
1001
|
],
|
|
944
1002
|
{ expressions },
|
|
@@ -953,15 +1011,17 @@ export const buildRegexString = (content) => {
|
|
|
953
1011
|
return buildTaggedString('re', content);
|
|
954
1012
|
};
|
|
955
1013
|
|
|
956
|
-
export const buildPropertyMatcher = (refMatcher, nodeMatcher) => {
|
|
1014
|
+
export const buildPropertyMatcher = (refMatcher, bindingMatcher, nodeMatcher) => {
|
|
957
1015
|
const expressions = [];
|
|
958
1016
|
const gap = buildFilledGapFunction(expressions);
|
|
959
1017
|
|
|
960
1018
|
return treeFromStream(
|
|
961
1019
|
[
|
|
962
|
-
t.nodeOpen(t.nodeFlags,
|
|
1020
|
+
t.nodeOpen(t.nodeFlags, 'PropertyMatcher'),
|
|
963
1021
|
t.ref`refMatcher`,
|
|
964
1022
|
gap(refMatcher || buildNullNode()),
|
|
1023
|
+
t.ref`bindingMatcher`,
|
|
1024
|
+
gap(bindingMatcher || buildNullNode()),
|
|
965
1025
|
t.ref`nodeMatcher`,
|
|
966
1026
|
gap(nodeMatcher),
|
|
967
1027
|
t.nodeClose(),
|
|
@@ -971,5 +1031,5 @@ export const buildPropertyMatcher = (refMatcher, nodeMatcher) => {
|
|
|
971
1031
|
};
|
|
972
1032
|
|
|
973
1033
|
export const buildGapNodeMatcher = () => {
|
|
974
|
-
return buildToken(
|
|
1034
|
+
return buildToken('GapNodeMatcher', '<//>');
|
|
975
1035
|
};
|