@bablr/boot 0.6.2 → 0.7.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/index.js +37 -218
- package/lib/languages/cstml.js +86 -375
- package/lib/languages/instruction.js +84 -119
- package/lib/languages/json.js +241 -0
- package/lib/languages/regex.js +76 -52
- package/lib/languages/spamex.js +119 -82
- package/lib/match.js +13 -11
- package/lib/miniparser.js +101 -80
- package/lib/path.js +42 -18
- package/lib/utils.js +14 -100
- package/package.json +11 -22
- package/shorthand.macro.js +5 -5
- package/lib/builders.js +0 -475
- package/lib/index.mjs +0 -17
- package/lib/print.js +0 -401
package/lib/index.js
CHANGED
|
@@ -1,79 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const instruction = require('./languages/instruction.js');
|
|
6
|
-
const {
|
|
7
|
-
buildLiteralTag,
|
|
8
|
-
buildDoctypeTag,
|
|
9
|
-
buildNodeOpenTag,
|
|
10
|
-
buildNodeCloseTag,
|
|
11
|
-
buildFragmentOpenTag,
|
|
12
|
-
buildFragmentCloseTag,
|
|
13
|
-
buildTriviaNode,
|
|
14
|
-
buildGapNode,
|
|
15
|
-
buildSyntacticEscapeNode,
|
|
16
|
-
nodeFlags,
|
|
17
|
-
buildReferenceTag,
|
|
18
|
-
} = require('./builders.js');
|
|
19
|
-
const { TemplateParser } = require('./miniparser.js');
|
|
20
|
-
const { Resolver } = require('./print.js');
|
|
21
|
-
const {
|
|
22
|
-
OpenNodeTag,
|
|
23
|
-
CloseNodeTag,
|
|
24
|
-
ReferenceTag,
|
|
25
|
-
ArrayTag,
|
|
26
|
-
EmbeddedNode,
|
|
27
|
-
Trivia,
|
|
28
|
-
Escape,
|
|
29
|
-
} = require('@bablr/boot-helpers/symbols');
|
|
30
|
-
const btree = require('@bablr/boot-helpers/btree');
|
|
1
|
+
import * as cstmll from './languages/cstml.js';
|
|
2
|
+
import * as spamex from './languages/spamex.js';
|
|
3
|
+
import * as regex from './languages/regex.js';
|
|
4
|
+
import * as instruction from './languages/instruction.js';
|
|
31
5
|
|
|
32
|
-
|
|
33
|
-
|
|
6
|
+
import { TemplateParser } from './miniparser.js';
|
|
7
|
+
import { Resolver, buildEmbeddedMatcher, buildEmbeddedRegex } from '@bablr/agast-helpers/tree';
|
|
34
8
|
|
|
35
|
-
const
|
|
36
|
-
const { type, properties } = node;
|
|
37
|
-
const { 1: name, 2: index } = /^([^\.]+)(?:\.(\d+))?/.exec(path) || [];
|
|
38
|
-
|
|
39
|
-
if (!hasOwn(properties, name)) {
|
|
40
|
-
throw new Error(`Cannot find {name: ${name}} on node of {type: ${type}}`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (index != null) {
|
|
44
|
-
return properties[name]?.[parseInt(index, 10)];
|
|
45
|
-
} else {
|
|
46
|
-
return properties[name];
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const add = (obj, path, value) => {
|
|
51
|
-
const { name, isArray: pathIsArray } = path;
|
|
52
|
-
if (pathIsArray) {
|
|
53
|
-
if (!obj[name]) {
|
|
54
|
-
obj[name] = [];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (!isArray(obj[name])) throw new Error('bad array value');
|
|
58
|
-
|
|
59
|
-
obj[name] = btree.push(obj[name], value);
|
|
60
|
-
} else {
|
|
61
|
-
if (hasOwn(obj, name)) {
|
|
62
|
-
throw new Error('duplicate child name');
|
|
63
|
-
}
|
|
64
|
-
obj[name] = value;
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const buildTag = (language, defaultType) => {
|
|
9
|
+
export const buildTag = (language, defaultType) => {
|
|
69
10
|
const defaultTag = (quasis, ...exprs) => {
|
|
70
|
-
return
|
|
71
|
-
language,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
type: defaultType,
|
|
75
|
-
}),
|
|
76
|
-
);
|
|
11
|
+
return new TemplateParser(language, quasis.raw, exprs).eval({
|
|
12
|
+
language: language.name,
|
|
13
|
+
type: defaultType,
|
|
14
|
+
});
|
|
77
15
|
};
|
|
78
16
|
|
|
79
17
|
return new Proxy(defaultTag, {
|
|
@@ -83,159 +21,40 @@ const buildTag = (language, defaultType) => {
|
|
|
83
21
|
|
|
84
22
|
get(_, type) {
|
|
85
23
|
return (quasis, ...exprs) => {
|
|
86
|
-
return
|
|
87
|
-
language,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
type,
|
|
91
|
-
}),
|
|
92
|
-
);
|
|
24
|
+
return new TemplateParser(language, quasis.raw, exprs).eval({
|
|
25
|
+
language: language.name,
|
|
26
|
+
type,
|
|
27
|
+
});
|
|
93
28
|
};
|
|
94
29
|
},
|
|
95
30
|
});
|
|
96
31
|
};
|
|
97
32
|
|
|
98
|
-
const parse = (language, type, sourceText) => {
|
|
33
|
+
export const parse = (language, type, sourceText) => {
|
|
99
34
|
return new TemplateParser(language, [sourceText], []).eval({
|
|
100
35
|
language: language.name,
|
|
101
36
|
type,
|
|
102
37
|
});
|
|
103
38
|
};
|
|
104
39
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return miniNode.map((node) => getAgASTValue(node));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const { language: languageName, type, attributes } = miniNode;
|
|
130
|
-
const flags = {
|
|
131
|
-
escape: !!miniNode.flags?.escape,
|
|
132
|
-
trivia: !!miniNode.flags?.trivia,
|
|
133
|
-
token: false,
|
|
134
|
-
hasGap: false,
|
|
135
|
-
};
|
|
136
|
-
const properties = {};
|
|
137
|
-
let children = [];
|
|
138
|
-
const resolver = new PathResolver(miniNode);
|
|
139
|
-
const resolvedLanguage =
|
|
140
|
-
languageName !== language.name ? language.dependencies[languageName] : language;
|
|
141
|
-
|
|
142
|
-
if (languageName.startsWith('https://')) {
|
|
143
|
-
return miniNode; // This node is already processed, possibly because it was interpolated
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (!resolvedLanguage) {
|
|
147
|
-
throw new Error();
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
type === 'Punctuator' ||
|
|
152
|
-
type === 'Keyword' ||
|
|
153
|
-
type === 'Identifier' ||
|
|
154
|
-
type === 'StringContent' ||
|
|
155
|
-
type === 'Escape' ||
|
|
156
|
-
miniNode.flags?.syntactic
|
|
157
|
-
) {
|
|
158
|
-
flags.token = true;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
children = btree.push(
|
|
162
|
-
children,
|
|
163
|
-
buildNodeOpenTag(flags, resolvedLanguage.canonicalURL, type, attributes),
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
for (const child of miniNode.children) {
|
|
167
|
-
if (child.type === OpenNodeTag || child.type === CloseNodeTag) {
|
|
168
|
-
continue;
|
|
169
|
-
} else if (child.type === ReferenceTag) {
|
|
170
|
-
const path = child.value;
|
|
171
|
-
const { name, isArray } = path;
|
|
172
|
-
let node = resolver.get(child.value);
|
|
173
|
-
|
|
174
|
-
if (node === undefined) throw new Error();
|
|
175
|
-
|
|
176
|
-
const agASTNode = node === null ? buildGapNode() : getAgASTValue(resolvedLanguage, node);
|
|
177
|
-
|
|
178
|
-
if (isArray && !hasOwn(properties, name)) {
|
|
179
|
-
const newRef = { type: ReferenceTag, value: { name, isArray } };
|
|
180
|
-
const arrayTag = { type: ArrayTag, value: undefined };
|
|
181
|
-
|
|
182
|
-
children = btree.push(children, newRef);
|
|
183
|
-
children = btree.push(children, arrayTag);
|
|
184
|
-
|
|
185
|
-
add(properties, { name }, []);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
add(properties, path, agASTNode);
|
|
189
|
-
children = btree.push(children, { type: ReferenceTag, value: { name, isArray } });
|
|
190
|
-
} else if (child.type === Trivia) {
|
|
191
|
-
children = btree.push(children, {
|
|
192
|
-
type: EmbeddedNode,
|
|
193
|
-
value: getAgASTValue(
|
|
194
|
-
resolvedLanguage,
|
|
195
|
-
buildTriviaNode(languageName, 'Space', [buildLiteralTag(child.value)]),
|
|
196
|
-
),
|
|
197
|
-
});
|
|
198
|
-
} else if (child.type === Escape) {
|
|
199
|
-
const { cooked, raw } = child.value;
|
|
200
|
-
const attributes = { cooked };
|
|
201
|
-
|
|
202
|
-
children = btree.push(children, {
|
|
203
|
-
type: EmbeddedNode,
|
|
204
|
-
value: getAgASTValue(
|
|
205
|
-
resolvedLanguage,
|
|
206
|
-
buildSyntacticEscapeNode(languageName, 'Escape', [buildLiteralTag(raw)], {}, attributes),
|
|
207
|
-
),
|
|
208
|
-
});
|
|
209
|
-
} else {
|
|
210
|
-
if (child.type === ArrayTag) throw new Error('badbad');
|
|
211
|
-
children = btree.push(children, child);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
children = btree.push(children, buildNodeCloseTag());
|
|
216
|
-
|
|
217
|
-
return { flags, language: resolvedLanguage.canonicalURL, type, children, properties, attributes };
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const str = buildTag(cstml, 'String');
|
|
221
|
-
const num = buildTag(cstml, 'Integer');
|
|
222
|
-
const cst = buildTag(cstml, 'Node');
|
|
223
|
-
const spam = buildTag(spamex, 'Matcher');
|
|
224
|
-
const re = buildTag(regex, 'Pattern');
|
|
225
|
-
const i = buildTag(instruction, 'Call');
|
|
226
|
-
|
|
227
|
-
module.exports = {
|
|
228
|
-
str,
|
|
229
|
-
num,
|
|
230
|
-
cst,
|
|
231
|
-
spam,
|
|
232
|
-
re,
|
|
233
|
-
i,
|
|
234
|
-
buildTag,
|
|
235
|
-
get,
|
|
236
|
-
add,
|
|
237
|
-
getAgASTValue,
|
|
238
|
-
TemplateParser,
|
|
239
|
-
Resolver,
|
|
240
|
-
parse,
|
|
241
|
-
};
|
|
40
|
+
export const str = buildTag(cstmll, 'String');
|
|
41
|
+
export const num = buildTag(cstmll, 'Integer');
|
|
42
|
+
export const cst = buildTag(cstmll, 'Node');
|
|
43
|
+
export const cstml = cst;
|
|
44
|
+
export const spam_ = buildTag(spamex, 'Matcher');
|
|
45
|
+
export const re_ = buildTag(regex, 'Pattern');
|
|
46
|
+
export const i = buildTag(instruction, 'Call');
|
|
47
|
+
|
|
48
|
+
export const spam = new Proxy(spam_, {
|
|
49
|
+
apply(tag, _, args) {
|
|
50
|
+
return buildEmbeddedMatcher(tag(...args));
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const re = new Proxy(re_, {
|
|
55
|
+
apply(tag, _, args) {
|
|
56
|
+
return buildEmbeddedRegex(tag(...args));
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export { TemplateParser, Resolver };
|