@bablr/agast-helpers 0.8.0 → 0.10.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/print.js CHANGED
@@ -6,22 +6,18 @@ import {
6
6
  ShiftTag,
7
7
  GapTag,
8
8
  NullTag,
9
- InitializerTag,
10
9
  LiteralTag,
11
10
  AttributeDefinition,
12
11
  BindingTag,
13
12
  } from './symbols.js';
14
- import { referenceFlags } from './tree.js';
13
+ import { referenceFlags } from './builders.js';
15
14
 
16
15
  let { isInteger, isFinite } = Number;
17
16
  let { isArray } = Array;
17
+ let { freeze } = Object;
18
18
  let isString = (val) => typeof val === 'string';
19
19
  let isNumber = (val) => typeof val === 'number';
20
20
  let isObject = (val) => val && typeof val === 'object' && !isArray(val);
21
- let isFunction = (val) => typeof val === 'function';
22
-
23
- let when = (condition, value) =>
24
- condition ? (isFunction(value) ? value() : value) : { *[Symbol.iterator]() {} };
25
21
 
26
22
  export const printArray = (arr) => `[${arr.map((v) => printExpression(v)).join(', ')}]`;
27
23
 
@@ -61,7 +57,20 @@ export const printAttributes = (attributes) => {
61
57
  };
62
58
 
63
59
  export const printIdentifierPath = (path) => {
64
- return path.map(printIdentifier).join('.');
60
+ return path
61
+ .map((segment) => {
62
+ let { name, type } = segment;
63
+ if (name) {
64
+ return printIdentifier(name);
65
+ }
66
+ if (type) {
67
+ if (type !== '..') throw new Error();
68
+ return type;
69
+ } else {
70
+ throw new Error();
71
+ }
72
+ })
73
+ .join('.');
65
74
  };
66
75
 
67
76
  let escapeReplacer = (esc) => {
@@ -81,7 +90,7 @@ let escapeReplacer = (esc) => {
81
90
  };
82
91
 
83
92
  export const printIdentifier = (id) => {
84
- return /^[a-zA-Z\u{80}-\u{10ffff}][a-zA-Z\u{80}-\u{10ffff}0-9_-]+$/u.test(id)
93
+ return /^[a-zA-Z\u{80}-\u{10ffff}][a-zA-Z\u{80}-\u{10ffff}0-9_-]*$/u.test(id)
85
94
  ? id
86
95
  : `\`${id
87
96
  .replace(/[`\\]/g, '\\`')
@@ -106,37 +115,46 @@ export const printGapTag = (tag) => {
106
115
  return `<//>`;
107
116
  };
108
117
 
109
- export const printInitializerTag = (tag) => {
110
- if (tag?.type !== InitializerTag) throw new Error();
111
-
112
- if (tag.value.isArray) {
113
- return `[]`;
114
- } else {
115
- return 'undefined';
116
- }
117
- };
118
-
119
118
  export const printShiftTag = (tag) => {
120
119
  if (tag?.type !== ShiftTag) throw new Error();
121
120
 
122
121
  return `^^^`;
123
122
  };
124
123
 
125
- export const printReferenceTag = (tag) => {
126
- if (tag?.type !== ReferenceTag) throw new Error();
124
+ export const printReference = (ref) => {
125
+ let { type, name, flags } = ref;
126
+
127
+ if (type && type !== '#' && name) throw new Error();
128
+ if (type && !['_', '.', '#', '@'].includes(type)) throw new Error();
129
+
130
+ return `${type || ''}${printIdentifier(name) || ''}${printReferenceFlags(flags)}:`;
131
+ };
127
132
 
128
- let { type, name, isArray, flags } = tag.value;
129
- let pathBraces = isArray ? `[]` : '';
133
+ export const printBinding = (binding) => {
134
+ let { segments } = binding;
135
+ return `:${
136
+ segments.length ? segments.map((segment) => printBindingSegment(segment)).join('/') : ''
137
+ }:`;
138
+ };
130
139
 
131
- if (type && name) throw new Error();
132
- if (type && !['.', '#', '@'].includes(type)) throw new Error();
140
+ export const printBindingSegment = (segment) => {
141
+ let { type, name } = segment;
142
+ if (type) {
143
+ if (type !== '..') throw new Error();
144
+ return type;
145
+ } else if (name) {
146
+ return printIdentifier(name);
147
+ } else {
148
+ throw new Error();
149
+ }
150
+ };
133
151
 
134
- return `${type || printIdentifier(name) || ''}${pathBraces}${printReferenceFlags(flags)}:`;
152
+ export const printReferenceTag = (tag) => {
153
+ return printReference(tag.value);
135
154
  };
136
155
 
137
156
  export const printBindingTag = (tag) => {
138
- let { languagePath } = tag.value;
139
- return `:${languagePath ? printIdentifierPath(languagePath) : ''}:`;
157
+ return printBinding(tag.value);
140
158
  };
141
159
 
142
160
  export const printNullTag = (tag) => {
@@ -147,7 +165,7 @@ export const printNullTag = (tag) => {
147
165
  return 'null';
148
166
  };
149
167
 
150
- export const printType = (type) => {
168
+ export const printName = (type) => {
151
169
  return typeof type === 'string'
152
170
  ? type
153
171
  : typeof type === 'symbol'
@@ -155,6 +173,10 @@ export const printType = (type) => {
155
173
  : String(type);
156
174
  };
157
175
 
176
+ export const printType = (type) => {
177
+ return typeof type === 'symbol' ? type.description : String(type);
178
+ };
179
+
158
180
  export const printDoctypeTag = (tag) => {
159
181
  if (tag?.type !== DoctypeTag) throw new Error();
160
182
 
@@ -173,45 +195,58 @@ export const printLiteralTag = (tag) => {
173
195
  };
174
196
 
175
197
  export const printReferenceFlags = (flags = referenceFlags) => {
198
+ let array = flags.array ? `[]` : '';
176
199
  let plus = flags.expression ? '+' : '';
200
+ let star = flags.intrinsic ? '*' : '';
177
201
  let dollar = flags.hasGap ? '$' : '';
178
202
 
179
- return `${plus}${dollar}`;
203
+ return `${array}${plus}${star}${dollar}`;
180
204
  };
181
205
 
182
206
  export const printNodeFlags = (flags) => {
183
- if (flags.cover && !flags.fragment) throw new Error();
184
207
  let star = flags.token ? '*' : '';
185
208
  let dollar = flags.hasGap ? '$' : '';
186
209
 
187
210
  return `${star}${dollar}`;
188
211
  };
189
212
 
213
+ export const printNodeType = (type) => {
214
+ if (![Symbol.for('_'), Symbol.for('__')].includes(type)) throw new Error();
215
+
216
+ return type.description;
217
+ };
218
+
190
219
  export const printOpenNodeTag = (tag) => {
191
220
  if (tag?.type !== OpenNodeTag) throw new Error();
192
221
 
193
- let { flags, type, attributes } = tag.value;
222
+ let { flags, type, name, literalValue, attributes, selfClosing } = tag.value;
194
223
 
195
- if (!type) {
196
- return `<${printNodeFlags(flags)}_>`;
197
- }
224
+ if (literalValue && !selfClosing) throw new Error();
225
+ let selfClosingFrag = selfClosing ? ' /' : '';
226
+ let literalFrag = literalValue ? ` ${printString(literalValue)}` : '';
198
227
 
199
228
  let printedAttributes = printAttributes(attributes);
200
229
  let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
230
+ let typeFrag = type ? printNodeType(type) : '';
231
+ let nameFrag = name ? printType(name) : '';
201
232
 
202
- return `<${printNodeFlags(flags)}${printType(type)}${attributesFrag}>`;
233
+ return `<${printNodeFlags(
234
+ flags,
235
+ )}${typeFrag}${nameFrag}${literalFrag}${attributesFrag}${selfClosingFrag}>`;
203
236
  };
204
237
 
205
- export const printSelfClosingNodeTag = (tag, intrinsicValue) => {
238
+ export const printSelfClosingNodeTag = (tag, literalValue) => {
206
239
  if (tag?.type !== OpenNodeTag) throw new Error();
207
240
 
208
- let { flags, type, attributes } = tag.value;
241
+ let { flags, type, name, attributes } = tag.value;
209
242
 
210
243
  let printedAttributes = printAttributes(attributes);
211
244
  let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
212
- let intrinsicFrag = intrinsicValue ? ` ${printString(intrinsicValue)}` : '';
245
+ let literalFrag = literalValue ? ` ${printString(literalValue)}` : '';
246
+ let typeFrag = type ? printNodeType(type) : '';
247
+ let nameFrag = name ? printType(name) : '';
213
248
 
214
- return `<${printNodeFlags(flags)}${printType(type)}${intrinsicFrag}${attributesFrag} />`;
249
+ return `<${printNodeFlags(flags)}${typeFrag}${nameFrag}${literalFrag}${attributesFrag} />`;
215
250
  };
216
251
 
217
252
  export const printCloseNodeTag = (tag) => {
@@ -222,16 +257,18 @@ export const printCloseNodeTag = (tag) => {
222
257
 
223
258
  export const printAttributeDefinition = (tag) => {
224
259
  if (tag?.type !== AttributeDefinition) throw new Error();
260
+ if (!tag.value.path?.length) throw new Error();
225
261
  let { path, value } = tag.value;
226
262
 
227
- return `{ ${printIdentifierPath(path)}: ${printExpression(value)} }`;
263
+ return `{ ${printIdentifierPath(
264
+ path.map((name) => freeze({ type: null, name })),
265
+ )}: ${printExpression(value)} }`;
228
266
  };
229
267
 
230
268
  const printers = {
231
269
  [NullTag]: printNullTag,
232
270
  [GapTag]: printGapTag,
233
271
  [BindingTag]: printBindingTag,
234
- [InitializerTag]: printInitializerTag,
235
272
  [ShiftTag]: printShiftTag,
236
273
  [LiteralTag]: printLiteralTag,
237
274
  [DoctypeTag]: printDoctypeTag,
package/lib/shorthand.js CHANGED
@@ -4,8 +4,10 @@ import {
4
4
  buildOpenNodeTag,
5
5
  buildCloseNodeTag,
6
6
  buildLiteralTag,
7
- buildInitializerTag,
7
+ buildOpenFragmentTag,
8
+ buildOpenCoverTag,
8
9
  } from './builders.js';
10
+ import { freeze } from './object.js';
9
11
  import { buildReferenceTag, treeFromStreamSync } from './tree.js';
10
12
 
11
13
  export * from './builders.js';
@@ -26,26 +28,27 @@ const stripArray = (val) => {
26
28
  export const parseReference = (str) => {
27
29
  let {
28
30
  1: type,
29
- 2: name,
30
- 3: isArray,
31
- 4: index,
31
+ 2: namedType,
32
+ 3: name,
33
+ 4: array,
32
34
  5: expressionToken,
33
- 6: hasGapToken,
34
- } = /^\s*(?:([.#@])|([a-zA-Z\u{80}-\u{10ffff}][a-zA-Z0-9_\u{80}-\u{10ffff}-]*))\s*(\[\s*(\d+\s*)?\])?\s*(\+)?(\$)?\s*$/u.exec(
35
+ 6: intrinsicToken,
36
+ 7: hasGapToken,
37
+ } = /^\s*(?:([.#@_])|(#)?([a-zA-Z\u{80}-\u{10ffff}][a-zA-Z0-9_\u{80}-\u{10ffff}-]*))\s*(\[\])?\s*(\+)?(\*)?(\$)?\s*$/u.exec(
35
38
  str,
36
39
  );
37
40
 
38
- let flags = {
41
+ let flags = freeze({
42
+ array: !!array,
39
43
  expression: !!expressionToken,
44
+ intrinsic: !!intrinsicToken,
40
45
  hasGap: !!hasGapToken,
41
- };
46
+ });
42
47
 
43
- index = index ? parseInt(index, 10) : null;
44
- isArray = !!isArray;
45
- type = type || null;
48
+ type = type || namedType || null;
46
49
  name = name || null;
47
50
 
48
- return buildReferenceTag(type, name, isArray, flags, index);
51
+ return buildReferenceTag(type, name, flags);
49
52
  };
50
53
 
51
54
  export const ref = (path) => {
@@ -56,7 +59,8 @@ export const lit = (str) => buildLiteralTag(stripArray(str));
56
59
 
57
60
  export const doctype = buildDoctypeTag;
58
61
  export const gap = buildGapTag;
59
- export const arr = () => buildInitializerTag(true);
60
62
  export const nodeOpen = buildOpenNodeTag;
63
+ export const fragOpen = buildOpenFragmentTag;
64
+ export const coverOpen = buildOpenCoverTag;
61
65
  export const nodeClose = buildCloseNodeTag;
62
66
  export const tree = (...tags) => treeFromStreamSync(tags);