@bablr/boot 0.4.0 → 0.6.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 +122 -55
- package/lib/index.js +131 -39
- package/lib/index.mjs +15 -1
- package/lib/languages/cstml.js +54 -40
- package/lib/languages/instruction.js +1 -1
- package/lib/languages/regex.js +3 -3
- package/lib/languages/spamex.js +41 -8
- package/lib/match.js +1 -1
- package/lib/miniparser.js +18 -6
- package/lib/print.js +196 -128
- package/package.json +3 -2
- package/shorthand.macro.js +108 -69
- package/lib/symbols.js +0 -4
package/shorthand.macro.js
CHANGED
|
@@ -8,21 +8,45 @@ const isNull = require('iter-tools/methods/is-null');
|
|
|
8
8
|
const isString = require('iter-tools/methods/is-string');
|
|
9
9
|
const concat = require('iter-tools/methods/concat');
|
|
10
10
|
const { createMacro } = require('babel-plugin-macros');
|
|
11
|
-
const { TemplateParser,
|
|
11
|
+
const { TemplateParser, add, getAgASTValue } = require('./lib/index.js');
|
|
12
12
|
const i = require('./lib/languages/instruction.js');
|
|
13
13
|
const re = require('./lib/languages/regex.js');
|
|
14
14
|
const spam = require('./lib/languages/spamex.js');
|
|
15
15
|
const cstml = require('./lib/languages/cstml.js');
|
|
16
16
|
const { addNamespace, addNamed } = require('@babel/helper-module-imports');
|
|
17
|
-
const { PathResolver } = require('@bablr/boot-helpers/path');
|
|
18
17
|
const { printPrettyCSTML } = require('./lib/print.js');
|
|
18
|
+
const sym = require('@bablr/boot-helpers/symbols');
|
|
19
|
+
const {
|
|
20
|
+
OpenNodeTag,
|
|
21
|
+
CloseNodeTag,
|
|
22
|
+
ReferenceTag,
|
|
23
|
+
GapTag,
|
|
24
|
+
ArrayTag,
|
|
25
|
+
LiteralTag,
|
|
26
|
+
EmbeddedNode,
|
|
27
|
+
} = require('@bablr/boot-helpers/symbols');
|
|
28
|
+
const btree = require('@bablr/boot-helpers/btree');
|
|
19
29
|
|
|
20
30
|
const { isArray } = Array;
|
|
31
|
+
const { hasOwn } = Object;
|
|
21
32
|
const isNumber = (v) => typeof v === 'number';
|
|
22
33
|
const isBoolean = (v) => typeof v === 'boolean';
|
|
23
34
|
const isPlainObject = (v) => isObject(v) && !isArray(v);
|
|
24
35
|
const printRef = (ref) => (ref.isArray ? `${ref.name}[]` : ref.name);
|
|
25
36
|
|
|
37
|
+
const getBtreeASTValue = (tree, exprs, bindings) => {
|
|
38
|
+
if (!isArray(tree)) return tree;
|
|
39
|
+
|
|
40
|
+
if (btree.isLeafNode(tree)) {
|
|
41
|
+
return t.arrayExpression(tree);
|
|
42
|
+
} else {
|
|
43
|
+
return t.arrayExpression([
|
|
44
|
+
t.numericLiteral(tree[0]),
|
|
45
|
+
t.arrayExpression(tree[1].map((v) => getBtreeASTValue(v, exprs, bindings))),
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
26
50
|
const getBabelASTValue = (v, exprs, bindings) => {
|
|
27
51
|
return isNull(v)
|
|
28
52
|
? t.nullLiteral()
|
|
@@ -46,30 +70,38 @@ const getBabelASTValue = (v, exprs, bindings) => {
|
|
|
46
70
|
};
|
|
47
71
|
|
|
48
72
|
const generateBabelNodeChild = (child, exprs, bindings) => {
|
|
49
|
-
if (child.type ===
|
|
73
|
+
if (child.type === ReferenceTag) {
|
|
50
74
|
return expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t });
|
|
51
|
-
} else if (child.type ===
|
|
75
|
+
} else if (child.type === LiteralTag) {
|
|
52
76
|
return expression(`%%t%%.lit(%%value%%)`)({
|
|
53
77
|
t: bindings.t,
|
|
54
78
|
value: getBabelASTValue(child.value, exprs, bindings),
|
|
55
79
|
});
|
|
56
|
-
} else if (child.type ===
|
|
80
|
+
} else if (child.type === EmbeddedNode) {
|
|
57
81
|
return expression(`%%t%%.embedded(%%value%%)`)({
|
|
58
82
|
t: bindings.t,
|
|
59
83
|
value: generateBabelNode(child.value, exprs, bindings),
|
|
60
84
|
});
|
|
85
|
+
} else if (child.type === ArrayTag) {
|
|
86
|
+
return expression(`%%t%%.arr()`)({
|
|
87
|
+
t: bindings.t,
|
|
88
|
+
});
|
|
89
|
+
} else if (child.type === GapTag) {
|
|
90
|
+
return expression(`%%t%%.gap()`)({
|
|
91
|
+
t: bindings.t,
|
|
92
|
+
});
|
|
61
93
|
} else {
|
|
62
94
|
throw new Error(`Unknown child type ${child.type}`);
|
|
63
95
|
}
|
|
64
96
|
};
|
|
65
97
|
|
|
66
98
|
const getAgastNodeType = (flags) => {
|
|
67
|
-
if (flags.
|
|
68
|
-
return 's_i_node';
|
|
69
|
-
} else if (flags.token && flags.trivia) {
|
|
99
|
+
if (flags.token && flags.trivia) {
|
|
70
100
|
return 's_t_node';
|
|
71
101
|
} else if (flags.token && flags.escape) {
|
|
72
102
|
return 's_e_node';
|
|
103
|
+
} else if (flags.escape) {
|
|
104
|
+
return 'e_node';
|
|
73
105
|
} else if (flags.token) {
|
|
74
106
|
return 's_node';
|
|
75
107
|
} else {
|
|
@@ -78,75 +110,81 @@ const getAgastNodeType = (flags) => {
|
|
|
78
110
|
};
|
|
79
111
|
|
|
80
112
|
const generateBabelNode = (node, exprs, bindings) => {
|
|
81
|
-
const resolver = new PathResolver(node);
|
|
82
113
|
const { flags = {}, children, type, language, attributes } = node;
|
|
83
114
|
|
|
84
115
|
const properties_ = {};
|
|
85
|
-
|
|
116
|
+
let children_ = [];
|
|
86
117
|
|
|
87
118
|
if (!children) {
|
|
88
119
|
throw new Error();
|
|
89
120
|
}
|
|
90
121
|
|
|
91
|
-
|
|
92
|
-
if (child.type === 'Reference') {
|
|
93
|
-
const path = child.value;
|
|
94
|
-
const { isArray: pathIsArray } = path;
|
|
95
|
-
const resolved = resolver.get(path);
|
|
122
|
+
// resolver.advance({ type: DoctypeTag, value: {} });
|
|
96
123
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const { interpolateArray, interpolateArrayChildren, interpolateString } = bindings;
|
|
124
|
+
for (const child of btree.traverse(children)) {
|
|
125
|
+
if (child.type === ReferenceTag) {
|
|
126
|
+
const path = child.value;
|
|
127
|
+
const { isArray: pathIsArray, name } = path;
|
|
128
|
+
if (!pathIsArray || hasOwn(properties_, name)) {
|
|
129
|
+
let resolved = node.properties[name];
|
|
104
130
|
|
|
105
131
|
if (pathIsArray) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
132
|
+
resolved = btree.getAt(btree.getSum(properties_[name]), resolved);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (resolved.type !== sym.gap) {
|
|
136
|
+
add(properties_, path, generateBabelNode(resolved, exprs, bindings));
|
|
137
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
138
|
+
} else {
|
|
139
|
+
// gap
|
|
140
|
+
const expr = exprs.pop();
|
|
141
|
+
const { interpolateArray, interpolateFragmentChildren, interpolateString } = bindings;
|
|
142
|
+
|
|
143
|
+
if (pathIsArray) {
|
|
144
|
+
add(
|
|
145
|
+
properties_,
|
|
146
|
+
path,
|
|
147
|
+
expression('[...%%interpolateArray%%(%%expr%%)]')({
|
|
148
|
+
interpolateArray,
|
|
149
|
+
expr,
|
|
150
|
+
}).elements[0],
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
children_ = btree.push(
|
|
154
|
+
children_,
|
|
155
|
+
t.spreadElement(
|
|
156
|
+
expression('%%interpolateFragmentChildren%%(%%expr%%, %%ref%%)')({
|
|
157
|
+
interpolateFragmentChildren,
|
|
158
|
+
expr,
|
|
159
|
+
ref: expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t }),
|
|
160
|
+
}),
|
|
161
|
+
),
|
|
162
|
+
);
|
|
163
|
+
} else if (language === cstml.canonicalURL && type === 'String') {
|
|
164
|
+
add(
|
|
165
|
+
properties_,
|
|
166
|
+
path,
|
|
167
|
+
expression('%%interpolateString%%(%%expr%%)')({
|
|
168
|
+
interpolateString,
|
|
119
169
|
expr,
|
|
120
|
-
ref: expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t }),
|
|
121
|
-
|
|
122
|
-
// Really really awful unsafe-as-heck hack, to be removed ASAP
|
|
123
|
-
// Fixing this requires having interpolation happen during parsing
|
|
124
|
-
// That way the grammar can deal with the separators!
|
|
125
|
-
sep: expression(
|
|
126
|
-
"%%t%%.embedded(%%t%%.t_node(%%l%%.Comment, null, [%%t%%.embedded(%%t%%.t_node('Space', 'Space', [%%t%%.lit(' ')]))]))",
|
|
127
|
-
)({ t: bindings.t, l: bindings.l }),
|
|
128
170
|
}),
|
|
129
|
-
)
|
|
130
|
-
);
|
|
131
|
-
} else if (language === cstml.canonicalURL && type === 'String') {
|
|
132
|
-
set(
|
|
133
|
-
properties_,
|
|
134
|
-
path,
|
|
135
|
-
expression('%%interpolateString%%(%%expr%%)')({
|
|
136
|
-
interpolateString,
|
|
137
|
-
expr,
|
|
138
|
-
}),
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
children_.push(generateBabelNodeChild(child, exprs, bindings));
|
|
142
|
-
} else {
|
|
143
|
-
set(properties_, path, expr);
|
|
171
|
+
);
|
|
144
172
|
|
|
145
|
-
|
|
173
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
174
|
+
} else {
|
|
175
|
+
add(properties_, path, expr);
|
|
176
|
+
|
|
177
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
178
|
+
}
|
|
146
179
|
}
|
|
180
|
+
} else if (pathIsArray) {
|
|
181
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
182
|
+
properties_[name] = [];
|
|
147
183
|
}
|
|
148
184
|
} else {
|
|
149
|
-
|
|
185
|
+
if (child.type !== OpenNodeTag && child.type !== CloseNodeTag) {
|
|
186
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
187
|
+
}
|
|
150
188
|
}
|
|
151
189
|
}
|
|
152
190
|
|
|
@@ -160,10 +198,7 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
160
198
|
: {
|
|
161
199
|
properties: t.objectExpression(
|
|
162
200
|
Object.entries(properties_).map(([key, value]) =>
|
|
163
|
-
t.objectProperty(
|
|
164
|
-
t.identifier(key),
|
|
165
|
-
isArray(value) ? t.arrayExpression(value) : value,
|
|
166
|
-
),
|
|
201
|
+
t.objectProperty(t.identifier(key), isArray(value) ? getBtreeASTValue(value) : value),
|
|
167
202
|
),
|
|
168
203
|
),
|
|
169
204
|
attributes: t.objectExpression(
|
|
@@ -173,6 +208,10 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
173
208
|
),
|
|
174
209
|
};
|
|
175
210
|
|
|
211
|
+
if (type === sym.gap) {
|
|
212
|
+
return expression(`%%t%%.g_node()`)({ t: bindings.t });
|
|
213
|
+
}
|
|
214
|
+
|
|
176
215
|
return expression(`%%t%%.%%nodeType%%(%%l%%.%%language%%, %%type%%, %%children%%${propsAtts})`)({
|
|
177
216
|
t: bindings.t,
|
|
178
217
|
l: bindings.l,
|
|
@@ -181,8 +220,8 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
181
220
|
type: t.stringLiteral(type),
|
|
182
221
|
children:
|
|
183
222
|
nodeType === 's_node' || nodeType === 's_i_node'
|
|
184
|
-
? t.stringLiteral(children
|
|
185
|
-
:
|
|
223
|
+
? t.stringLiteral(btree.getAt(1, children).value)
|
|
224
|
+
: getBtreeASTValue(children_),
|
|
186
225
|
...propsAttsValue,
|
|
187
226
|
});
|
|
188
227
|
};
|
|
@@ -258,10 +297,10 @@ const shorthandMacro = ({ references }) => {
|
|
|
258
297
|
);
|
|
259
298
|
}
|
|
260
299
|
|
|
261
|
-
if (!bindings.
|
|
262
|
-
bindings.
|
|
300
|
+
if (!bindings.interpolateFragmentChildren) {
|
|
301
|
+
bindings.interpolateFragmentChildren = addNamed(
|
|
263
302
|
getTopScope(ref.scope).path,
|
|
264
|
-
'
|
|
303
|
+
'interpolateFragmentChildren',
|
|
265
304
|
'@bablr/agast-helpers/template',
|
|
266
305
|
);
|
|
267
306
|
}
|
package/lib/symbols.js
DELETED