@bablr/boot 0.1.7 → 0.1.9

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
@@ -34,7 +34,7 @@ const i = buildTag(instruction, 'Call');
34
34
  const spam = buildTag(spamex, 'Matcher');
35
35
  const re = buildTag(regex, 'Pattern');
36
36
  const str = buildTag(string, 'String');
37
- const num = buildTag(number, 'Number');
37
+ const num = buildTag(number, 'Integer');
38
38
  const cst = buildTag(cstml, 'Fragment');
39
39
 
40
40
  module.exports = { re, spam, str, num, i, cst };
@@ -20,7 +20,7 @@ const covers = buildCovers({
20
20
  'TagType',
21
21
  'Node',
22
22
  'OpenFragmentNodeTag',
23
- 'OpenTerminalNodeTag',
23
+ 'TerminalNodeShorthandTag',
24
24
  'OpenNodeTag',
25
25
  'CloseNodeTag',
26
26
  'Terminal',
@@ -56,7 +56,7 @@ const grammar = class CSTMLMiniparserGrammar {
56
56
 
57
57
  // @Node
58
58
  Node(p) {
59
- const openType = p.match('<|') ? 'OpenTerminalNodeTag' : 'OpenNodeTag';
59
+ const openType = p.match('<|') ? 'TerminalNodeShorthandTag' : 'OpenNodeTag';
60
60
  const childrenType = openType === 'OpenNodeTag' ? 'NodeChildren' : 'TerminalNodeChildren';
61
61
 
62
62
  if (p.match('<>')) throw new Error('Fragment is not a node');
@@ -134,7 +134,7 @@ const grammar = class CSTMLMiniparserGrammar {
134
134
  }
135
135
 
136
136
  // @Node
137
- OpenTerminalNodeTag(p) {
137
+ TerminalNodeShorthandTag(p) {
138
138
  p.eat('<|', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
139
139
  p.eatMatchTrivia(_);
140
140
  p.eatProduction('TagType', { path: 'type' });
@@ -154,14 +154,11 @@ const grammar = class CSTMLMiniparserGrammar {
154
154
 
155
155
  p.eatMatchTrivia(_);
156
156
  p.eat('|>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
157
-
158
- return { attrs: { selfClosing: !!value } };
159
157
  }
160
158
 
161
159
  // @Node
162
160
  CloseNodeTag(p) {
163
161
  p.eat('</', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
164
- // TODO permit .type
165
162
  p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
166
163
  }
167
164
 
@@ -7,18 +7,18 @@ const dependencies = {};
7
7
 
8
8
  const covers = buildCovers({
9
9
  [sym.node]: ['Number', 'Digit'],
10
- Number: ['LiteralNumber', 'SymbolicNumber'],
10
+ Number: ['Integer', 'Infinity'],
11
11
  });
12
12
 
13
13
  const grammar = class NumberMiniparserGrammar {
14
14
  // @Node
15
- LiteralNumber(p) {
15
+ Integer(p) {
16
16
  p.eatMatch('-', 'Punctuator', { path: 'negative' });
17
17
  p.eatProduction('Digits', { path: 'digits[]' });
18
18
  }
19
19
 
20
20
  // @Node
21
- SymbolicNumber(p) {
21
+ Infinity(p) {
22
22
  p.eatMatch('-', 'Punctuator', { path: 'negative' });
23
23
  p.eat('Infinity', 'Keyword', { path: 'value' });
24
24
  }
@@ -71,12 +71,12 @@ const grammar = class SpamexMiniparserGrammar {
71
71
  p.eatProduction('TagType', { path: 'type' });
72
72
  let sp = p.eatMatchTrivia(_);
73
73
 
74
- if (sp && p.match(/['"/]/y)) {
74
+ if (sp && (p.match(/['"/]/y) || p.atExpression)) {
75
75
  p.eatProduction('StringMatcher', { path: 'value' });
76
76
  sp = p.eatMatchTrivia(_);
77
77
  }
78
78
 
79
- if (sp && p.match(/\w+/y)) {
79
+ if (sp && (p.match(/\w+/y) || p.atExpression)) {
80
80
  p.eatProduction('Attributes', { path: 'attributes[]' });
81
81
  sp = p.eatMatchTrivia(_);
82
82
  }
@@ -24,17 +24,11 @@ const escapables = new Map(
24
24
  const cookEscape = (escape, span) => {
25
25
  let hexMatch;
26
26
 
27
- if (!span.type.startsWith('String')) {
28
- throw new Error();
29
- }
30
-
31
27
  if (!escape.startsWith('\\')) {
32
28
  throw new Error('string escape must start with \\');
33
29
  }
34
30
 
35
- if ((hexMatch = /\\x([0-9a-f]{2})/iy.exec(escape))) {
36
- //continue
37
- } else if ((hexMatch = /\\u([0-9a-f]{4})/iy.exec(escape))) {
31
+ if ((hexMatch = /\\u([0-9a-f]{4})/iy.exec(escape))) {
38
32
  //continue
39
33
  } else if ((hexMatch = /\\u{([0-9a-f]+)}/iy.exec(escape))) {
40
34
  //continue
@@ -44,11 +38,11 @@ const cookEscape = (escape, span) => {
44
38
  return String.fromCodePoint(parseInt(hexMatch[1], 16));
45
39
  }
46
40
 
47
- const litPattern = span === 'String:Single' ? /\\([\\nrt0'])/y : /\\([\\nrt0"])/y;
41
+ const litPattern = span === 'Single' ? /\\([\\nrt0'])/y : /\\([\\nrt0"])/y;
48
42
  const litMatch = litPattern.exec(escape);
49
43
 
50
44
  if (litMatch) {
51
- return escapables.get(litMatch[1]);
45
+ return escapables.get(litMatch[1]) || litMatch[1];
52
46
  }
53
47
 
54
48
  throw new Error('unable to cook string escape');
@@ -75,8 +69,8 @@ const grammar = class StringMiniparserGrammar {
75
69
  do {
76
70
  esc =
77
71
  p.span.type === 'Single'
78
- ? p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|x[0-9a-fA-F]{2}|[\\nrt0'])/y)
79
- : p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|x[0-9a-fA-F]{2}|[\\nrt0"])/y);
72
+ ? p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|[\\nrt0'])/y)
73
+ : p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|[\\nrt0"])/y);
80
74
  lit =
81
75
  p.span.type === 'Single'
82
76
  ? p.eatMatchLiteral(/[^\r\n\0\\']+/y)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/boot",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Compile-time tools for bootstrapping BABLR VM",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -63,20 +63,34 @@ const getASTValue = (v, exprs, bindings) => {
63
63
  : generateNode(v, exprs, bindings);
64
64
  };
65
65
 
66
+ const escapeReplacer = (esc) => {
67
+ if (esc === '\r') {
68
+ return '\\r';
69
+ } else if (esc === '\n') {
70
+ return '\\n';
71
+ } else if (esc === '\0') {
72
+ return '\\0';
73
+ } else {
74
+ return `\\${esc}`;
75
+ }
76
+ };
77
+ const printTemplateString = (str) => {
78
+ return `\`${str.replace(/[`\\\0\r\n]/g, escapeReplacer)}\``;
79
+ };
80
+
66
81
  const generateNodeChild = (child, bindings) => {
67
82
  if (child.type === 'Reference') {
68
83
  const { pathName, pathIsArray } = child.value;
69
84
  const printedRef = pathIsArray ? `${pathName}[]` : pathName;
70
85
  return expression(`%%t%%.ref\`${printedRef}\``)({ t: bindings.t });
71
86
  } else if (child.type === 'Literal') {
72
- return expression(`%%t%%.lit\`${child.value.replace(/\\/g, '\\\\')}\``)({ t: bindings.t });
87
+ return expression(`%%t%%.lit${printTemplateString(child.value)}`)({ t: bindings.t });
73
88
  } else if (child.type === 'Trivia') {
74
- return expression(`%%t%%.trivia\` \``)({ t: bindings.t });
89
+ return expression(`%%t%%.trivia${printTemplateString(child.value)}`)({ t: bindings.t });
75
90
  } else if (child.type === 'Escape') {
76
- return expression(`%%t%%.esc(%%cooked%%, %%raw%%)`)({
91
+ const {cooked, raw} = child.value
92
+ return expression(`%%t%%.esc(${printTemplateString(raw)}, ${printTemplateString(cooked)})`)({
77
93
  t: bindings.t,
78
- cooked: child.cooked,
79
- raw: child.raw,
80
94
  });
81
95
  } else {
82
96
  throw new Error(`Unknown child type ${child.type}`);
@@ -159,7 +173,7 @@ const topTypes = {
159
173
  re: 'Pattern',
160
174
  spam: 'Matcher',
161
175
  str: 'String',
162
- num: 'Number',
176
+ num: 'Integer',
163
177
  cst: 'Fragment',
164
178
  };
165
179