@bablr/boot 0.5.0 → 0.6.1
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 +28 -0
- package/lib/index.js +26 -8
- package/lib/languages/cstml.js +67 -15
- package/lib/languages/regex.js +1 -1
- package/lib/languages/spamex.js +12 -10
- package/lib/miniparser.js +13 -2
- package/lib/print.js +0 -6
- package/package.json +2 -2
- package/shorthand.macro.js +7 -16
package/lib/builders.js
CHANGED
|
@@ -2,8 +2,11 @@ const sym = require('@bablr/boot-helpers/symbols');
|
|
|
2
2
|
const { freeze, getPrototypeOf } = Object;
|
|
3
3
|
const { isArray } = Array;
|
|
4
4
|
const {
|
|
5
|
+
DoctypeTag,
|
|
5
6
|
OpenNodeTag,
|
|
6
7
|
CloseNodeTag,
|
|
8
|
+
OpenFragmentTag,
|
|
9
|
+
CloseFragmentTag,
|
|
7
10
|
ReferenceTag,
|
|
8
11
|
GapTag,
|
|
9
12
|
LiteralTag,
|
|
@@ -66,6 +69,13 @@ const interpolateString = (value) => {
|
|
|
66
69
|
return buildNode('String', 'Content', children);
|
|
67
70
|
};
|
|
68
71
|
|
|
72
|
+
const buildDoctypeTag = (attributes) => {
|
|
73
|
+
return freeze({
|
|
74
|
+
type: DoctypeTag,
|
|
75
|
+
value: freeze({ doctype: 'cstml', version: 0, attributes }),
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
69
79
|
const buildReferenceTag = (name, isArray) => {
|
|
70
80
|
return freeze({ type: ReferenceTag, value: freeze({ name, isArray }) });
|
|
71
81
|
};
|
|
@@ -82,6 +92,19 @@ const buildNodeCloseTag = (type) => {
|
|
|
82
92
|
return freeze({ type: CloseNodeTag, value: freeze({ type }) });
|
|
83
93
|
};
|
|
84
94
|
|
|
95
|
+
const buildFragmentOpenTag = (flags = {}) => {
|
|
96
|
+
return freeze({
|
|
97
|
+
type: OpenFragmentTag,
|
|
98
|
+
value: freeze({
|
|
99
|
+
flags: freeze(flags),
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const buildFragmentCloseTag = (type = null, language = null) => {
|
|
105
|
+
return freeze({ type: CloseFragmentTag, value: freeze({ language, type }) });
|
|
106
|
+
};
|
|
107
|
+
|
|
85
108
|
const buildLiteralTag = (value) => {
|
|
86
109
|
return freeze({ type: LiteralTag, value });
|
|
87
110
|
};
|
|
@@ -421,10 +444,13 @@ module.exports = {
|
|
|
421
444
|
buildSpace,
|
|
422
445
|
buildIdentifier,
|
|
423
446
|
buildAttribute,
|
|
447
|
+
buildDoctypeTag,
|
|
424
448
|
buildReferenceTag,
|
|
425
449
|
buildGapTag,
|
|
426
450
|
buildNodeOpenTag,
|
|
427
451
|
buildNodeCloseTag,
|
|
452
|
+
buildFragmentOpenTag,
|
|
453
|
+
buildFragmentCloseTag,
|
|
428
454
|
buildLiteralTag,
|
|
429
455
|
buildNode,
|
|
430
456
|
buildSyntacticNode,
|
|
@@ -432,6 +458,8 @@ module.exports = {
|
|
|
432
458
|
buildSyntacticEscapeNode,
|
|
433
459
|
buildTriviaNode,
|
|
434
460
|
buildGapNode,
|
|
461
|
+
nodeFlags,
|
|
462
|
+
|
|
435
463
|
ref,
|
|
436
464
|
lit,
|
|
437
465
|
gap,
|
package/lib/index.js
CHANGED
|
@@ -5,11 +5,16 @@ const regex = require('./languages/regex.js');
|
|
|
5
5
|
const instruction = require('./languages/instruction.js');
|
|
6
6
|
const {
|
|
7
7
|
buildLiteralTag,
|
|
8
|
+
buildDoctypeTag,
|
|
8
9
|
buildNodeOpenTag,
|
|
9
10
|
buildNodeCloseTag,
|
|
11
|
+
buildFragmentOpenTag,
|
|
12
|
+
buildFragmentCloseTag,
|
|
10
13
|
buildTriviaNode,
|
|
11
14
|
buildGapNode,
|
|
12
15
|
buildSyntacticEscapeNode,
|
|
16
|
+
nodeFlags,
|
|
17
|
+
buildReferenceTag,
|
|
13
18
|
} = require('./builders.js');
|
|
14
19
|
const { TemplateParser } = require('./miniparser.js');
|
|
15
20
|
const { Resolver } = require('./print.js');
|
|
@@ -62,7 +67,7 @@ const add = (obj, path, value) => {
|
|
|
62
67
|
|
|
63
68
|
const buildTag = (language, defaultType) => {
|
|
64
69
|
const defaultTag = (quasis, ...exprs) => {
|
|
65
|
-
return
|
|
70
|
+
return getAgASTTree(
|
|
66
71
|
language,
|
|
67
72
|
new TemplateParser(language, quasis.raw, exprs).eval({
|
|
68
73
|
language: language.name,
|
|
@@ -78,7 +83,7 @@ const buildTag = (language, defaultType) => {
|
|
|
78
83
|
|
|
79
84
|
get(_, type) {
|
|
80
85
|
return (quasis, ...exprs) => {
|
|
81
|
-
return
|
|
86
|
+
return getAgASTTree(
|
|
82
87
|
language,
|
|
83
88
|
new TemplateParser(language, quasis.raw, exprs).eval({
|
|
84
89
|
language: language.name,
|
|
@@ -97,6 +102,23 @@ const parse = (language, type, sourceText) => {
|
|
|
97
102
|
});
|
|
98
103
|
};
|
|
99
104
|
|
|
105
|
+
const getAgASTTree = (language, miniNode) => {
|
|
106
|
+
const attributes = { 'bablr-language': language.canonicalURL };
|
|
107
|
+
return {
|
|
108
|
+
flags: nodeFlags,
|
|
109
|
+
language: language.canonicalURL,
|
|
110
|
+
type: null,
|
|
111
|
+
children: [
|
|
112
|
+
buildDoctypeTag(attributes),
|
|
113
|
+
buildFragmentOpenTag(nodeFlags, null, null, null),
|
|
114
|
+
buildReferenceTag('.'),
|
|
115
|
+
buildFragmentCloseTag(),
|
|
116
|
+
],
|
|
117
|
+
properties: { ['.']: getAgASTValue(language, miniNode) },
|
|
118
|
+
attributes,
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
|
|
100
122
|
const getAgASTValue = (language, miniNode) => {
|
|
101
123
|
if (!miniNode) return miniNode;
|
|
102
124
|
|
|
@@ -109,7 +131,7 @@ const getAgASTValue = (language, miniNode) => {
|
|
|
109
131
|
escape: !!miniNode.flags?.escape,
|
|
110
132
|
trivia: !!miniNode.flags?.trivia,
|
|
111
133
|
token: false,
|
|
112
|
-
|
|
134
|
+
hasGap: false,
|
|
113
135
|
};
|
|
114
136
|
const properties = {};
|
|
115
137
|
let children = [];
|
|
@@ -136,10 +158,6 @@ const getAgASTValue = (language, miniNode) => {
|
|
|
136
158
|
flags.token = true;
|
|
137
159
|
}
|
|
138
160
|
|
|
139
|
-
if (type === 'Punctuator' || type === 'Keyword') {
|
|
140
|
-
flags.intrinsic = true;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
161
|
children = btree.push(
|
|
144
162
|
children,
|
|
145
163
|
buildNodeOpenTag(flags, resolvedLanguage.canonicalURL, type, attributes),
|
|
@@ -202,7 +220,7 @@ const getAgASTValue = (language, miniNode) => {
|
|
|
202
220
|
const str = buildTag(cstml, 'String');
|
|
203
221
|
const num = buildTag(cstml, 'Integer');
|
|
204
222
|
const cst = buildTag(cstml, 'Node');
|
|
205
|
-
const spam = buildTag(spamex, '
|
|
223
|
+
const spam = buildTag(spamex, 'Matcher');
|
|
206
224
|
const re = buildTag(regex, 'Pattern');
|
|
207
225
|
const i = buildTag(instruction, 'Call');
|
|
208
226
|
|
package/lib/languages/cstml.js
CHANGED
|
@@ -7,7 +7,6 @@ const _ = /\s+/y;
|
|
|
7
7
|
const PN = 'Punctuator';
|
|
8
8
|
const ID = 'Identifier';
|
|
9
9
|
const KW = 'Keyword';
|
|
10
|
-
const LIT = 'Literal';
|
|
11
10
|
|
|
12
11
|
const name = 'CSTML';
|
|
13
12
|
|
|
@@ -67,9 +66,12 @@ const covers = buildCovers({
|
|
|
67
66
|
'NullTag',
|
|
68
67
|
'GapTag',
|
|
69
68
|
'Node',
|
|
69
|
+
'Fragment',
|
|
70
70
|
'IdentifierPath',
|
|
71
71
|
'OpenNodeTag',
|
|
72
72
|
'CloseNodeTag',
|
|
73
|
+
'OpenFragmentTag',
|
|
74
|
+
'CloseFragmentTag',
|
|
73
75
|
'Tag',
|
|
74
76
|
'Number',
|
|
75
77
|
'Digit',
|
|
@@ -93,7 +95,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
93
95
|
Document(p) {
|
|
94
96
|
p.eatProduction('DoctypeTag', { path: 'doctype' });
|
|
95
97
|
p.eatMatchTrivia(_);
|
|
96
|
-
p.eatProduction('
|
|
98
|
+
p.eatProduction('Fragment', { path: 'tree' });
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
// @Node
|
|
@@ -105,7 +107,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
105
107
|
|
|
106
108
|
let sp = p.eatMatchTrivia(_);
|
|
107
109
|
|
|
108
|
-
if ((sp && p.match(
|
|
110
|
+
if ((sp && p.match(/!?[a-zA-Z]/y)) || p.atExpression) {
|
|
109
111
|
p.eatProduction('Attributes');
|
|
110
112
|
sp = p.eatMatchTrivia(_);
|
|
111
113
|
}
|
|
@@ -156,7 +158,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
156
158
|
} else {
|
|
157
159
|
if (p.match(/<\*?#/y)) {
|
|
158
160
|
p.eatProduction('Node');
|
|
159
|
-
} else if (p.match(/[a-zA-Z]
|
|
161
|
+
} else if (p.match(/[a-zA-Z]|\./y)) {
|
|
160
162
|
p.eatProduction('Property');
|
|
161
163
|
} else if (p.match(/['"]/y)) {
|
|
162
164
|
p.eatProduction('LiteralTag');
|
|
@@ -164,6 +166,25 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
168
|
|
|
169
|
+
// @Node
|
|
170
|
+
Fragment(p) {
|
|
171
|
+
let open = p.eatProduction('OpenFragmentTag', { path: 'open' });
|
|
172
|
+
|
|
173
|
+
p.eatMatchTrivia(_);
|
|
174
|
+
|
|
175
|
+
if (open.properties.flags?.token) {
|
|
176
|
+
p.eatProduction('NodeChild', { path: 'children[]' }, { token: true });
|
|
177
|
+
p.eatMatchTrivia(_);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
while (!(p.match('</') || p.done)) {
|
|
181
|
+
p.eatProduction('NodeChild', { path: 'children[]' });
|
|
182
|
+
p.eatMatchTrivia(_);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
p.eatProduction('CloseFragmentTag', { path: 'close' });
|
|
186
|
+
}
|
|
187
|
+
|
|
167
188
|
// @Node
|
|
168
189
|
Property(p) {
|
|
169
190
|
p.eatProduction('ReferenceTag', { path: 'reference' });
|
|
@@ -184,10 +205,10 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
184
205
|
// @Node
|
|
185
206
|
Flags(p) {
|
|
186
207
|
let tr = p.eatMatch('#', PN, { path: 'triviaToken' });
|
|
187
|
-
p.eatMatch('~', PN, { path: 'intrinsicToken' });
|
|
188
208
|
p.eatMatch('*', PN, { path: 'tokenToken' });
|
|
189
209
|
let esc = p.eatMatch('@', PN, { path: 'escapeToken' });
|
|
190
210
|
let exp = p.eatMatch('+', PN, { path: 'expressionToken' });
|
|
211
|
+
p.eatMatch('$', PN, { path: 'hasGapToken' });
|
|
191
212
|
|
|
192
213
|
if ((tr && esc) || (exp && (tr || esc))) throw new Error();
|
|
193
214
|
}
|
|
@@ -210,12 +231,18 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
210
231
|
|
|
211
232
|
let sp = p.eatMatchTrivia(_);
|
|
212
233
|
|
|
213
|
-
|
|
214
|
-
|
|
234
|
+
let iv;
|
|
235
|
+
|
|
236
|
+
if (sp && (p.match(/['"]/y) || p.atExpression)) {
|
|
237
|
+
iv = p.eatProduction('String', { path: 'intrinsicValue' });
|
|
215
238
|
|
|
216
239
|
sp = p.eatMatchTrivia(_);
|
|
217
240
|
}
|
|
218
241
|
|
|
242
|
+
if (!flags.properties.tokenToken && iv) {
|
|
243
|
+
throw new Error();
|
|
244
|
+
}
|
|
245
|
+
|
|
219
246
|
if ((sp && p.match(/[a-zA-Z]+/y)) || p.atExpression) {
|
|
220
247
|
p.eatProduction('Attributes');
|
|
221
248
|
sp = p.eatMatchTrivia(_);
|
|
@@ -232,16 +259,37 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
232
259
|
p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
|
|
233
260
|
}
|
|
234
261
|
|
|
262
|
+
// @Node
|
|
263
|
+
OpenFragmentTag(p) {
|
|
264
|
+
p.eat('<', PN, { path: 'openToken', startSpan: 'Tag', balanced: '>' });
|
|
265
|
+
|
|
266
|
+
let flags = null;
|
|
267
|
+
if (!p.atExpression) {
|
|
268
|
+
flags = p.eatProduction('Flags', { path: 'flags' });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (p.done) {
|
|
272
|
+
p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// @Node
|
|
278
|
+
CloseFragmentTag(p) {
|
|
279
|
+
p.eat('</', PN, { path: 'openToken', startSpan: 'Tag', balanced: '>' });
|
|
280
|
+
p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
|
|
281
|
+
}
|
|
282
|
+
|
|
235
283
|
// @Fragment
|
|
236
284
|
Attributes(p) {
|
|
237
285
|
let sp = true;
|
|
238
|
-
while (sp && (p.match(
|
|
286
|
+
while (sp && (p.match(/!?[a-zA-Z]/y) || p.atExpression)) {
|
|
239
287
|
if (p.atExpression) {
|
|
240
288
|
p.eatProduction('Attributes'); // ??
|
|
241
289
|
} else {
|
|
242
290
|
p.eatProduction('Attribute', { path: 'attributes[]' });
|
|
243
291
|
}
|
|
244
|
-
if (p.match(/\s
|
|
292
|
+
if (p.match(/\s+!?[a-zA-Z]/y) || (p.match(/\s+$/y) && !p.quasisDone)) {
|
|
245
293
|
sp = p.eatMatchTrivia(_);
|
|
246
294
|
} else {
|
|
247
295
|
sp = false;
|
|
@@ -251,7 +299,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
251
299
|
|
|
252
300
|
// @Cover
|
|
253
301
|
Attribute(p) {
|
|
254
|
-
if (p.match(/[a-zA-Z][
|
|
302
|
+
if (p.match(/[a-zA-Z][a-zA-Z-_]*\s*=/y)) {
|
|
255
303
|
p.eatProduction('MappingAttribute');
|
|
256
304
|
} else {
|
|
257
305
|
p.eatProduction('BooleanAttribute');
|
|
@@ -260,13 +308,13 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
260
308
|
|
|
261
309
|
// @Node
|
|
262
310
|
BooleanAttribute(p) {
|
|
263
|
-
p.
|
|
264
|
-
p.eat(/[a-zA-Z]
|
|
311
|
+
p.eatMatch('!', KW, { path: 'negateToken' });
|
|
312
|
+
p.eat(/[a-zA-Z][a-zA-Z-_]*/y, ID, { path: 'key' });
|
|
265
313
|
}
|
|
266
314
|
|
|
267
315
|
// @Node
|
|
268
316
|
MappingAttribute(p) {
|
|
269
|
-
p.eat(/[a-zA-Z]
|
|
317
|
+
p.eat(/[a-zA-Z][a-zA-Z-_]*/y, ID, { path: 'key' });
|
|
270
318
|
p.eatMatchTrivia(_);
|
|
271
319
|
p.eat('=', PN, { path: 'mapToken' });
|
|
272
320
|
p.eatMatchTrivia(_);
|
|
@@ -283,7 +331,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
283
331
|
}
|
|
284
332
|
|
|
285
333
|
TagType(p) {
|
|
286
|
-
if (p.match(/[[a-zA-Z]
|
|
334
|
+
if (p.match(/['"]|[a-zA-Z\.]+:/y)) {
|
|
287
335
|
p.eatProduction('LanguageReference', { path: 'language' });
|
|
288
336
|
p.eat(':', PN, { path: 'namespaceSeparatorToken' });
|
|
289
337
|
p.eatProduction('Identifier', { path: 'type' });
|
|
@@ -324,7 +372,11 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
324
372
|
|
|
325
373
|
// @Node
|
|
326
374
|
ReferenceTag(p) {
|
|
327
|
-
p.
|
|
375
|
+
if (p.match('.')) {
|
|
376
|
+
p.eat('.', PN, { path: 'name' });
|
|
377
|
+
} else {
|
|
378
|
+
p.eatProduction('Identifier', { path: 'name' });
|
|
379
|
+
}
|
|
328
380
|
p.eatMatchTrivia(_);
|
|
329
381
|
p.eatMatch('[]', PN, { path: 'arrayToken' });
|
|
330
382
|
p.eatMatchTrivia(_);
|
package/lib/languages/regex.js
CHANGED
package/lib/languages/spamex.js
CHANGED
|
@@ -14,18 +14,22 @@ const canonicalURL = 'https://bablr.org/languages/core/en/spamex';
|
|
|
14
14
|
const dependencies = { CSTML, Regex };
|
|
15
15
|
|
|
16
16
|
const covers = buildCovers({
|
|
17
|
-
[sym.node]: [
|
|
17
|
+
[sym.node]: [
|
|
18
|
+
'Attribute',
|
|
19
|
+
'Identifier',
|
|
20
|
+
'Matcher',
|
|
21
|
+
'OpenNodeMatcher',
|
|
22
|
+
'CloseNodeMatcher',
|
|
23
|
+
'Literal',
|
|
24
|
+
'CSTML:Flags',
|
|
25
|
+
],
|
|
18
26
|
Attribute: ['MappingAttribute', 'BooleanAttribute'],
|
|
19
27
|
AttributeValue: ['CSTML:String', 'CSTML:Number'],
|
|
20
|
-
Matcher: ['NodeMatcher', '
|
|
28
|
+
Matcher: ['NodeMatcher', 'StringMatcher'],
|
|
21
29
|
StringMatcher: ['CSTML:String', 'Regex:Pattern'],
|
|
22
30
|
});
|
|
23
31
|
|
|
24
32
|
const grammar = class SpamexMiniparserGrammar {
|
|
25
|
-
Pattern(p) {
|
|
26
|
-
p.eatProduction('Matcher', { path: 'matcher' });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
33
|
// @Cover
|
|
30
34
|
Matcher(p) {
|
|
31
35
|
if (p.match(/<[^!/]/y)) {
|
|
@@ -67,10 +71,8 @@ const grammar = class SpamexMiniparserGrammar {
|
|
|
67
71
|
p.eatProduction('CSTML:Flags', { path: 'flags' });
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
if (p.match(/[a-zA-Z]+:/y)) {
|
|
71
|
-
p.
|
|
72
|
-
p.eat(':', PN, { path: 'namespaceSeparatorToken' });
|
|
73
|
-
p.eat(/[a-zA-Z]+/y, ID, { path: 'type' });
|
|
74
|
+
if (p.match(/['"]|[a-zA-Z]+:/y)) {
|
|
75
|
+
p.eatProduction('CSTML:TagType', { path: 'type' });
|
|
74
76
|
} else if (p.match('?')) {
|
|
75
77
|
p.eat('?', PN, { path: 'type' });
|
|
76
78
|
} else if (p.match(' ')) {
|
package/lib/miniparser.js
CHANGED
|
@@ -178,9 +178,19 @@ class TemplateParser {
|
|
|
178
178
|
const { properties, children } = parentPath.node;
|
|
179
179
|
const path = parsePath(this.m.attrs.path);
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
if (isArray(result)) {
|
|
182
|
+
for (const value of result) {
|
|
183
|
+
children.push(ref(path));
|
|
182
184
|
|
|
183
|
-
|
|
185
|
+
// TODO interpolate separators!
|
|
186
|
+
|
|
187
|
+
set(properties, path, value);
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
children.push(ref(path));
|
|
191
|
+
|
|
192
|
+
set(properties, path, result);
|
|
193
|
+
}
|
|
184
194
|
}
|
|
185
195
|
} else {
|
|
186
196
|
if (isEmbedded) {
|
|
@@ -198,6 +208,7 @@ class TemplateParser {
|
|
|
198
208
|
if (result?.attrs) {
|
|
199
209
|
node.attributes = result.attrs;
|
|
200
210
|
}
|
|
211
|
+
|
|
201
212
|
if (parentPath?.node && !covers.has(type)) {
|
|
202
213
|
const path = parsePath(this.m.attrs.path);
|
|
203
214
|
|
package/lib/print.js
CHANGED
|
@@ -161,17 +161,11 @@ class Resolver {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
const buildDoctypeTag = () => {
|
|
165
|
-
return freeze({ type: DoctypeTag, value: { doctype: 'cstml', version: 0 } });
|
|
166
|
-
};
|
|
167
|
-
|
|
168
164
|
function* streamFromTree(rootNode) {
|
|
169
165
|
if (!rootNode || rootNode.type === GapTag) {
|
|
170
166
|
return rootNode;
|
|
171
167
|
}
|
|
172
168
|
|
|
173
|
-
yield buildDoctypeTag(rootNode.attributes);
|
|
174
|
-
|
|
175
169
|
let stack = emptyStack.push(rootNode);
|
|
176
170
|
const resolver = new Resolver();
|
|
177
171
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/boot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Compile-time tools for bootstrapping BABLR VM",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=12.0.0"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@babel/helper-module-imports": "^7.22.15",
|
|
23
23
|
"@babel/template": "^7.22.15",
|
|
24
24
|
"@babel/types": "7.23.0",
|
|
25
|
-
"@bablr/boot-helpers": "0.3.
|
|
25
|
+
"@bablr/boot-helpers": "0.3.1",
|
|
26
26
|
"@iter-tools/imm-stack": "1.1.0",
|
|
27
27
|
"escape-string-regexp": "4.0.0",
|
|
28
28
|
"iter-tools": "^7.5.3",
|
package/shorthand.macro.js
CHANGED
|
@@ -96,9 +96,7 @@ const generateBabelNodeChild = (child, exprs, bindings) => {
|
|
|
96
96
|
};
|
|
97
97
|
|
|
98
98
|
const getAgastNodeType = (flags) => {
|
|
99
|
-
if (flags.
|
|
100
|
-
return 's_i_node';
|
|
101
|
-
} else if (flags.token && flags.trivia) {
|
|
99
|
+
if (flags.token && flags.trivia) {
|
|
102
100
|
return 's_t_node';
|
|
103
101
|
} else if (flags.token && flags.escape) {
|
|
104
102
|
return 's_e_node';
|
|
@@ -140,7 +138,7 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
140
138
|
} else {
|
|
141
139
|
// gap
|
|
142
140
|
const expr = exprs.pop();
|
|
143
|
-
const { interpolateArray,
|
|
141
|
+
const { interpolateArray, interpolateFragmentChildren, interpolateString } = bindings;
|
|
144
142
|
|
|
145
143
|
if (pathIsArray) {
|
|
146
144
|
add(
|
|
@@ -155,17 +153,10 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
155
153
|
children_ = btree.push(
|
|
156
154
|
children_,
|
|
157
155
|
t.spreadElement(
|
|
158
|
-
expression('%%
|
|
159
|
-
|
|
156
|
+
expression('%%interpolateFragmentChildren%%(%%expr%%, %%ref%%)')({
|
|
157
|
+
interpolateFragmentChildren,
|
|
160
158
|
expr,
|
|
161
159
|
ref: expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t }),
|
|
162
|
-
|
|
163
|
-
// Really really awful unsafe-as-heck hack, to be removed ASAP
|
|
164
|
-
// Fixing this requires having interpolation happen during parsing
|
|
165
|
-
// That way the grammar can deal with the separators!
|
|
166
|
-
sep: expression(
|
|
167
|
-
"%%t%%.embedded(%%t%%.t_node(%%l%%.Comment, null, [%%t%%.embedded(%%t%%.t_node('Space', 'Space', [%%t%%.lit(' ')]))]))",
|
|
168
|
-
)({ t: bindings.t, l: bindings.l }),
|
|
169
160
|
}),
|
|
170
161
|
),
|
|
171
162
|
);
|
|
@@ -306,10 +297,10 @@ const shorthandMacro = ({ references }) => {
|
|
|
306
297
|
);
|
|
307
298
|
}
|
|
308
299
|
|
|
309
|
-
if (!bindings.
|
|
310
|
-
bindings.
|
|
300
|
+
if (!bindings.interpolateFragmentChildren) {
|
|
301
|
+
bindings.interpolateFragmentChildren = addNamed(
|
|
311
302
|
getTopScope(ref.scope).path,
|
|
312
|
-
'
|
|
303
|
+
'interpolateFragmentChildren',
|
|
313
304
|
'@bablr/agast-helpers/template',
|
|
314
305
|
);
|
|
315
306
|
}
|