@bablr/boot 0.1.3 → 0.1.5

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
@@ -2,6 +2,7 @@ const instruction = require('./languages/instruction.js');
2
2
  const regex = require('./languages/regex.js');
3
3
  const spamex = require('./languages/spamex.js');
4
4
  const string = require('./languages/string.js');
5
+ const number = require('./languages/number.js');
5
6
  const cstml = require('./languages/cstml.js');
6
7
  const { TemplateParser } = require('./miniparser.js');
7
8
 
@@ -33,6 +34,7 @@ const i = buildTag(instruction, 'Call');
33
34
  const spam = buildTag(spamex, 'Matcher');
34
35
  const re = buildTag(regex, 'Pattern');
35
36
  const str = buildTag(string, 'String');
37
+ const num = buildTag(number, 'Number');
36
38
  const cst = buildTag(cstml, 'Node');
37
39
 
38
- module.exports = { re, spam, str, i, cst };
40
+ module.exports = { re, spam, str, num, i, cst };
@@ -1,28 +1,44 @@
1
1
  const Regex = require('./regex.js');
2
2
  const StringLanguage = require('./string.js');
3
+ const Number = require('./number.js');
3
4
  const { buildCovers } = require('../utils.js');
4
5
  const sym = require('../symbols.js');
5
6
 
6
7
  const _ = /\s+/y;
7
8
  const PN = 'Punctuator';
8
9
  const ID = 'Identifier';
10
+ const LIT = 'Literal';
9
11
 
10
12
  const name = 'CSTML';
11
13
 
12
- const dependencies = { Regex, String: StringLanguage };
14
+ const dependencies = { Regex, String: StringLanguage, Number };
13
15
 
14
16
  const covers = buildCovers({
15
- [sym.node]: ['Attribute', 'Property', 'TagType', 'Node', 'OpenNodeTag', 'CloseNodeTag'],
17
+ [sym.node]: [
18
+ 'Attribute',
19
+ 'Property',
20
+ 'TagType',
21
+ 'Node',
22
+ 'OpenNodeTag',
23
+ 'CloseNodeTag',
24
+ 'Terminal',
25
+ ],
16
26
  [sym.fragment]: ['Attributes'],
17
- Attribute: ['StringAttribute', 'BooleanAttribute'],
27
+ Attribute: ['MappingAttribute', 'BooleanAttribute'],
28
+ AttributeValue: ['String:String', 'Number:Number'],
18
29
  TagType: ['Identifier', 'GlobalIdentifier'],
30
+ Terminal: ['Literal', 'Trivia', 'Escape'],
19
31
  });
20
32
 
21
33
  const grammar = class CSTMLMiniparserGrammar {
22
34
  Fragment(p) {
23
35
  p.eatMatchTrivia(_);
24
- while (p.match(/<[^/]/y) || p.atExpression) {
25
- p.eatProduction('Property', { path: 'properties[]' });
36
+ while (p.match(/['"]|<[^/]/y) || p.atExpression) {
37
+ if (p.match(/['"]/y)) {
38
+ p.eatProduction('Terminal', { path: 'properties[]' });
39
+ } else {
40
+ p.eatProduction('Property', { path: 'properties[]' });
41
+ }
26
42
  p.eatMatchTrivia(_);
27
43
  }
28
44
  }
@@ -62,7 +78,7 @@ const grammar = class CSTMLMiniparserGrammar {
62
78
  // @Node
63
79
  CloseNodeTag(p) {
64
80
  p.eat('</', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
65
-
81
+ // TODO permit .type
66
82
  p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
67
83
  }
68
84
 
@@ -86,7 +102,7 @@ const grammar = class CSTMLMiniparserGrammar {
86
102
  // @Cover
87
103
  Attribute(p) {
88
104
  if (p.match(/\w+\s*=/y)) {
89
- p.eatProduction('StringAttribute');
105
+ p.eatProduction('MappingAttribute');
90
106
  } else {
91
107
  p.eatProduction('BooleanAttribute');
92
108
  }
@@ -98,12 +114,21 @@ const grammar = class CSTMLMiniparserGrammar {
98
114
  }
99
115
 
100
116
  // @Node
101
- StringAttribute(p) {
102
- p.eat(/\w+/y, ID, { path: 'key' });
117
+ MappingAttribute(p) {
118
+ p.eat(/\w+/y, LIT, { path: 'key' });
103
119
  p.eatMatchTrivia(_);
104
120
  p.eat('=', PN, { path: 'mapOperator' });
105
121
  p.eatMatchTrivia(_);
106
- p.eatProduction('String:String', { path: 'value' });
122
+ p.eatProduction('AttributeValue', { path: 'value' });
123
+ }
124
+
125
+ // @Cover
126
+ AttributeValue(p) {
127
+ if (p.match(/['"]/y)) {
128
+ p.eatProduction('String:String');
129
+ } else if (p.match(/-|\d/y)) {
130
+ p.eatProduction('Number:Number');
131
+ }
107
132
  }
108
133
 
109
134
  // @Cover
@@ -126,6 +151,37 @@ const grammar = class CSTMLMiniparserGrammar {
126
151
  Identifier(p) {
127
152
  p.eatLiteral(/\w+/y);
128
153
  }
154
+
155
+ // @Cover
156
+ Terminal(p) {
157
+ if (p.match(/!['"]/y)) {
158
+ p.eatProduction('Escape');
159
+ } else if (p.match(/#['"]/y)) {
160
+ p.eatProduction('Trivia');
161
+ } else {
162
+ p.eatProduction('Literal');
163
+ }
164
+ }
165
+
166
+ // @Node
167
+ Escape(p) {
168
+ p.eat('!', PN, { path: 'escapeOperator' });
169
+ p.eatProduction('String:String', { path: 'rawValue' });
170
+ p.eatMatchTrivia(_);
171
+ p.eat(':', PN, { path: 'rawOperator' });
172
+ p.eatProduction('String:String', { path: 'value' });
173
+ }
174
+
175
+ // @Node
176
+ Trivia(p) {
177
+ p.eat('#', PN, { path: 'trivializeOperator' });
178
+ p.eatProduction('String:String', { path: 'value' });
179
+ }
180
+
181
+ // @Node
182
+ Literal(p) {
183
+ p.eatProduction('String:String', { path: 'value' });
184
+ }
129
185
  };
130
186
 
131
187
  module.exports = { name, dependencies, covers, grammar };
@@ -34,6 +34,7 @@ const grammar = class InstructionMiniparserGrammar {
34
34
  Call(p) {
35
35
  p.eat(/\w+/y, ID, { path: 'verb' });
36
36
  p.eatMatchTrivia(_);
37
+ p.eatMatch(/[!#]/y, PN, { path: 'verbSuffix' });
37
38
  p.eatProduction('Tuple', { path: 'arguments' });
38
39
  }
39
40
 
@@ -0,0 +1,38 @@
1
+ const { buildCovers } = require('../utils.js');
2
+ const sym = require('../symbols.js');
3
+
4
+ const name = 'Number';
5
+
6
+ const dependencies = {};
7
+
8
+ const covers = buildCovers({
9
+ [sym.node]: ['Number', 'Digit'],
10
+ Number: ['LiteralNumber', 'SymbolicNumber'],
11
+ });
12
+
13
+ const grammar = class NumberMiniparserGrammar {
14
+ // @Node
15
+ LiteralNumber(p) {
16
+ p.eatMatch('-', 'Punctuator', { path: 'negative' });
17
+ p.eatProduction('Digits', { path: 'digits[]' });
18
+ }
19
+
20
+ // @Node
21
+ SymbolicNumber(p) {
22
+ p.eatMatch('-', 'Punctuator', { path: 'negative' });
23
+ p.eat('Infinity', 'Keyword', { path: 'value' });
24
+ }
25
+
26
+ Digits(p) {
27
+ while (p.match(/\d/y)) {
28
+ p.eatProduction('Digit');
29
+ }
30
+ }
31
+
32
+ // @Node
33
+ Digit(p) {
34
+ p.eatLiteral(/\d/y);
35
+ }
36
+ };
37
+
38
+ module.exports = { name, dependencies, covers, grammar };
@@ -76,7 +76,7 @@ const cookEscape = (escape, span) => {
76
76
  }
77
77
 
78
78
  if (hexMatch) {
79
- return parseInt(hexMatch[1], 16);
79
+ return String.fromCodePoint(parseInt(hexMatch[1], 16));
80
80
  }
81
81
 
82
82
  let litMatch = /\\([nrt0])/y.exec(escape);
@@ -306,7 +306,7 @@ const grammar = class RegexMiniparserGrammar {
306
306
  max = p.eatMatch(/\d+/y, 'Number', { path: 'max' });
307
307
  }
308
308
 
309
- attrs = { min, max };
309
+ attrs = { min: min && parseInt(min, 10), max: max && parseInt(max, 10) };
310
310
 
311
311
  p.eat('}', PN, { path: 'close', balancer: true });
312
312
  }
@@ -1,5 +1,6 @@
1
1
  const Regex = require('./regex.js');
2
2
  const StringLanguage = require('./string.js');
3
+ const Number = require('./number.js');
3
4
  const { buildCovers } = require('../utils.js');
4
5
  const sym = require('../symbols.js');
5
6
 
@@ -11,11 +12,12 @@ const LIT = 'Literal';
11
12
 
12
13
  const name = 'Spamex';
13
14
 
14
- const dependencies = { Regex, String: StringLanguage };
15
+ const dependencies = { Regex, String: StringLanguage, Number };
15
16
 
16
17
  const covers = buildCovers({
17
18
  [sym.node]: ['Attribute', 'TagType', 'Matcher', 'Literal'],
18
- Attribute: ['StringAttribute', 'BooleanAttribute'],
19
+ Attribute: ['MappingAttribute', 'BooleanAttribute'],
20
+ AttributeValue: ['String:String', 'Number:Number'],
19
21
  Matcher: ['NodeMatcher', 'TerminalMatcher', 'TriviaTerminalMatcher', 'StringMatcher'],
20
22
  StringMatcher: ['String:String', 'Regex:Pattern'],
21
23
  TagType: ['Identifier', 'GlobalIdentifier'],
@@ -96,7 +98,7 @@ const grammar = class SpamexMiniparserGrammar {
96
98
  // @Cover
97
99
  Attribute(p) {
98
100
  if (p.match(/\w+\s*=/y)) {
99
- p.eatProduction('StringAttribute');
101
+ p.eatProduction('MappingAttribute');
100
102
  } else {
101
103
  p.eatProduction('BooleanAttribute');
102
104
  }
@@ -108,12 +110,21 @@ const grammar = class SpamexMiniparserGrammar {
108
110
  }
109
111
 
110
112
  // @Node
111
- StringAttribute(p) {
113
+ MappingAttribute(p) {
112
114
  p.eat(/\w+/y, LIT, { path: 'key' });
113
115
  p.eatMatchTrivia(_);
114
116
  p.eat('=', PN, { path: 'mapOperator' });
115
117
  p.eatMatchTrivia(_);
116
- p.eatProduction('String:String', { path: 'value' });
118
+ p.eatProduction('AttributeValue', { path: 'value' });
119
+ }
120
+
121
+ // @Cover
122
+ AttributeValue(p) {
123
+ if (p.match(/['"]/y)) {
124
+ p.eatProduction('String:String');
125
+ } else if (p.match(/-|\d/y)) {
126
+ p.eatProduction('Number:Number');
127
+ }
117
128
  }
118
129
 
119
130
  // @Cover
@@ -14,10 +14,10 @@ const PN = 'Punctuator';
14
14
 
15
15
  const escapables = new Map(
16
16
  objectEntries({
17
- n: '\n'.codePointAt(0),
18
- r: '\r'.codePointAt(0),
19
- t: '\t'.codePointAt(0),
20
- 0: '\0'.codePointAt(0),
17
+ n: '\n',
18
+ r: '\r',
19
+ t: '\t',
20
+ 0: '\0',
21
21
  }),
22
22
  );
23
23
 
@@ -41,7 +41,7 @@ const cookEscape = (escape, span) => {
41
41
  }
42
42
 
43
43
  if (hexMatch) {
44
- return parseInt(hexMatch[1], 16);
44
+ return String.fromCodePoint(parseInt(hexMatch[1], 16));
45
45
  }
46
46
 
47
47
  const litPattern = span === 'String:Single' ? /\\([\\nrt0'])/y : /\\([\\nrt0"])/y;
@@ -79,8 +79,8 @@ const grammar = class StringMiniparserGrammar {
79
79
  : p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|x[0-9a-fA-F]{2}|[\\nrt0"])/y);
80
80
  lit =
81
81
  p.span.type === 'Single'
82
- ? p.eatMatchLiteral(/[^\r\n\\']+/y)
83
- : p.eatMatchLiteral(/[^\r\n\\"]+/y);
82
+ ? p.eatMatchLiteral(/[^\r\n\0\\']+/y)
83
+ : p.eatMatchLiteral(/[^\r\n\0\\"]+/y);
84
84
  i++;
85
85
  } while (esc || lit);
86
86
  if (i === 1 && !esc && !lit) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/boot",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Compile-time tools for bootstrapping BABLR VM",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -11,6 +11,7 @@ const i = require('./lib/languages/instruction.js');
11
11
  const re = require('./lib/languages/regex.js');
12
12
  const spam = require('./lib/languages/spamex.js');
13
13
  const str = require('./lib/languages/string.js');
14
+ const num = require('./lib/languages/number.js');
14
15
  const cstml = require('./lib/languages/cstml.js');
15
16
  const { addNamespace, addNamed } = require('@babel/helper-module-imports');
16
17
  const { PathResolver } = require('@bablr/boot-helpers/path');
@@ -146,6 +147,7 @@ const languages = {
146
147
  re,
147
148
  spam,
148
149
  str,
150
+ num,
149
151
  cst: cstml,
150
152
  };
151
153
 
@@ -154,6 +156,7 @@ const topTypes = {
154
156
  re: 'Pattern',
155
157
  spam: 'Matcher',
156
158
  str: 'String',
159
+ num: 'Number',
157
160
  cst: 'Node',
158
161
  };
159
162
 
@@ -173,6 +176,7 @@ const shorthandMacro = ({ references }) => {
173
176
  references.spam,
174
177
  references.re,
175
178
  references.str,
179
+ references.num,
176
180
  references.cst,
177
181
  )) {
178
182
  if (!bindings.t) {