@bablr/boot 0.6.3 → 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 CHANGED
@@ -1,79 +1,17 @@
1
- const { PathResolver } = require('@bablr/boot-helpers/path');
2
- const cstml = require('./languages/cstml.js');
3
- const spamex = require('./languages/spamex.js');
4
- const regex = require('./languages/regex.js');
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
- const { isArray } = Array;
33
- const { hasOwn } = Object;
6
+ import { TemplateParser } from './miniparser.js';
7
+ import { Resolver, buildEmbeddedMatcher, buildEmbeddedRegex } from '@bablr/agast-helpers/tree';
34
8
 
35
- const get = (node, path) => {
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 getAgASTTree(
71
- language,
72
- new TemplateParser(language, quasis.raw, exprs).eval({
73
- language: language.name,
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 getAgASTTree(
87
- language,
88
- new TemplateParser(language, quasis.raw, exprs).eval({
89
- language: language.name,
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 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
-
122
- const getAgASTValue = (language, miniNode) => {
123
- if (!miniNode) return miniNode;
124
-
125
- if (isArray(miniNode)) {
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 };