@bablr/boot 0.3.0 → 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 +94 -55
- package/lib/index.js +108 -34
- package/lib/index.mjs +15 -1
- package/lib/languages/cstml.js +34 -29
- package/lib/languages/instruction.js +1 -1
- package/lib/languages/regex.js +2 -2
- package/lib/languages/spamex.js +41 -8
- package/lib/match.js +1 -1
- package/lib/miniparser.js +5 -4
- package/lib/print.js +199 -125
- package/package.json +3 -2
- package/shorthand.macro.js +111 -63
- 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,18 +70,26 @@ 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
|
}
|
|
@@ -70,6 +102,8 @@ const getAgastNodeType = (flags) => {
|
|
|
70
102
|
return 's_t_node';
|
|
71
103
|
} else if (flags.token && flags.escape) {
|
|
72
104
|
return 's_e_node';
|
|
105
|
+
} else if (flags.escape) {
|
|
106
|
+
return 'e_node';
|
|
73
107
|
} else if (flags.token) {
|
|
74
108
|
return 's_node';
|
|
75
109
|
} else {
|
|
@@ -78,75 +112,88 @@ const getAgastNodeType = (flags) => {
|
|
|
78
112
|
};
|
|
79
113
|
|
|
80
114
|
const generateBabelNode = (node, exprs, bindings) => {
|
|
81
|
-
const resolver = new PathResolver(node);
|
|
82
115
|
const { flags = {}, children, type, language, attributes } = node;
|
|
83
116
|
|
|
84
117
|
const properties_ = {};
|
|
85
|
-
|
|
118
|
+
let children_ = [];
|
|
86
119
|
|
|
87
120
|
if (!children) {
|
|
88
121
|
throw new Error();
|
|
89
122
|
}
|
|
90
123
|
|
|
91
|
-
|
|
92
|
-
if (child.type === 'Reference') {
|
|
93
|
-
const path = child.value;
|
|
94
|
-
const { isArray: pathIsArray } = path;
|
|
95
|
-
const resolved = resolver.get(path);
|
|
124
|
+
// resolver.advance({ type: DoctypeTag, value: {} });
|
|
96
125
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const { interpolateArray, interpolateArrayChildren, interpolateString } = bindings;
|
|
126
|
+
for (const child of btree.traverse(children)) {
|
|
127
|
+
if (child.type === ReferenceTag) {
|
|
128
|
+
const path = child.value;
|
|
129
|
+
const { isArray: pathIsArray, name } = path;
|
|
130
|
+
if (!pathIsArray || hasOwn(properties_, name)) {
|
|
131
|
+
let resolved = node.properties[name];
|
|
104
132
|
|
|
105
133
|
if (pathIsArray) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
134
|
+
resolved = btree.getAt(btree.getSum(properties_[name]), resolved);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (resolved.type !== sym.gap) {
|
|
138
|
+
add(properties_, path, generateBabelNode(resolved, exprs, bindings));
|
|
139
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
140
|
+
} else {
|
|
141
|
+
// gap
|
|
142
|
+
const expr = exprs.pop();
|
|
143
|
+
const { interpolateArray, interpolateArrayChildren, interpolateString } = bindings;
|
|
144
|
+
|
|
145
|
+
if (pathIsArray) {
|
|
146
|
+
add(
|
|
147
|
+
properties_,
|
|
148
|
+
path,
|
|
149
|
+
expression('[...%%interpolateArray%%(%%expr%%)]')({
|
|
150
|
+
interpolateArray,
|
|
151
|
+
expr,
|
|
152
|
+
}).elements[0],
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
children_ = btree.push(
|
|
156
|
+
children_,
|
|
157
|
+
t.spreadElement(
|
|
158
|
+
expression('%%interpolateArrayChildren%%(%%expr%%, %%ref%%, %%sep%%)')({
|
|
159
|
+
interpolateArrayChildren,
|
|
160
|
+
expr,
|
|
161
|
+
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
|
+
}),
|
|
170
|
+
),
|
|
171
|
+
);
|
|
172
|
+
} else if (language === cstml.canonicalURL && type === 'String') {
|
|
173
|
+
add(
|
|
174
|
+
properties_,
|
|
175
|
+
path,
|
|
176
|
+
expression('%%interpolateString%%(%%expr%%)')({
|
|
177
|
+
interpolateString,
|
|
119
178
|
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
179
|
}),
|
|
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);
|
|
180
|
+
);
|
|
144
181
|
|
|
145
|
-
|
|
182
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
183
|
+
} else {
|
|
184
|
+
add(properties_, path, expr);
|
|
185
|
+
|
|
186
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
187
|
+
}
|
|
146
188
|
}
|
|
189
|
+
} else if (pathIsArray) {
|
|
190
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
191
|
+
properties_[name] = [];
|
|
147
192
|
}
|
|
148
193
|
} else {
|
|
149
|
-
|
|
194
|
+
if (child.type !== OpenNodeTag && child.type !== CloseNodeTag) {
|
|
195
|
+
children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
|
|
196
|
+
}
|
|
150
197
|
}
|
|
151
198
|
}
|
|
152
199
|
|
|
@@ -160,10 +207,7 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
160
207
|
: {
|
|
161
208
|
properties: t.objectExpression(
|
|
162
209
|
Object.entries(properties_).map(([key, value]) =>
|
|
163
|
-
t.objectProperty(
|
|
164
|
-
t.identifier(key),
|
|
165
|
-
isArray(value) ? t.arrayExpression(value) : value,
|
|
166
|
-
),
|
|
210
|
+
t.objectProperty(t.identifier(key), isArray(value) ? getBtreeASTValue(value) : value),
|
|
167
211
|
),
|
|
168
212
|
),
|
|
169
213
|
attributes: t.objectExpression(
|
|
@@ -173,6 +217,10 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
173
217
|
),
|
|
174
218
|
};
|
|
175
219
|
|
|
220
|
+
if (type === sym.gap) {
|
|
221
|
+
return expression(`%%t%%.g_node()`)({ t: bindings.t });
|
|
222
|
+
}
|
|
223
|
+
|
|
176
224
|
return expression(`%%t%%.%%nodeType%%(%%l%%.%%language%%, %%type%%, %%children%%${propsAtts})`)({
|
|
177
225
|
t: bindings.t,
|
|
178
226
|
l: bindings.l,
|
|
@@ -181,8 +229,8 @@ const generateBabelNode = (node, exprs, bindings) => {
|
|
|
181
229
|
type: t.stringLiteral(type),
|
|
182
230
|
children:
|
|
183
231
|
nodeType === 's_node' || nodeType === 's_i_node'
|
|
184
|
-
? t.stringLiteral(children
|
|
185
|
-
:
|
|
232
|
+
? t.stringLiteral(btree.getAt(1, children).value)
|
|
233
|
+
: getBtreeASTValue(children_),
|
|
186
234
|
...propsAttsValue,
|
|
187
235
|
});
|
|
188
236
|
};
|
package/lib/symbols.js
DELETED