@bablr/agast-vm-helpers 0.3.2 → 0.5.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 +281 -166
- package/lib/deembed.js +3 -1
- package/lib/index.js +164 -32
- package/package.json +2 -2
package/lib/builders.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
// import { i } from '@bablr/boot/shorthand.macro';
|
|
2
|
-
import {
|
|
3
|
-
interpolateArray,
|
|
4
|
-
interpolateArrayChildren,
|
|
5
|
-
interpolateString,
|
|
6
|
-
} from '@bablr/agast-helpers/template';
|
|
2
|
+
import { interpolateFragmentChildren, interpolateString } from '@bablr/agast-helpers/template';
|
|
7
3
|
import { isNull } from '@bablr/agast-helpers/tree';
|
|
4
|
+
import { buildLiteralTag as agastBuildLiteralTag } from '@bablr/agast-helpers/builders';
|
|
8
5
|
import * as t from '@bablr/agast-helpers/shorthand';
|
|
6
|
+
import * as btree from '@bablr/agast-helpers/btree';
|
|
9
7
|
import * as l from './languages.js';
|
|
10
8
|
|
|
11
9
|
const { getPrototypeOf, freeze } = Object;
|
|
@@ -20,54 +18,83 @@ function* repeat(times, ...values) {
|
|
|
20
18
|
for (let i = 0; i < times; i++) for (const value of values) yield value;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
function* concat(...iterables) {
|
|
22
|
+
for (const iterable of iterables) yield* iterable;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const buildSeparatedListChildren = (list, ref, sep) => {
|
|
26
|
+
const children = [];
|
|
27
|
+
let first = true;
|
|
28
|
+
for (const _ of list) {
|
|
29
|
+
if (!first && sep) {
|
|
30
|
+
children.push(freeze({ ...sep }));
|
|
31
|
+
}
|
|
32
|
+
children.push(freeze({ ...ref }));
|
|
33
|
+
first = false;
|
|
34
|
+
}
|
|
35
|
+
return children;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const buildReferenceTag = (name, isArray, hasGap) => {
|
|
24
39
|
return t.node(
|
|
25
40
|
l.CSTML,
|
|
26
|
-
'
|
|
27
|
-
|
|
41
|
+
'ReferenceTag',
|
|
42
|
+
btree.fromValues(
|
|
43
|
+
concat(
|
|
44
|
+
[t.ref`name`],
|
|
45
|
+
when(isArray, [t.ref`arrayOperatorToken`]),
|
|
46
|
+
when(hasGap, [t.ref`hasGapToken`]),
|
|
47
|
+
[t.ref`sigilToken`],
|
|
48
|
+
),
|
|
49
|
+
),
|
|
28
50
|
{
|
|
29
51
|
name: buildIdentifier(name),
|
|
30
52
|
arrayOperatorToken: isArray ? t.s_node(l.CSTML, 'Punctuator', '[]') : t.null_node(),
|
|
53
|
+
hasGapToken: hasGap ? t.s_node(l.CSTML, 'Punctuator', '$') : t.null_node(),
|
|
31
54
|
sigilToken: t.s_node(l.CSTML, 'Punctuator', ':'),
|
|
32
55
|
},
|
|
33
56
|
);
|
|
34
57
|
};
|
|
35
58
|
|
|
36
|
-
export const
|
|
37
|
-
return t.node(l.CSTML, '
|
|
59
|
+
export const buildGapTag = () => {
|
|
60
|
+
return t.node(l.CSTML, 'GapTag', [t.ref`sigilToken`], {
|
|
38
61
|
sigilToken: t.s_node(l.CSTML, 'Punctuator', '<//>'),
|
|
39
62
|
});
|
|
40
63
|
};
|
|
41
64
|
|
|
42
|
-
export const
|
|
43
|
-
return t.node(l.CSTML, '
|
|
65
|
+
export const buildShiftTag = () => {
|
|
66
|
+
return t.node(l.CSTML, 'ShiftTag', [t.ref`sigilToken`], {
|
|
44
67
|
sigilToken: t.s_node(l.CSTML, 'Punctuator', '^^^'),
|
|
45
68
|
});
|
|
46
69
|
};
|
|
47
70
|
|
|
48
71
|
export const buildFlags = (flags = {}) => {
|
|
49
|
-
const {
|
|
72
|
+
const { token = null, escape = null, trivia = null, expression = null, hasGap = null } = flags;
|
|
50
73
|
|
|
51
74
|
if ((trivia && escape) || (expression && (trivia || escape))) {
|
|
52
75
|
throw new Error('invalid flags');
|
|
53
76
|
}
|
|
54
77
|
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
return t.node(
|
|
79
|
+
l.CSTML,
|
|
80
|
+
'Flags',
|
|
81
|
+
btree.fromValues(
|
|
82
|
+
concat(
|
|
83
|
+
when(trivia, [t.ref`triviaToken`]),
|
|
84
|
+
when(token, [t.ref`tokenToken`]),
|
|
85
|
+
when(escape, [t.ref`escapeToken`]),
|
|
86
|
+
when(expression, [t.ref`expressionToken`]),
|
|
87
|
+
when(hasGap, [t.ref`hasGapToken`]),
|
|
88
|
+
),
|
|
89
|
+
),
|
|
90
|
+
{
|
|
64
91
|
triviaToken: trivia ? t.s_node(l.CSTML, 'Punctuator', '#') : t.null_node(),
|
|
65
|
-
intrinsicToken: intrinsic ? t.s_node(l.CSTML, 'Punctuator', '~') : t.null_node(),
|
|
66
92
|
tokenToken: token ? t.s_node(l.CSTML, 'Punctuator', '*') : t.null_node(),
|
|
67
93
|
escapeToken: escape ? t.s_node(l.CSTML, 'Punctuator', '@') : t.null_node(),
|
|
68
94
|
expressionToken: expression ? t.s_node(l.CSTML, 'Punctuator', '+') : t.null_node(),
|
|
95
|
+
hasGapToken: hasGap ? t.s_node(l.CSTML, 'Punctuator', '$') : t.null_node(),
|
|
69
96
|
},
|
|
70
|
-
|
|
97
|
+
);
|
|
71
98
|
};
|
|
72
99
|
|
|
73
100
|
export const buildSpamMatcher = (type = null, value = null, attributes = {}) => {
|
|
@@ -93,30 +120,35 @@ export const buildFullyQualifiedSpamMatcher = (
|
|
|
93
120
|
language_ = lArr.length === 0 ? null : lArr;
|
|
94
121
|
}
|
|
95
122
|
|
|
96
|
-
return t.node(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
return t.node(l.Spamex, 'NodeMatcher', [t.ref`open`], {
|
|
124
|
+
open: t.node(
|
|
125
|
+
l.Spamex,
|
|
126
|
+
'NodeMatcher',
|
|
127
|
+
btree.fromValues(
|
|
128
|
+
concat(
|
|
129
|
+
[t.ref`openToken`, t.ref`flags`],
|
|
130
|
+
when(language_, [t.ref`language`, t.ref`languageSeparator`]),
|
|
131
|
+
when(type, [t.ref`type`]),
|
|
132
|
+
when(intrinsicValue, [t.embedded(buildSpace()), t.ref`intrinsicValue`]),
|
|
133
|
+
when(attributes_.length, [t.embedded(buildSpace())]),
|
|
134
|
+
interpolateFragmentChildren(attributes_, t.ref`attributes[]`),
|
|
135
|
+
when(!type, [t.embedded(buildSpace())]),
|
|
136
|
+
[t.ref`selfClosingTagToken`, t.ref`closeToken`],
|
|
137
|
+
),
|
|
138
|
+
),
|
|
139
|
+
{
|
|
140
|
+
openToken: t.s_node(l.CSTML, 'Punctuator', '<'),
|
|
141
|
+
flags: buildFlags(flags),
|
|
142
|
+
language: language_ ? buildLanguage(language_) : t.null_node(),
|
|
143
|
+
languageSeparator: language_ && type ? t.s_node(l.CSTML, 'Punctuator', ':') : t.null_node(),
|
|
144
|
+
type: type ? buildIdentifier(type) : t.null_node(),
|
|
145
|
+
intrinsicValue: intrinsicValue ? buildString(intrinsicValue) : t.null_node(),
|
|
146
|
+
attributes: attributes_.properties['.'],
|
|
147
|
+
selfClosingTagToken: t.s_node(l.CSTML, 'Punctuator', '/'),
|
|
148
|
+
closeToken: t.s_node(l.CSTML, 'Punctuator', '>'),
|
|
149
|
+
},
|
|
150
|
+
),
|
|
151
|
+
});
|
|
120
152
|
};
|
|
121
153
|
|
|
122
154
|
export const buildNodeOpenTag = (flags, language, type = null, attributes = {}) => {
|
|
@@ -127,22 +159,23 @@ export const buildNodeOpenTag = (flags, language, type = null, attributes = {})
|
|
|
127
159
|
return t.node(
|
|
128
160
|
l.CSTML,
|
|
129
161
|
'OpenNodeTag',
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
162
|
+
btree.fromValues(
|
|
163
|
+
concat(
|
|
164
|
+
[t.ref`openToken`, t.ref`flags`],
|
|
165
|
+
when(language_, [t.ref`language`, t.ref`languageSeparator`]),
|
|
166
|
+
when(type, [t.ref`type`]),
|
|
167
|
+
when(attributes_.length, [t.embedded(buildSpace())]),
|
|
168
|
+
interpolateFragmentChildren(attributes_, t.ref`attributes[]`),
|
|
169
|
+
[t.ref`closeToken`],
|
|
170
|
+
),
|
|
171
|
+
),
|
|
139
172
|
{
|
|
140
173
|
openToken: t.s_node(l.CSTML, 'Punctuator', '<'),
|
|
141
174
|
flags: buildFlags(flags),
|
|
142
175
|
language: language_ && type ? buildLanguage(language_) : t.null_node(),
|
|
143
176
|
languageSeparator: language_ && type ? t.s_node(l.CSTML, 'Punctuator', ':') : t.null_node(),
|
|
144
177
|
type: type ? buildIdentifier(type) : t.null_node(),
|
|
145
|
-
attributes: attributes_,
|
|
178
|
+
attributes: attributes_.properties['.'],
|
|
146
179
|
closeToken: t.s_node(l.CSTML, 'Punctuator', '>'),
|
|
147
180
|
},
|
|
148
181
|
);
|
|
@@ -154,21 +187,20 @@ export const buildDoctypeTag = (attributes) => {
|
|
|
154
187
|
return t.node(
|
|
155
188
|
l.CSTML,
|
|
156
189
|
'DoctypeTag',
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
],
|
|
190
|
+
btree.fromValues(
|
|
191
|
+
concat(
|
|
192
|
+
[t.ref`openToken`, t.ref`version`, t.ref`versionSeparator`, t.ref`doctype`],
|
|
193
|
+
when(attributes_.length, [t.embedded(buildSpace())]),
|
|
194
|
+
interpolateFragmentChildren(attributes_, t.ref`attributes[]`),
|
|
195
|
+
[t.ref`closeToken`],
|
|
196
|
+
),
|
|
197
|
+
),
|
|
166
198
|
{
|
|
167
199
|
openToken: t.s_node(l.CSTML, 'Punctuator', '<!'),
|
|
168
200
|
version: t.s_node(l.CSTML, 'PositiveInteger', '0'),
|
|
169
201
|
versionSeparator: t.s_node(l.CSTML, 'Punctuator', ':'),
|
|
170
202
|
doctype: t.s_node(l.CSTML, 'Keyword', 'cstml'),
|
|
171
|
-
attributes: attributes_,
|
|
203
|
+
attributes: attributes_.properties['.'],
|
|
172
204
|
closeToken: t.s_node(l.CSTML, 'Punctuator', '>'),
|
|
173
205
|
},
|
|
174
206
|
);
|
|
@@ -186,7 +218,13 @@ export const buildIdentifierPath = (path) => {
|
|
|
186
218
|
return t.node(
|
|
187
219
|
l.CSTML,
|
|
188
220
|
'IdentifierPath',
|
|
189
|
-
|
|
221
|
+
btree.fromValues(
|
|
222
|
+
concat(
|
|
223
|
+
[t.ref`segments[]`, t.arr()],
|
|
224
|
+
repeat(segments.length - 1, t.ref`segments[]`, t.ref`separators[]`),
|
|
225
|
+
[t.ref`segments[]`],
|
|
226
|
+
),
|
|
227
|
+
),
|
|
190
228
|
{
|
|
191
229
|
segments,
|
|
192
230
|
separators,
|
|
@@ -204,13 +242,15 @@ export const buildNodeCloseTag = (type, language) => {
|
|
|
204
242
|
return t.node(
|
|
205
243
|
l.CSTML,
|
|
206
244
|
'CloseNodeTag',
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
245
|
+
btree.fromValues(
|
|
246
|
+
concat(
|
|
247
|
+
[t.ref`openToken`],
|
|
248
|
+
when(language, [t.ref`language`]),
|
|
249
|
+
when(type && language, [t.ref`languageSeparator`]),
|
|
250
|
+
when(type, [t.ref`type`]),
|
|
251
|
+
[t.ref`closeToken`],
|
|
252
|
+
),
|
|
253
|
+
),
|
|
214
254
|
{
|
|
215
255
|
openToken: t.s_node(l.CSTML, 'Punctuator', '</'),
|
|
216
256
|
language: language ? buildLanguage(language) : t.null_node(),
|
|
@@ -221,8 +261,8 @@ export const buildNodeCloseTag = (type, language) => {
|
|
|
221
261
|
);
|
|
222
262
|
};
|
|
223
263
|
|
|
224
|
-
export const
|
|
225
|
-
return t.node(l.CSTML, '
|
|
264
|
+
export const buildLiteralTag = (value) => {
|
|
265
|
+
return t.node(l.CSTML, 'LiteralTag', [t.ref`value`], { value });
|
|
226
266
|
};
|
|
227
267
|
|
|
228
268
|
export const buildTerminalProps = (matcher) => {
|
|
@@ -254,7 +294,7 @@ export const buildProperty = (key, value) => {
|
|
|
254
294
|
return t.node(
|
|
255
295
|
l.Instruction,
|
|
256
296
|
'Property',
|
|
257
|
-
|
|
297
|
+
btree.from(t.ref`key`, t.ref`mapOperator`, t.embedded(buildSpace()), t.ref`value`),
|
|
258
298
|
{
|
|
259
299
|
key: buildIdentifier(key),
|
|
260
300
|
mapOperator: t.s_node(l.Instruction, 'Punctuator', ':'),
|
|
@@ -280,8 +320,15 @@ export const buildInteger = (value, base = 10) => {
|
|
|
280
320
|
return t.node(
|
|
281
321
|
l.CSTML,
|
|
282
322
|
'Integer',
|
|
283
|
-
|
|
284
|
-
|
|
323
|
+
btree.fromValues(
|
|
324
|
+
concat(
|
|
325
|
+
[t.ref`digits[]`, t.arr()],
|
|
326
|
+
digits.map(() => t.ref`digits[]`),
|
|
327
|
+
),
|
|
328
|
+
),
|
|
329
|
+
{
|
|
330
|
+
digits: digits.map((digit) => buildDigit(digit)),
|
|
331
|
+
},
|
|
285
332
|
);
|
|
286
333
|
};
|
|
287
334
|
|
|
@@ -309,24 +356,22 @@ export const buildNumber = (value) => {
|
|
|
309
356
|
}
|
|
310
357
|
};
|
|
311
358
|
|
|
312
|
-
const buildLiteralTerminal = (lit) => freeze({ type: 'Literal', value: lit });
|
|
313
|
-
|
|
314
359
|
export const buildString = (value) => {
|
|
315
360
|
const pieces = isArray(value) ? value : [value];
|
|
316
|
-
const
|
|
361
|
+
const tags = [];
|
|
317
362
|
let lit = '';
|
|
318
363
|
|
|
319
364
|
if (pieces.length === 1 && pieces[0] === "'") {
|
|
320
|
-
return t.node(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
365
|
+
return t.node(
|
|
366
|
+
l.CSTML,
|
|
367
|
+
'String',
|
|
368
|
+
btree.from(t.ref`openToken`, t.ref`content`, t.ref`closeToken`),
|
|
369
|
+
{
|
|
370
|
+
openToken: t.s_node(l.CSTML, 'Punctuator', '"'),
|
|
371
|
+
content: interpolateString(agastBuildLiteralTag(value)),
|
|
372
|
+
closeToken: t.s_node(l.CSTML, 'Punctuator', '"'),
|
|
373
|
+
},
|
|
374
|
+
);
|
|
330
375
|
}
|
|
331
376
|
|
|
332
377
|
for (const piece of pieces) {
|
|
@@ -344,7 +389,7 @@ export const buildString = (value) => {
|
|
|
344
389
|
chr.charCodeAt(0) < 32
|
|
345
390
|
) {
|
|
346
391
|
if (lit) {
|
|
347
|
-
|
|
392
|
+
tags.push(agastBuildLiteralTag(lit));
|
|
348
393
|
lit = '';
|
|
349
394
|
}
|
|
350
395
|
|
|
@@ -360,7 +405,12 @@ export const buildString = (value) => {
|
|
|
360
405
|
value = t.node(
|
|
361
406
|
l.CSTML,
|
|
362
407
|
'EscapeCode',
|
|
363
|
-
|
|
408
|
+
btree.fromValues(
|
|
409
|
+
concat(
|
|
410
|
+
[t.ref`sigilToken`, t.ref`digits[]`, t.arr()],
|
|
411
|
+
[...hexDigits].map((d) => t.ref`digits[]`),
|
|
412
|
+
),
|
|
413
|
+
),
|
|
364
414
|
{
|
|
365
415
|
sigilToken: buildKeyword('u'),
|
|
366
416
|
digits: [...hexDigits].map((digit) => buildDigit(digit)),
|
|
@@ -370,7 +420,7 @@ export const buildString = (value) => {
|
|
|
370
420
|
value = buildKeyword(chr);
|
|
371
421
|
}
|
|
372
422
|
|
|
373
|
-
|
|
423
|
+
tags.push(
|
|
374
424
|
t.buildEmbeddedNode(
|
|
375
425
|
t.e_node(
|
|
376
426
|
l.CSTML,
|
|
@@ -389,27 +439,32 @@ export const buildString = (value) => {
|
|
|
389
439
|
}
|
|
390
440
|
}
|
|
391
441
|
} else {
|
|
392
|
-
|
|
442
|
+
tags.push(agastBuildLiteralTag(lit));
|
|
393
443
|
lit = '';
|
|
394
444
|
|
|
395
445
|
if (piece == null) {
|
|
396
446
|
throw new Error('not implemented');
|
|
397
447
|
} else if (isString(piece.type)) {
|
|
398
|
-
|
|
448
|
+
tags.push(piece);
|
|
399
449
|
} else {
|
|
400
450
|
throw new Error();
|
|
401
451
|
}
|
|
402
452
|
}
|
|
403
453
|
}
|
|
404
454
|
|
|
405
|
-
if (lit)
|
|
455
|
+
if (lit) tags.push(agastBuildLiteralTag(lit));
|
|
406
456
|
lit = '';
|
|
407
457
|
|
|
408
|
-
return t.node(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
458
|
+
return t.node(
|
|
459
|
+
l.CSTML,
|
|
460
|
+
'String',
|
|
461
|
+
btree.from(t.ref`openToken`, t.ref`content`, t.ref`closeToken`),
|
|
462
|
+
{
|
|
463
|
+
openToken: t.s_node(l.CSTML, 'Punctuator', "'"),
|
|
464
|
+
content: interpolateString(tags),
|
|
465
|
+
closeToken: t.s_node(l.CSTML, 'Punctuator', "'"),
|
|
466
|
+
},
|
|
467
|
+
);
|
|
413
468
|
};
|
|
414
469
|
|
|
415
470
|
export const buildBoolean = (value) => {
|
|
@@ -418,80 +473,87 @@ export const buildBoolean = (value) => {
|
|
|
418
473
|
});
|
|
419
474
|
};
|
|
420
475
|
|
|
421
|
-
export const
|
|
476
|
+
export const buildNullTag = () => {
|
|
422
477
|
return t.node(l.Instruction, 'Null', [t.ref`sigilToken`], {
|
|
423
478
|
sigilToken: t.s_node(l.Instruction, 'Keyword', 'null'),
|
|
424
479
|
});
|
|
425
480
|
};
|
|
426
481
|
|
|
427
482
|
export const buildArray = (elements) => {
|
|
483
|
+
const elements_ = buildArrayElements(elements);
|
|
428
484
|
return t.node(
|
|
429
485
|
l.Instruction,
|
|
430
486
|
'Array',
|
|
431
|
-
|
|
432
|
-
t.ref`openToken
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
t.embedded(
|
|
437
|
-
t.t_node(l.Comment, null, [t.embedded(t.t_node('Space', 'Space', [t.lit(' ')]))]),
|
|
438
|
-
),
|
|
439
|
-
),
|
|
440
|
-
t.ref`closeToken`,
|
|
441
|
-
],
|
|
487
|
+
btree.fromValues(
|
|
488
|
+
concat([t.ref`openToken`], interpolateFragmentChildren(elements_, t.ref`elements[]`), [
|
|
489
|
+
t.ref`closeToken`,
|
|
490
|
+
]),
|
|
491
|
+
),
|
|
442
492
|
{
|
|
443
493
|
openToken: t.s_node(l.Instruction, 'Punctuator', '['),
|
|
444
|
-
elements: [
|
|
494
|
+
elements: elements_.properties['.'],
|
|
445
495
|
closeToken: t.s_node(l.Instruction, 'Punctuator', ']'),
|
|
446
496
|
},
|
|
447
497
|
);
|
|
448
498
|
};
|
|
449
499
|
|
|
500
|
+
export const buildArrayElements = (values) => {
|
|
501
|
+
return buildSpaceSeparatedList(values.map((value) => buildExpression(value)));
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
export const buildTupleValues = buildArrayElements;
|
|
505
|
+
|
|
450
506
|
export const buildTuple = (values) => {
|
|
507
|
+
const values_ = buildTupleValues(values);
|
|
451
508
|
return t.node(
|
|
452
509
|
l.Instruction,
|
|
453
510
|
'Tuple',
|
|
454
|
-
|
|
455
|
-
t.ref`openToken
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
t.embedded(
|
|
460
|
-
t.t_node(l.Comment, null, [t.embedded(t.t_node('Space', 'Space', [t.lit(' ')]))]),
|
|
461
|
-
),
|
|
462
|
-
),
|
|
463
|
-
t.ref`closeToken`,
|
|
464
|
-
],
|
|
511
|
+
btree.fromValues(
|
|
512
|
+
concat([t.ref`openToken`], interpolateFragmentChildren(values_, t.ref`values[]`), [
|
|
513
|
+
t.ref`closeToken`,
|
|
514
|
+
]),
|
|
515
|
+
),
|
|
465
516
|
{
|
|
466
517
|
openToken: t.s_node(l.Instruction, 'Punctuator', '('),
|
|
467
|
-
values: [
|
|
518
|
+
values: values_.properties['.'],
|
|
468
519
|
closeToken: t.s_node(l.Instruction, 'Punctuator', ')'),
|
|
469
520
|
},
|
|
470
521
|
);
|
|
471
522
|
};
|
|
472
523
|
|
|
524
|
+
export const buildSpaceSeparatedList = (values) => {
|
|
525
|
+
return t.frag(
|
|
526
|
+
btree.fromValues(
|
|
527
|
+
concat(
|
|
528
|
+
[t.ref`.`, t.arr()],
|
|
529
|
+
buildSeparatedListChildren(values, t.ref`.`, t.embedded(buildSpace())),
|
|
530
|
+
),
|
|
531
|
+
),
|
|
532
|
+
{
|
|
533
|
+
['.']: values,
|
|
534
|
+
},
|
|
535
|
+
);
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
export const buildObjectProperties = (properties) => {
|
|
539
|
+
return buildSpaceSeparatedList(
|
|
540
|
+
Object.entries(properties).map(({ 0: key, 1: value }) => buildProperty(key, value)),
|
|
541
|
+
);
|
|
542
|
+
};
|
|
543
|
+
|
|
473
544
|
export const buildObject = (properties) => {
|
|
545
|
+
const properties_ = buildObjectProperties(properties);
|
|
474
546
|
return t.node(
|
|
475
547
|
l.Instruction,
|
|
476
548
|
'Object',
|
|
477
|
-
|
|
478
|
-
t.ref`openToken
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
t.embedded(
|
|
483
|
-
t.t_node(l.Comment, null, [t.embedded(t.t_node('Space', 'Space', [t.lit(' ')]))]),
|
|
484
|
-
),
|
|
485
|
-
),
|
|
486
|
-
t.ref`closeToken`,
|
|
487
|
-
],
|
|
549
|
+
btree.fromValues(
|
|
550
|
+
concat([t.ref`openToken`], interpolateFragmentChildren(properties_, t.ref`properties[]`), [
|
|
551
|
+
t.ref`closeToken`,
|
|
552
|
+
]),
|
|
553
|
+
),
|
|
488
554
|
{
|
|
489
555
|
openToken: t.s_node(l.Instruction, 'Punctuator', '{'),
|
|
490
|
-
properties: [
|
|
491
|
-
...interpolateArray(
|
|
492
|
-
Object.entries(properties).map(([key, value]) => buildProperty(key, value)),
|
|
493
|
-
),
|
|
494
|
-
],
|
|
556
|
+
properties: properties_.properties['.'],
|
|
495
557
|
closeToken: t.s_node(l.Instruction, 'Punctuator', '}'),
|
|
496
558
|
},
|
|
497
559
|
{},
|
|
@@ -499,11 +561,16 @@ export const buildObject = (properties) => {
|
|
|
499
561
|
};
|
|
500
562
|
|
|
501
563
|
export const buildMappingAttribute = (key, value) => {
|
|
502
|
-
return t.node(
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
564
|
+
return t.node(
|
|
565
|
+
l.CSTML,
|
|
566
|
+
'MappingAttribute',
|
|
567
|
+
btree.from(t.ref`key`, t.ref`mapOperator`, t.ref`value`),
|
|
568
|
+
{
|
|
569
|
+
key: buildIdentifier(key),
|
|
570
|
+
mapOperator: t.s_node(l.CSTML, 'Punctuator', '='),
|
|
571
|
+
value: buildExpression(value),
|
|
572
|
+
},
|
|
573
|
+
);
|
|
507
574
|
};
|
|
508
575
|
|
|
509
576
|
export const buildBooleanAttribute = (key, value) => {
|
|
@@ -517,8 +584,44 @@ export const buildAttribute = (key, value) => {
|
|
|
517
584
|
return isBoolean(value) ? buildBooleanAttribute(key, value) : buildMappingAttribute(key, value);
|
|
518
585
|
};
|
|
519
586
|
|
|
587
|
+
export const buildPattern = (alternatives, flags) => {
|
|
588
|
+
return t.node(
|
|
589
|
+
l.Regex,
|
|
590
|
+
'Pattern',
|
|
591
|
+
btree.fromValues(
|
|
592
|
+
concat(
|
|
593
|
+
[t.ref`openToken`],
|
|
594
|
+
buildSeparatedListChildren(alternatives, t.ref`alternatives[]`, t.ref`separators[]`),
|
|
595
|
+
[t.ref`closeToken`, t.ref`flags`],
|
|
596
|
+
),
|
|
597
|
+
),
|
|
598
|
+
{
|
|
599
|
+
openToken: t.s_node(l.Regex, 'Punctuator', '/'),
|
|
600
|
+
alternatives,
|
|
601
|
+
separators: alternatives.slice(0, -1).map((alt) => t.s_node(l.Regex, 'Punctuator', '|')),
|
|
602
|
+
closeToken: t.s_node(l.Regex, 'Punctuator', '/'),
|
|
603
|
+
flags: buildFlags(flags),
|
|
604
|
+
},
|
|
605
|
+
);
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
export const buildAlternative = (elements) => {
|
|
609
|
+
return t.node(
|
|
610
|
+
l.Regex,
|
|
611
|
+
'Pattern',
|
|
612
|
+
btree.fromValues(
|
|
613
|
+
concat([t.ref`openToken`], buildSeparatedListChildren(elements, t.ref`elements[]`), [
|
|
614
|
+
t.ref`closeToken`,
|
|
615
|
+
]),
|
|
616
|
+
),
|
|
617
|
+
{
|
|
618
|
+
elements,
|
|
619
|
+
},
|
|
620
|
+
);
|
|
621
|
+
};
|
|
622
|
+
|
|
520
623
|
export const buildExpression = (expr) => {
|
|
521
|
-
if (isNull(expr)) return
|
|
624
|
+
if (isNull(expr)) return buildNullTag();
|
|
522
625
|
|
|
523
626
|
switch (typeof expr) {
|
|
524
627
|
case 'boolean':
|
|
@@ -546,12 +649,22 @@ export const buildExpression = (expr) => {
|
|
|
546
649
|
};
|
|
547
650
|
|
|
548
651
|
export const buildAttributes = (attributes = {}) => {
|
|
549
|
-
|
|
550
|
-
|
|
652
|
+
const attributes_ = Object.entries(attributes).map(({ 0: key, 1: value }) =>
|
|
653
|
+
buildAttribute(key, value),
|
|
654
|
+
);
|
|
551
655
|
|
|
552
|
-
|
|
553
|
-
|
|
656
|
+
return t.frag(
|
|
657
|
+
btree.fromValues(
|
|
658
|
+
[t.ref`.[]`, t.arr()],
|
|
659
|
+
buildSeparatedListChildren(attributes_, t.ref`.[]`, t.embedded(buildSpace())),
|
|
660
|
+
),
|
|
661
|
+
{
|
|
662
|
+
['.']: attributes_,
|
|
663
|
+
},
|
|
664
|
+
);
|
|
665
|
+
};
|
|
554
666
|
|
|
667
|
+
export const buildNodeMatcher = (flags, language, type, attributes) => {
|
|
555
668
|
let language_ = !language || language.length === 0 ? null : language;
|
|
556
669
|
|
|
557
670
|
const flags_ = buildFlags(flags);
|
|
@@ -559,22 +672,24 @@ export const buildNodeMatcher = (flags, language, type, attributes = {}) => {
|
|
|
559
672
|
return t.node(
|
|
560
673
|
l.Spamex,
|
|
561
674
|
'NodeMatcher',
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
675
|
+
btree.fromValues(
|
|
676
|
+
concat(
|
|
677
|
+
[t.ref`openToken`],
|
|
678
|
+
when(flags_, [t.ref`flags`]),
|
|
679
|
+
when(language_, [t.ref`language`, t.ref`languageSeparator`]),
|
|
680
|
+
[t.ref`type`],
|
|
681
|
+
when(attributes.length, [t.embedded(buildSpace())]),
|
|
682
|
+
[...btree.traverse(attributes.children)].slice(1, -1),
|
|
683
|
+
[t.ref`closeToken`],
|
|
684
|
+
),
|
|
685
|
+
),
|
|
571
686
|
{
|
|
572
687
|
openToken: t.s_node(l.CSTML, 'Punctuator', '<'),
|
|
573
688
|
language: buildLanguage(language_),
|
|
574
689
|
languageSeparator: language_ && type ? t.s_node(l.CSTML, 'Punctuator', ':') : t.null_node(),
|
|
575
690
|
flags: flags_,
|
|
576
691
|
type: buildIdentifier(type),
|
|
577
|
-
attributes:
|
|
692
|
+
attributes: attributes.properties.attributes,
|
|
578
693
|
closeToken: t.s_node(l.CSTML, 'Punctuator', '>'),
|
|
579
694
|
},
|
|
580
695
|
);
|
package/lib/deembed.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { EmbeddedExpression } from '@bablr/agast-helpers/symbols';
|
|
2
|
+
|
|
1
3
|
const { isArray } = Array;
|
|
2
4
|
const isString = (val) => typeof val === 'string';
|
|
3
5
|
const isNumber = (val) => typeof val === 'number';
|
|
@@ -18,6 +20,6 @@ export const deembedExpression = (expr) => {
|
|
|
18
20
|
|
|
19
21
|
export const getEmbeddedExpression = (expr) => {
|
|
20
22
|
if (!expr) return expr;
|
|
21
|
-
if (expr.type !==
|
|
23
|
+
if (expr.type !== EmbeddedExpression) throw new Error();
|
|
22
24
|
return expr.value;
|
|
23
25
|
};
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
import { getCooked, isNull } from '@bablr/agast-helpers/tree';
|
|
1
|
+
import { sourceTextFor, getCooked, isNull, nodeFlags } from '@bablr/agast-helpers/tree';
|
|
2
|
+
import * as btree from '@bablr/agast-helpers/btree';
|
|
2
3
|
import * as sym from '@bablr/agast-helpers/symbols';
|
|
4
|
+
import { buildNodeCloseTag, buildLiteralTag, buildDoctypeTag } from '@bablr/agast-helpers/builders';
|
|
5
|
+
import {
|
|
6
|
+
DoctypeTag,
|
|
7
|
+
OpenNodeTag,
|
|
8
|
+
CloseNodeTag,
|
|
9
|
+
ReferenceTag,
|
|
10
|
+
ShiftTag,
|
|
11
|
+
GapTag,
|
|
12
|
+
NullTag,
|
|
13
|
+
ArrayTag,
|
|
14
|
+
LiteralTag,
|
|
15
|
+
} from '@bablr/agast-helpers/symbols';
|
|
3
16
|
|
|
4
17
|
export * from './builders.js';
|
|
5
18
|
|
|
@@ -29,14 +42,14 @@ export const shouldBranch = (effects) => {
|
|
|
29
42
|
};
|
|
30
43
|
|
|
31
44
|
const reifyFlags = (flags) => {
|
|
32
|
-
let { triviaToken, escapeToken, tokenToken, expressionToken,
|
|
45
|
+
let { triviaToken, escapeToken, tokenToken, expressionToken, hasGapToken } = flags.properties;
|
|
33
46
|
|
|
34
47
|
return {
|
|
35
|
-
token: reifyExpression(tokenToken),
|
|
36
|
-
escape: reifyExpression(escapeToken),
|
|
37
|
-
trivia: reifyExpression(triviaToken),
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
token: !!reifyExpression(tokenToken),
|
|
49
|
+
escape: !!reifyExpression(escapeToken),
|
|
50
|
+
trivia: !!reifyExpression(triviaToken),
|
|
51
|
+
expression: !!reifyExpression(expressionToken),
|
|
52
|
+
hasGap: !!reifyExpression(hasGapToken),
|
|
40
53
|
};
|
|
41
54
|
};
|
|
42
55
|
|
|
@@ -46,39 +59,149 @@ export const reifyLanguage = (language) => {
|
|
|
46
59
|
return typeof value === 'string' && !value.startsWith('https://') ? [value] : value;
|
|
47
60
|
};
|
|
48
61
|
|
|
62
|
+
export const reifyProperties = (properties = []) => {
|
|
63
|
+
const built = {};
|
|
64
|
+
for (const property of btree.traverse(properties)) {
|
|
65
|
+
switch (property.type) {
|
|
66
|
+
case 'Property': {
|
|
67
|
+
let { reference, value } = property.properties;
|
|
68
|
+
|
|
69
|
+
reference = reifyExpression(reference);
|
|
70
|
+
value = reifyExpression(value);
|
|
71
|
+
|
|
72
|
+
if (reference.value.isArray) {
|
|
73
|
+
built[reference.value.name] ||= [];
|
|
74
|
+
built[reference.value.name].push(value);
|
|
75
|
+
} else {
|
|
76
|
+
built[reference.value.name] = value;
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
default:
|
|
81
|
+
throw new Error();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return built;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const buildChildren = (node) => {
|
|
88
|
+
let { open, children = [], close } = node.properties;
|
|
89
|
+
|
|
90
|
+
const selfClosing = !!open.properties.selfClosingTagToken;
|
|
91
|
+
const { intrinsicValue } = open.properties;
|
|
92
|
+
let built = [];
|
|
93
|
+
|
|
94
|
+
open = reifyExpression(open);
|
|
95
|
+
close = reifyExpression(close);
|
|
96
|
+
|
|
97
|
+
if (selfClosing) {
|
|
98
|
+
built = btree.push(built, open);
|
|
99
|
+
if (intrinsicValue) {
|
|
100
|
+
built = btree.push(built, buildLiteralTag(intrinsicValue));
|
|
101
|
+
}
|
|
102
|
+
built = btree.push(built, buildNodeCloseTag());
|
|
103
|
+
} else {
|
|
104
|
+
built = btree.push(built, open);
|
|
105
|
+
for (const child of btree.traverse(children)) {
|
|
106
|
+
if (child.type !== 'Property') throw new Error('umimplemented');
|
|
107
|
+
|
|
108
|
+
let { reference } = child.properties;
|
|
109
|
+
|
|
110
|
+
reference = reifyExpression(reference);
|
|
111
|
+
|
|
112
|
+
built = btree.push(built, reference);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
built = btree.push(built, close);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return built;
|
|
119
|
+
};
|
|
120
|
+
|
|
49
121
|
export const reifyExpression = (node) => {
|
|
50
122
|
if (node instanceof Promise) throw new Error();
|
|
51
123
|
|
|
52
124
|
if (!node || node.type === sym.null) return null;
|
|
53
125
|
|
|
126
|
+
if (!node.type) {
|
|
127
|
+
node = node.properties['.'];
|
|
128
|
+
}
|
|
129
|
+
|
|
54
130
|
if (node.language === 'https://bablr.org/languages/core/en/cstml') {
|
|
55
|
-
switch (node.type) {
|
|
131
|
+
switch (node.type?.description || node.type) {
|
|
132
|
+
case 'Document': {
|
|
133
|
+
let { doctype, tree } = node.properties;
|
|
134
|
+
|
|
135
|
+
doctype = reifyExpression(doctype);
|
|
136
|
+
tree = reifyExpression(tree);
|
|
137
|
+
|
|
138
|
+
let { attributes } = doctype.value;
|
|
139
|
+
let { properties } = tree;
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
flags: nodeFlags,
|
|
143
|
+
language: attributes['bablr-language'],
|
|
144
|
+
type: null,
|
|
145
|
+
children: btree.addAt(
|
|
146
|
+
0,
|
|
147
|
+
buildChildren(node.properties.tree),
|
|
148
|
+
buildDoctypeTag(attributes),
|
|
149
|
+
),
|
|
150
|
+
properties,
|
|
151
|
+
attributes,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
case 'Node': {
|
|
156
|
+
let { open, children } = node.properties;
|
|
157
|
+
|
|
158
|
+
open = reifyExpression(open);
|
|
159
|
+
|
|
160
|
+
let { flags, language, type, attributes } = open.value;
|
|
161
|
+
|
|
162
|
+
const properties = reifyProperties(children);
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
flags,
|
|
166
|
+
language,
|
|
167
|
+
type,
|
|
168
|
+
children: buildChildren(node),
|
|
169
|
+
properties,
|
|
170
|
+
attributes,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
56
174
|
case 'DoctypeTag': {
|
|
57
175
|
let { doctype, version, attributes } = node.properties;
|
|
58
176
|
return {
|
|
59
|
-
type:
|
|
177
|
+
type: DoctypeTag,
|
|
60
178
|
value: {
|
|
61
179
|
doctype: getCooked(doctype),
|
|
62
|
-
version: parseInt(
|
|
180
|
+
version: parseInt(sourceTextFor(version), 10),
|
|
63
181
|
attributes: reifyAttributes(attributes),
|
|
64
182
|
},
|
|
65
183
|
};
|
|
66
184
|
}
|
|
67
185
|
|
|
68
|
-
case '
|
|
69
|
-
let { name, arrayOperatorToken } = node.properties;
|
|
186
|
+
case 'ReferenceTag': {
|
|
187
|
+
let { name, arrayOperatorToken, hasGapToken } = node.properties;
|
|
70
188
|
|
|
71
189
|
name = reifyExpression(name);
|
|
72
190
|
|
|
73
|
-
return {
|
|
191
|
+
return {
|
|
192
|
+
type: ReferenceTag,
|
|
193
|
+
value: { name, isArray: !isNull(arrayOperatorToken), hasGap: !isNull(hasGapToken) },
|
|
194
|
+
};
|
|
74
195
|
}
|
|
75
196
|
|
|
76
|
-
case '
|
|
197
|
+
case 'LiteralTag': {
|
|
77
198
|
let { value } = node.properties;
|
|
78
199
|
|
|
79
|
-
return { type:
|
|
200
|
+
return { type: LiteralTag, value: getCooked(value.properties.content) };
|
|
201
|
+
}
|
|
202
|
+
case 'Identifier': {
|
|
203
|
+
return getCooked(node);
|
|
80
204
|
}
|
|
81
|
-
|
|
82
205
|
case 'IdentifierPath': {
|
|
83
206
|
return node.properties.segments.map((segment) => reifyExpression(segment));
|
|
84
207
|
}
|
|
@@ -92,7 +215,7 @@ export const reifyExpression = (node) => {
|
|
|
92
215
|
attributes = reifyAttributes(attributes);
|
|
93
216
|
|
|
94
217
|
return {
|
|
95
|
-
type:
|
|
218
|
+
type: OpenNodeTag,
|
|
96
219
|
value: { flags, language, type, attributes },
|
|
97
220
|
};
|
|
98
221
|
}
|
|
@@ -103,7 +226,7 @@ export const reifyExpression = (node) => {
|
|
|
103
226
|
language = reifyLanguage(language);
|
|
104
227
|
type = reifyExpression(type);
|
|
105
228
|
|
|
106
|
-
return { type:
|
|
229
|
+
return { type: CloseNodeTag, value: { language, type } };
|
|
107
230
|
}
|
|
108
231
|
|
|
109
232
|
case 'Integer': {
|
|
@@ -122,11 +245,17 @@ export const reifyExpression = (node) => {
|
|
|
122
245
|
case 'String':
|
|
123
246
|
return node.properties.content ? getCooked(node.properties.content) : '';
|
|
124
247
|
|
|
125
|
-
case '
|
|
126
|
-
return { type:
|
|
248
|
+
case 'GapTag':
|
|
249
|
+
return { type: GapTag, value: undefined };
|
|
250
|
+
|
|
251
|
+
case 'ArrayTag':
|
|
252
|
+
return { type: ArrayTag, value: undefined };
|
|
253
|
+
|
|
254
|
+
case 'NullTag':
|
|
255
|
+
return { type: NullTag, value: undefined };
|
|
127
256
|
|
|
128
|
-
case '
|
|
129
|
-
return { type:
|
|
257
|
+
case 'ShiftTag':
|
|
258
|
+
return { type: ShiftTag, value: undefined };
|
|
130
259
|
|
|
131
260
|
default:
|
|
132
261
|
throw new Error();
|
|
@@ -145,7 +274,7 @@ export const reifyExpression = (node) => {
|
|
|
145
274
|
|
|
146
275
|
switch (node.type) {
|
|
147
276
|
case 'NodeMatcher':
|
|
148
|
-
let { flags, language, type, attributes, intrinsicValue } = node.properties;
|
|
277
|
+
let { flags, language, type, attributes, intrinsicValue } = node.properties.open.properties;
|
|
149
278
|
|
|
150
279
|
flags = reifyFlags(flags);
|
|
151
280
|
language = reifyLanguage(language);
|
|
@@ -164,7 +293,7 @@ export const reifyExpression = (node) => {
|
|
|
164
293
|
const { properties } = node.properties;
|
|
165
294
|
|
|
166
295
|
return Object.fromEntries(
|
|
167
|
-
properties.map(({ properties: { key, value } }) => [
|
|
296
|
+
[...btree.traverse(properties)].map(({ properties: { key, value } }) => [
|
|
168
297
|
getCooked(key),
|
|
169
298
|
reifyExpression(value),
|
|
170
299
|
]),
|
|
@@ -174,16 +303,16 @@ export const reifyExpression = (node) => {
|
|
|
174
303
|
case 'Tuple': {
|
|
175
304
|
const { values = [] } = node.properties;
|
|
176
305
|
|
|
177
|
-
return [...values.map((el) => reifyExpression(el))
|
|
306
|
+
return [...btree.traverse(values)].map((el) => reifyExpression(el));
|
|
178
307
|
}
|
|
179
308
|
|
|
180
309
|
case 'Array': {
|
|
181
|
-
const { elements } = node.properties;
|
|
310
|
+
const { elements = [] } = node.properties;
|
|
182
311
|
|
|
183
|
-
return [...elements.map((el) => reifyExpression(el))
|
|
312
|
+
return [...btree.traverse(elements)].map((el) => reifyExpression(el));
|
|
184
313
|
}
|
|
185
314
|
|
|
186
|
-
case '
|
|
315
|
+
case 'LiteralTag':
|
|
187
316
|
case 'Identifier':
|
|
188
317
|
return getCooked(node);
|
|
189
318
|
|
|
@@ -221,15 +350,18 @@ export const reifyExpressionShallow = (node) => {
|
|
|
221
350
|
const { properties } = node.properties;
|
|
222
351
|
|
|
223
352
|
return Object.fromEntries(
|
|
224
|
-
properties.map(({ properties: { key, value } }) => [
|
|
353
|
+
[...btree.traverse(properties)].map(({ properties: { key, value } }) => [
|
|
354
|
+
getCooked(key),
|
|
355
|
+
value,
|
|
356
|
+
]),
|
|
225
357
|
);
|
|
226
358
|
}
|
|
227
359
|
|
|
228
360
|
case 'Array':
|
|
229
|
-
return [...node.properties.elements];
|
|
361
|
+
return [...btree.traverse(node.properties.elements)];
|
|
230
362
|
|
|
231
363
|
case 'Tuple':
|
|
232
|
-
return [...node.properties.values];
|
|
364
|
+
return [...btree.traverse(node.properties.values)];
|
|
233
365
|
|
|
234
366
|
default:
|
|
235
367
|
return reifyExpression(node);
|
|
@@ -240,7 +372,7 @@ export const reifyAttributes = (attributes) => {
|
|
|
240
372
|
if (attributes == null) return {};
|
|
241
373
|
|
|
242
374
|
return Object.fromEntries(
|
|
243
|
-
attributes.map((attr) => {
|
|
375
|
+
[...btree.traverse(attributes)].map((attr) => {
|
|
244
376
|
if (attr.type === 'MappingAttribute') {
|
|
245
377
|
return [reifyExpression(attr.properties.key), reifyExpression(attr.properties.value)];
|
|
246
378
|
} else if (attr.type === 'BooleanAttribute') {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/agast-vm-helpers",
|
|
3
3
|
"description": "Helper functions for working with the BABLR VM",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"author": "Conrad Buck<conartist6@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@bablr/agast-helpers": "0.
|
|
21
|
+
"@bablr/agast-helpers": "^0.5.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#49f5952efed27f94ee9b94340eb1563c440bf64e",
|