@bablr/agast-helpers 0.3.2 → 0.4.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/btree.js ADDED
@@ -0,0 +1 @@
1
+ export * from '@bablr/btree';
package/lib/builders.js CHANGED
@@ -1,4 +1,20 @@
1
1
  import * as sym from './symbols.js';
2
+ import * as btree from './btree.js';
3
+ import {
4
+ DoctypeTag,
5
+ OpenNodeTag,
6
+ CloseNodeTag,
7
+ ReferenceTag,
8
+ ShiftTag,
9
+ GapTag,
10
+ NullTag,
11
+ ArrayTag,
12
+ LiteralTag,
13
+ EmbeddedNode,
14
+ EmbeddedExpression,
15
+ EmbeddedTag,
16
+ TokenGroup,
17
+ } from './symbols.js';
2
18
 
3
19
  const { freeze } = Object;
4
20
 
@@ -6,11 +22,11 @@ const isObject = (val) => val !== null && typeof value !== 'object';
6
22
 
7
23
  export const buildEmbeddedExpression = (expr) => {
8
24
  if (!isObject(expr)) return expr;
9
- return freeze({ type: 'EmbeddedExpression', value: expr });
25
+ return freeze({ type: EmbeddedExpression, value: expr });
10
26
  };
11
27
 
12
28
  export const buildEmbeddedTag = (tag) => {
13
- return freeze({ type: 'EmbeddedTag', value: tag });
29
+ return freeze({ type: EmbeddedTag, value: tag });
14
30
  };
15
31
 
16
32
  export const buildEffect = (value) => {
@@ -48,7 +64,7 @@ export const buildAnsiPopEffect = () => {
48
64
  };
49
65
 
50
66
  export const buildTokenGroup = (tokens) => {
51
- return freeze({ type: 'TokenGroup', value: tokens });
67
+ return freeze({ type: TokenGroup, value: tokens });
52
68
  };
53
69
 
54
70
  export const buildCall = (verb, ...args) => {
@@ -59,29 +75,33 @@ export const buildBeginningOfStreamToken = () => {
59
75
  return freeze({ type: Symbol.for('@bablr/beginning-of-stream'), value: undefined });
60
76
  };
61
77
 
62
- export const buildReference = (name, isArray) => {
63
- return freeze({ type: 'Reference', value: freeze({ name, isArray }) });
78
+ export const buildReferenceTag = (name, isArray = false) => {
79
+ return freeze({ type: ReferenceTag, value: freeze({ name, isArray }) });
64
80
  };
65
81
 
66
- export const buildNull = () => {
67
- return freeze({ type: 'Null', value: undefined });
82
+ export const buildNullTag = () => {
83
+ return freeze({ type: NullTag, value: undefined });
68
84
  };
69
85
 
70
- export const buildGap = () => {
71
- return freeze({ type: 'Gap', value: undefined });
86
+ export const buildArrayTag = () => {
87
+ return freeze({ type: ArrayTag, value: undefined });
72
88
  };
73
89
 
74
- export const buildShift = () => {
75
- return freeze({ type: 'Shift', value: undefined });
90
+ export const buildGapTag = () => {
91
+ return freeze({ type: GapTag, value: undefined });
92
+ };
93
+
94
+ export const buildShiftTag = () => {
95
+ return freeze({ type: ShiftTag, value: undefined });
76
96
  };
77
97
 
78
98
  export const buildEmbeddedNode = (node) => {
79
- return freeze({ type: 'EmbeddedNode', value: node });
99
+ return freeze({ type: EmbeddedNode, value: node });
80
100
  };
81
101
 
82
102
  export const buildDoctypeTag = (attributes) => {
83
103
  return freeze({
84
- type: 'DoctypeTag',
104
+ type: DoctypeTag,
85
105
  value: { doctype: 'cstml', version: 0, attributes: freeze(attributes) },
86
106
  });
87
107
  };
@@ -96,7 +116,7 @@ export const buildNodeOpenTag = (flags = {}, language = null, type = null, attri
96
116
  intrinsic = !!intrinsic;
97
117
 
98
118
  return freeze({
99
- type: 'OpenNodeTag',
119
+ type: OpenNodeTag,
100
120
  value: freeze({
101
121
  flags: freeze({ token, trivia, escape, intrinsic, expression }),
102
122
  language,
@@ -107,14 +127,14 @@ export const buildNodeOpenTag = (flags = {}, language = null, type = null, attri
107
127
  };
108
128
 
109
129
  export const buildNodeCloseTag = (type = null, language = null) => {
110
- return freeze({ type: 'CloseNodeTag', value: freeze({ language, type }) });
130
+ return freeze({ type: CloseNodeTag, value: freeze({ language, type }) });
111
131
  };
112
132
 
113
133
  const isString = (val) => typeof val === 'string';
114
134
 
115
- export const buildLiteral = (value) => {
135
+ export const buildLiteralTag = (value) => {
116
136
  if (!isString(value)) throw new Error('invalid literal');
117
- return freeze({ type: 'Literal', value });
137
+ return freeze({ type: LiteralTag, value });
118
138
  };
119
139
 
120
140
  export const buildNodeWithFlags = (
@@ -124,15 +144,19 @@ export const buildNodeWithFlags = (
124
144
  children = [],
125
145
  properties = {},
126
146
  attributes = {},
127
- ) =>
128
- freeze({
147
+ ) => {
148
+ const openTag = buildNodeOpenTag(nodeFlags, language, type, attributes);
149
+ const closeTag = buildNodeCloseTag(type);
150
+
151
+ return freeze({
129
152
  flags,
130
153
  language,
131
154
  type,
132
- children: freeze(children),
155
+ children: btree.addAt(0, btree.addAt(btree.getSum(children), children, closeTag), openTag),
133
156
  properties: freeze(properties),
134
157
  attributes: freeze(attributes),
135
158
  });
159
+ };
136
160
 
137
161
  export const nodeFlags = freeze({
138
162
  token: false,
@@ -142,15 +166,9 @@ export const nodeFlags = freeze({
142
166
  expression: false,
143
167
  });
144
168
 
145
- export const buildNode = (language, type, children = [], properties = {}, attributes = {}) =>
146
- freeze({
147
- flags: nodeFlags,
148
- language,
149
- type,
150
- children: freeze(children),
151
- properties: freeze(properties),
152
- attributes: freeze(attributes),
153
- });
169
+ export const buildNode = (language, type, children = [], properties = {}, attributes = {}) => {
170
+ return buildNodeWithFlags(nodeFlags, language, type, children, properties, attributes);
171
+ };
154
172
 
155
173
  export const syntacticFlags = freeze({
156
174
  token: true,
@@ -160,15 +178,16 @@ export const syntacticFlags = freeze({
160
178
  expression: false,
161
179
  });
162
180
 
163
- export const buildSyntacticNode = (language, type, value, attributes = {}) =>
164
- freeze({
165
- flags: syntacticFlags,
181
+ export const buildSyntacticNode = (language, type, value, attributes = {}) => {
182
+ return buildNodeWithFlags(
183
+ syntacticFlags,
166
184
  language,
167
185
  type,
168
- children: [buildLiteral(value)],
169
- properties: freeze({}),
170
- attributes: freeze(attributes),
171
- });
186
+ [buildLiteralTag(value)],
187
+ {},
188
+ attributes,
189
+ );
190
+ };
172
191
 
173
192
  export const syntacticIntrinsicFlags = freeze({
174
193
  token: true,
@@ -177,15 +196,16 @@ export const syntacticIntrinsicFlags = freeze({
177
196
  intrinsic: true,
178
197
  expression: false,
179
198
  });
180
- export const buildSyntacticIntrinsicNode = (language, type, value, attributes = {}) =>
181
- freeze({
182
- flags: syntacticIntrinsicFlags,
199
+ export const buildSyntacticIntrinsicNode = (language, type, value, attributes = {}) => {
200
+ return buildNodeWithFlags(
201
+ syntacticIntrinsicFlags,
183
202
  language,
184
203
  type,
185
- children: [buildLiteral(value)],
186
- properties: freeze({}),
187
- attributes: freeze(attributes),
188
- });
204
+ [buildLiteralTag(value)],
205
+ {},
206
+ attributes,
207
+ );
208
+ };
189
209
 
190
210
  export const escapeFlags = freeze({
191
211
  token: false,
@@ -195,15 +215,15 @@ export const escapeFlags = freeze({
195
215
  expression: false,
196
216
  });
197
217
 
198
- export const buildEscapeNode = (language, type, children = [], properties = {}, attributes = {}) =>
199
- freeze({
200
- flags: escapeFlags,
201
- language,
202
- type,
203
- children: freeze(children),
204
- properties: freeze(properties),
205
- attributes: freeze(attributes),
206
- });
218
+ export const buildEscapeNode = (
219
+ language,
220
+ type,
221
+ children = [],
222
+ properties = {},
223
+ attributes = {},
224
+ ) => {
225
+ return buildNodeWithFlags(escapeFlags, language, type, children, properties, attributes);
226
+ };
207
227
 
208
228
  export const syntacticEscapeFlags = freeze({
209
229
  token: true,
@@ -219,15 +239,9 @@ export const buildSyntacticEscapeNode = (
219
239
  children = [],
220
240
  properties = {},
221
241
  attributes = {},
222
- ) =>
223
- freeze({
224
- flags: syntacticEscapeFlags,
225
- language,
226
- type,
227
- children: freeze(children),
228
- properties: freeze(properties),
229
- attributes: freeze(attributes),
230
- });
242
+ ) => {
243
+ return buildNodeWithFlags(syntacticEscapeFlags, language, type, children, properties, attributes);
244
+ };
231
245
 
232
246
  export const syntacticTriviaFlags = freeze({
233
247
  token: true,
@@ -243,15 +257,9 @@ export const buildSyntacticTriviaNode = (
243
257
  children = [],
244
258
  properties = {},
245
259
  attributes = {},
246
- ) =>
247
- freeze({
248
- flags: syntacticTriviaFlags,
249
- language,
250
- type,
251
- children: freeze(children),
252
- properties: freeze(properties),
253
- attributes: freeze(attributes),
254
- });
260
+ ) => {
261
+ return buildNodeWithFlags(syntacticTriviaFlags, language, type, children, properties, attributes);
262
+ };
255
263
 
256
264
  export const triviaFlags = freeze({
257
265
  token: false,
@@ -261,22 +269,33 @@ export const triviaFlags = freeze({
261
269
  expression: false,
262
270
  });
263
271
 
264
- export const buildTriviaNode = (language, type, children = [], properties = {}, attributes = {}) =>
265
- freeze({
266
- flags: triviaFlags,
267
- language,
268
- type,
269
- children: freeze(children),
270
- properties: freeze(properties),
271
- attributes: freeze(attributes),
272
- });
272
+ export const buildTriviaNode = (
273
+ language,
274
+ type,
275
+ children = [],
276
+ properties = {},
277
+ attributes = {},
278
+ ) => {
279
+ return buildNodeWithFlags(triviaFlags, language, type, children, properties, attributes);
280
+ };
273
281
 
274
- export const buildNullNode = () => {
282
+ export const buildNullNode = (nullToken = buildNullTag()) => {
275
283
  return freeze({
276
284
  flags: nodeFlags,
277
285
  language: null,
278
286
  type: sym.null,
279
- children: freeze([buildNull()]),
287
+ children: btree.freeze([nullToken]),
288
+ properties: freeze({}),
289
+ attributes: freeze({}),
290
+ });
291
+ };
292
+
293
+ export const buildGapNode = (gapToken = buildGapTag()) => {
294
+ return freeze({
295
+ flags: nodeFlags,
296
+ language: null,
297
+ type: sym.gap,
298
+ children: btree.freeze([gapToken]),
280
299
  properties: freeze({}),
281
300
  attributes: freeze({}),
282
301
  });
package/lib/path.js CHANGED
@@ -4,7 +4,7 @@ export const parsePath = (str) => {
4
4
 
5
5
  if (!/^[a-zA-Z]+$/.test(name)) throw new Error();
6
6
 
7
- return { isArray, name };
7
+ return { name, isArray };
8
8
  };
9
9
 
10
10
  export const printPath = (path) => {
package/lib/print.js CHANGED
@@ -1,3 +1,18 @@
1
+ import {
2
+ DoctypeTag,
3
+ OpenNodeTag,
4
+ CloseNodeTag,
5
+ ReferenceTag,
6
+ ShiftTag,
7
+ GapTag,
8
+ NullTag,
9
+ ArrayTag,
10
+ LiteralTag,
11
+ EmbeddedNode,
12
+ EmbeddedTag,
13
+ EmbeddedExpression,
14
+ } from './symbols.js';
15
+
1
16
  const { isInteger, isFinite } = Number;
2
17
  const { isArray } = Array;
3
18
  const isString = (val) => typeof val === 'string';
@@ -13,14 +28,14 @@ export const printCall = (call) => {
13
28
  return `${verb}${printTuple(args)}`;
14
29
  };
15
30
 
16
- export const printArray = (arr) => `[${arr.map((v) => printExpression(v)).join(', ')}]`;
31
+ export const printArray = (arr) => `[${arr.map((v) => printExpression(v)).join(' ')}]`;
17
32
 
18
- export const printTuple = (tup) => `(${tup.map((v) => printExpression(v)).join(', ')})`;
33
+ export const printTuple = (tup) => `(${tup.map((v) => printExpression(v)).join(' ')})`;
19
34
 
20
35
  export const printObject = (obj) => {
21
36
  const entries = Object.entries(obj);
22
37
  return entries.length
23
- ? `{ ${entries.map(([k, v]) => `${k}: ${printExpression(v)}`).join(', ')} }`
38
+ ? `{ ${entries.map(([k, v]) => `${k}: ${printExpression(v)}`).join(' ')} }`
24
39
  : '{}';
25
40
  };
26
41
 
@@ -49,14 +64,14 @@ export const printExpression = (expr) => {
49
64
 
50
65
  export const printEmbedded = (value) => {
51
66
  switch (value.type) {
52
- case 'EmbeddedTag':
53
- return printTerminal(value.value);
67
+ case EmbeddedTag:
68
+ return printTag(value.value);
54
69
 
55
- case 'EmbeddedExpression': {
70
+ case EmbeddedExpression: {
56
71
  return printObject(value.value);
57
72
  }
58
73
 
59
- case 'EmbeddedNode': {
74
+ case EmbeddedNode: {
60
75
  throw new Error('not implemented');
61
76
  break;
62
77
  }
@@ -83,7 +98,7 @@ export const printLanguage = (language) => {
83
98
  export const printTagPath = (language, type) => {
84
99
  return [
85
100
  ...when(type && language?.length, () => [printLanguage(language)]),
86
- ...when(type, [type]),
101
+ ...when(type, [printType(type)]),
87
102
  ].join(':');
88
103
  };
89
104
 
@@ -115,29 +130,35 @@ export const printString = (str) => {
115
130
  return str === "'" ? printDoubleString(str) : printSingleString(str);
116
131
  };
117
132
 
118
- export const printGap = (terminal) => {
119
- if (terminal?.type !== 'Gap') throw new Error();
133
+ export const printGapTag = (tag) => {
134
+ if (tag?.type !== GapTag) throw new Error();
120
135
 
121
136
  return `<//>`;
122
137
  };
123
138
 
124
- export const printShift = (terminal) => {
125
- if (terminal?.type !== 'Shift') throw new Error();
139
+ export const printArrayTag = (tag) => {
140
+ if (tag?.type !== ArrayTag) throw new Error();
141
+
142
+ return `[]`;
143
+ };
144
+
145
+ export const printShiftTag = (tag) => {
146
+ if (tag?.type !== ShiftTag) throw new Error();
126
147
 
127
148
  return `^^^`;
128
149
  };
129
150
 
130
- export const printReference = (terminal) => {
131
- if (terminal?.type !== 'Reference') throw new Error();
151
+ export const printReferenceTag = (tag) => {
152
+ if (tag?.type !== ReferenceTag) throw new Error();
132
153
 
133
- const { name, isArray } = terminal.value;
154
+ const { name, isArray } = tag.value;
134
155
  const pathBraces = isArray ? '[]' : '';
135
156
 
136
157
  return `${name}${pathBraces}:`;
137
158
  };
138
159
 
139
- export const printNull = (terminal) => {
140
- if (terminal && terminal.type !== 'Null') {
160
+ export const printNullTag = (tag) => {
161
+ if (tag && tag.type !== NullTag) {
141
162
  throw new Error();
142
163
  }
143
164
 
@@ -148,14 +169,14 @@ export const printType = (type) => {
148
169
  return typeof type === 'string'
149
170
  ? type
150
171
  : typeof type === 'symbol'
151
- ? `$${type.description.replace('@bablr/', '')}`
172
+ ? type.description.replace('@bablr/', '')
152
173
  : String(type);
153
174
  };
154
175
 
155
- export const printDoctypeTag = (terminal) => {
156
- if (terminal?.type !== 'DoctypeTag') throw new Error();
176
+ export const printDoctypeTag = (tag) => {
177
+ if (tag?.type !== DoctypeTag) throw new Error();
157
178
 
158
- let { doctype, version, attributes } = terminal.value;
179
+ let { doctype, version, attributes } = tag.value;
159
180
 
160
181
  attributes =
161
182
  attributes && Object.values(attributes).length ? ` ${printAttributes(attributes)}` : '';
@@ -163,10 +184,10 @@ export const printDoctypeTag = (terminal) => {
163
184
  return `<!${version}:${doctype}${attributes}>`;
164
185
  };
165
186
 
166
- export const printLiteral = (terminal) => {
167
- if (terminal?.type !== 'Literal') throw new Error();
187
+ export const printLiteralTag = (tag) => {
188
+ if (tag?.type !== LiteralTag) throw new Error();
168
189
 
169
- return printString(terminal.value);
190
+ return printString(tag.value);
170
191
  };
171
192
 
172
193
  export const printFlags = (flags) => {
@@ -181,10 +202,10 @@ export const printFlags = (flags) => {
181
202
  return `${hash}${tilde}${star}${at}${plus}`;
182
203
  };
183
204
 
184
- export const printOpenNodeTag = (terminal) => {
185
- if (terminal?.type !== 'OpenNodeTag') throw new Error();
205
+ export const printOpenNodeTag = (tag) => {
206
+ if (tag?.type !== OpenNodeTag) throw new Error();
186
207
 
187
- const { flags, language: tagLanguage, type, attributes } = terminal.value;
208
+ const { flags, language: tagLanguage, type, attributes } = tag.value;
188
209
 
189
210
  const printedAttributes = attributes && printAttributes(attributes);
190
211
  const attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
@@ -192,10 +213,10 @@ export const printOpenNodeTag = (terminal) => {
192
213
  return `<${printFlags(flags)}${printTagPath(tagLanguage, type)}${attributesFrag}>`;
193
214
  };
194
215
 
195
- export const printSelfClosingNodeTag = (terminal, intrinsicValue) => {
196
- if (terminal?.type !== 'OpenNodeTag') throw new Error();
216
+ export const printSelfClosingNodeTag = (tag, intrinsicValue) => {
217
+ if (tag?.type !== OpenNodeTag) throw new Error();
197
218
 
198
- const { flags, language: tagLanguage, type, attributes } = terminal.value;
219
+ const { flags, language: tagLanguage, type, attributes } = tag.value;
199
220
 
200
221
  const printedAttributes = attributes && printAttributes(attributes);
201
222
  const attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
@@ -207,39 +228,42 @@ export const printSelfClosingNodeTag = (terminal, intrinsicValue) => {
207
228
  )}${intrinsicFrag}${attributesFrag} />`;
208
229
  };
209
230
 
210
- export const printCloseNodeTag = (terminal) => {
211
- if (terminal?.type !== 'CloseNodeTag') throw new Error();
231
+ export const printCloseNodeTag = (tag) => {
232
+ if (tag?.type !== CloseNodeTag) throw new Error();
212
233
 
213
234
  return `</>`;
214
235
  };
215
236
 
216
- export const printTerminal = (terminal) => {
217
- if (!isObject(terminal)) throw new Error();
237
+ export const printTag = (tag) => {
238
+ if (!isObject(tag)) throw new Error();
239
+
240
+ switch (tag?.type || NullTag) {
241
+ case NullTag:
242
+ return printNullTag(tag);
218
243
 
219
- switch (terminal?.type || 'Null') {
220
- case 'Null':
221
- return printNull(terminal);
244
+ case GapTag:
245
+ return printGapTag(tag);
222
246
 
223
- case 'Gap':
224
- return printGap(terminal);
247
+ case ArrayTag:
248
+ return printArrayTag(tag);
225
249
 
226
- case 'Shift':
227
- return printShift(terminal);
250
+ case ShiftTag:
251
+ return printShiftTag(tag);
228
252
 
229
- case 'Literal':
230
- return printLiteral(terminal);
253
+ case LiteralTag:
254
+ return printLiteralTag(tag);
231
255
 
232
- case 'DoctypeTag':
233
- return printDoctypeTag(terminal);
256
+ case DoctypeTag:
257
+ return printDoctypeTag(tag);
234
258
 
235
- case 'Reference':
236
- return printReference(terminal);
259
+ case ReferenceTag:
260
+ return printReferenceTag(tag);
237
261
 
238
- case 'OpenNodeTag':
239
- return printOpenNodeTag(terminal);
262
+ case OpenNodeTag:
263
+ return printOpenNodeTag(tag);
240
264
 
241
- case 'CloseNodeTag':
242
- return printCloseNodeTag(terminal);
265
+ case CloseNodeTag:
266
+ return printCloseNodeTag(tag);
243
267
 
244
268
  default:
245
269
  throw new Error();
package/lib/shorthand.js CHANGED
@@ -1,18 +1,20 @@
1
1
  import {
2
- buildReference,
3
- buildGap,
2
+ buildReferenceTag,
3
+ buildGapTag,
4
4
  buildEmbeddedNode,
5
5
  buildNodeOpenTag,
6
6
  buildNodeCloseTag,
7
- buildLiteral,
7
+ buildLiteralTag,
8
+ buildNullNode,
9
+ buildArrayTag,
8
10
  buildNode,
11
+ buildGapNode,
9
12
  buildSyntacticNode,
10
13
  buildSyntacticIntrinsicNode,
11
14
  buildEscapeNode,
12
15
  buildSyntacticEscapeNode,
13
16
  buildSyntacticTriviaNode,
14
17
  buildTriviaNode,
15
- buildNullNode,
16
18
  } from './builders.js';
17
19
 
18
20
  export * from './builders.js';
@@ -34,20 +36,22 @@ export const ref = (path) => {
34
36
  if (isArray(path)) {
35
37
  const pathIsArray = path[0].endsWith('[]');
36
38
  const name = pathIsArray ? path[0].slice(0, -2) : path[0];
37
- return buildReference(name, pathIsArray);
39
+ return buildReferenceTag(name, pathIsArray);
38
40
  } else {
39
41
  const { name, isArray: pathIsArray } = path;
40
- return buildReference(name, pathIsArray);
42
+ return buildReferenceTag(name, pathIsArray);
41
43
  }
42
44
  };
43
45
 
44
- export const lit = (str) => buildLiteral(stripArray(str));
46
+ export const lit = (str) => buildLiteralTag(stripArray(str));
45
47
 
46
- export const gap = buildGap;
48
+ export const gap = buildGapTag;
49
+ export const arr = buildArrayTag;
47
50
  export const embedded = buildEmbeddedNode;
48
51
  export const nodeOpen = buildNodeOpenTag;
49
52
  export const nodeClose = buildNodeCloseTag;
50
53
  export const node = buildNode;
54
+ export const g_node = buildGapNode;
51
55
  export const s_node = buildSyntacticNode;
52
56
  export const s_i_node = buildSyntacticIntrinsicNode;
53
57
  export const e_node = buildEscapeNode;