@bablr/agast-helpers 0.9.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,16 +6,15 @@ import {
6
6
  ShiftTag,
7
7
  GapTag,
8
8
  NullTag,
9
- InitializerTag,
10
9
  LiteralTag,
11
10
  AttributeDefinition,
12
11
  BindingTag,
13
- Document,
14
12
  } from './symbols.js';
15
13
  import { referenceFlags } from './builders.js';
16
14
 
17
15
  let { isInteger, isFinite } = Number;
18
16
  let { isArray } = Array;
17
+ let { freeze } = Object;
19
18
  let isString = (val) => typeof val === 'string';
20
19
  let isNumber = (val) => typeof val === 'number';
21
20
  let isObject = (val) => val && typeof val === 'object' && !isArray(val);
@@ -58,7 +57,20 @@ export const printAttributes = (attributes) => {
58
57
  };
59
58
 
60
59
  export const printIdentifierPath = (path) => {
61
- 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('.');
62
74
  };
63
75
 
64
76
  let escapeReplacer = (esc) => {
@@ -78,7 +90,7 @@ let escapeReplacer = (esc) => {
78
90
  };
79
91
 
80
92
  export const printIdentifier = (id) => {
81
- 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)
82
94
  ? id
83
95
  : `\`${id
84
96
  .replace(/[`\\]/g, '\\`')
@@ -103,16 +115,6 @@ export const printGapTag = (tag) => {
103
115
  return `<//>`;
104
116
  };
105
117
 
106
- export const printInitializerTag = (tag) => {
107
- if (tag?.type !== InitializerTag) throw new Error();
108
-
109
- if (tag.value.isArray) {
110
- return `[]`;
111
- } else {
112
- return 'undefined';
113
- }
114
- };
115
-
116
118
  export const printShiftTag = (tag) => {
117
119
  if (tag?.type !== ShiftTag) throw new Error();
118
120
 
@@ -120,18 +122,31 @@ export const printShiftTag = (tag) => {
120
122
  };
121
123
 
122
124
  export const printReference = (ref) => {
123
- let { type, name, isArray, flags } = ref;
124
- let pathBraces = isArray ? `[]` : '';
125
+ let { type, name, flags } = ref;
125
126
 
126
127
  if (type && type !== '#' && name) throw new Error();
127
- if (type && !['.', '#', '@', '_'].includes(type)) throw new Error();
128
+ if (type && !['_', '.', '#', '@'].includes(type)) throw new Error();
128
129
 
129
- return `${type || ''}${printIdentifier(name) || ''}${pathBraces}${printReferenceFlags(flags)}:`;
130
+ return `${type || ''}${printIdentifier(name) || ''}${printReferenceFlags(flags)}:`;
130
131
  };
131
132
 
132
133
  export const printBinding = (binding) => {
133
- let { languagePath } = binding;
134
- return `:${languagePath ? printIdentifierPath(languagePath) : ''}:`;
134
+ let { segments } = binding;
135
+ return `:${
136
+ segments.length ? segments.map((segment) => printBindingSegment(segment)).join('/') : ''
137
+ }:`;
138
+ };
139
+
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
+ }
135
150
  };
136
151
 
137
152
  export const printReferenceTag = (tag) => {
@@ -150,7 +165,7 @@ export const printNullTag = (tag) => {
150
165
  return 'null';
151
166
  };
152
167
 
153
- export const printType = (type) => {
168
+ export const printName = (type) => {
154
169
  return typeof type === 'string'
155
170
  ? type
156
171
  : typeof type === 'symbol'
@@ -158,6 +173,10 @@ export const printType = (type) => {
158
173
  : String(type);
159
174
  };
160
175
 
176
+ export const printType = (type) => {
177
+ return typeof type === 'symbol' ? type.description : String(type);
178
+ };
179
+
161
180
  export const printDoctypeTag = (tag) => {
162
181
  if (tag?.type !== DoctypeTag) throw new Error();
163
182
 
@@ -176,55 +195,58 @@ export const printLiteralTag = (tag) => {
176
195
  };
177
196
 
178
197
  export const printReferenceFlags = (flags = referenceFlags) => {
198
+ let array = flags.array ? `[]` : '';
179
199
  let plus = flags.expression ? '+' : '';
200
+ let star = flags.intrinsic ? '*' : '';
180
201
  let dollar = flags.hasGap ? '$' : '';
181
202
 
182
- return `${plus}${dollar}`;
203
+ return `${array}${plus}${star}${dollar}`;
183
204
  };
184
205
 
185
206
  export const printNodeFlags = (flags) => {
186
- if (flags.cover && !flags.fragment) throw new Error();
187
-
188
207
  let star = flags.token ? '*' : '';
189
208
  let dollar = flags.hasGap ? '$' : '';
190
- let fragment = flags.fragment ? '_' : '';
191
- let multiFragment = fragment && !flags.cover ? '_' : '';
192
209
 
193
- return `${star}${dollar}${fragment}${multiFragment}`;
210
+ return `${star}${dollar}`;
211
+ };
212
+
213
+ export const printNodeType = (type) => {
214
+ if (![Symbol.for('_'), Symbol.for('__')].includes(type)) throw new Error();
215
+
216
+ return type.description;
194
217
  };
195
218
 
196
219
  export const printOpenNodeTag = (tag) => {
197
220
  if (tag?.type !== OpenNodeTag) throw new Error();
198
221
 
199
- let { flags, type, literalValue, attributes, selfClosing } = tag.value;
222
+ let { flags, type, name, literalValue, attributes, selfClosing } = tag.value;
200
223
 
201
- if (!type && !flags.fragment) throw new Error();
202
224
  if (literalValue && !selfClosing) throw new Error();
203
-
204
- if (!type) {
205
- return `<${printNodeFlags(flags)}>`;
206
- }
225
+ let selfClosingFrag = selfClosing ? ' /' : '';
226
+ let literalFrag = literalValue ? ` ${printString(literalValue)}` : '';
207
227
 
208
228
  let printedAttributes = printAttributes(attributes);
209
229
  let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
210
- let literalFrag = literalValue ? ` ${printString(literalValue)}` : '';
211
- let selfClosingFrag = selfClosing ? ' /' : '';
230
+ let typeFrag = type ? printNodeType(type) : '';
231
+ let nameFrag = name ? printType(name) : '';
212
232
 
213
- return `<${printNodeFlags(flags)}${printType(
214
- type,
215
- )}${literalFrag}${attributesFrag}${selfClosingFrag}>`;
233
+ return `<${printNodeFlags(
234
+ flags,
235
+ )}${typeFrag}${nameFrag}${literalFrag}${attributesFrag}${selfClosingFrag}>`;
216
236
  };
217
237
 
218
238
  export const printSelfClosingNodeTag = (tag, literalValue) => {
219
239
  if (tag?.type !== OpenNodeTag) throw new Error();
220
240
 
221
- let { flags, type, attributes } = tag.value;
241
+ let { flags, type, name, attributes } = tag.value;
222
242
 
223
243
  let printedAttributes = printAttributes(attributes);
224
244
  let attributesFrag = printedAttributes ? ` ${printedAttributes}` : '';
225
- let intrinsicFrag = literalValue ? ` ${printString(literalValue)}` : '';
245
+ let literalFrag = literalValue ? ` ${printString(literalValue)}` : '';
246
+ let typeFrag = type ? printNodeType(type) : '';
247
+ let nameFrag = name ? printType(name) : '';
226
248
 
227
- return `<${printNodeFlags(flags)}${printType(type)}${intrinsicFrag}${attributesFrag} />`;
249
+ return `<${printNodeFlags(flags)}${typeFrag}${nameFrag}${literalFrag}${attributesFrag} />`;
228
250
  };
229
251
 
230
252
  export const printCloseNodeTag = (tag) => {
@@ -238,14 +260,15 @@ export const printAttributeDefinition = (tag) => {
238
260
  if (!tag.value.path?.length) throw new Error();
239
261
  let { path, value } = tag.value;
240
262
 
241
- return `{ ${printIdentifierPath(path)}: ${printExpression(value)} }`;
263
+ return `{ ${printIdentifierPath(
264
+ path.map((name) => freeze({ type: null, name })),
265
+ )}: ${printExpression(value)} }`;
242
266
  };
243
267
 
244
268
  const printers = {
245
269
  [NullTag]: printNullTag,
246
270
  [GapTag]: printGapTag,
247
271
  [BindingTag]: printBindingTag,
248
- [InitializerTag]: printInitializerTag,
249
272
  [ShiftTag]: printShiftTag,
250
273
  [LiteralTag]: printLiteralTag,
251
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);