@bablr/boot 0.1.2 → 0.1.4

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,20 +1,23 @@
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
17
  [sym.node]: ['Attribute', 'Property', 'TagType', 'Node', 'OpenNodeTag', 'CloseNodeTag'],
16
18
  [sym.fragment]: ['Attributes'],
17
- Attribute: ['StringAttribute', 'BooleanAttribute'],
19
+ Attribute: ['MappingAttribute', 'BooleanAttribute'],
20
+ AttributeValue: ['String:String', 'Number:Number'],
18
21
  TagType: ['Identifier', 'GlobalIdentifier'],
19
22
  });
20
23
 
@@ -22,7 +25,7 @@ const grammar = class CSTMLMiniparserGrammar {
22
25
  Fragment(p) {
23
26
  p.eatMatchTrivia(_);
24
27
  while (p.match(/<[^/]/y) || p.atExpression) {
25
- p.eatProduction('Property', { path: 'properties' });
28
+ p.eatProduction('Property', { path: 'properties[]' });
26
29
  p.eatMatchTrivia(_);
27
30
  }
28
31
  }
@@ -73,7 +76,7 @@ const grammar = class CSTMLMiniparserGrammar {
73
76
  if (p.atExpression) {
74
77
  p.eatProduction('Attributes'); // ??
75
78
  } else {
76
- p.eatProduction('Attribute', { path: '[attributes]' });
79
+ p.eatProduction('Attribute', { path: 'attributes[]' });
77
80
  }
78
81
  if (p.match(/\s+\w/y) || (p.match(/\s+$/y) && !p.quasisDone)) {
79
82
  sp = p.eatMatchTrivia(_);
@@ -86,7 +89,7 @@ const grammar = class CSTMLMiniparserGrammar {
86
89
  // @Cover
87
90
  Attribute(p) {
88
91
  if (p.match(/\w+\s*=/y)) {
89
- p.eatProduction('StringAttribute');
92
+ p.eatProduction('MappingAttribute');
90
93
  } else {
91
94
  p.eatProduction('BooleanAttribute');
92
95
  }
@@ -98,12 +101,21 @@ const grammar = class CSTMLMiniparserGrammar {
98
101
  }
99
102
 
100
103
  // @Node
101
- StringAttribute(p) {
102
- p.eat(/\w+/y, ID, { path: 'key' });
104
+ MappingAttribute(p) {
105
+ p.eat(/\w+/y, LIT, { path: 'key' });
103
106
  p.eatMatchTrivia(_);
104
107
  p.eat('=', PN, { path: 'mapOperator' });
105
108
  p.eatMatchTrivia(_);
106
- p.eatProduction('String:String', { path: 'value' });
109
+ p.eatProduction('AttributeValue', { path: 'value' });
110
+ }
111
+
112
+ // @Cover
113
+ AttributeValue(p) {
114
+ if (p.match(/['"]/y)) {
115
+ p.eatProduction('String:String');
116
+ } else if (p.match(/-|\d/y)) {
117
+ p.eatProduction('Number:Number');
118
+ }
107
119
  }
108
120
 
109
121
  // @Cover
@@ -69,7 +69,7 @@ const grammar = class InstructionMiniparserGrammar {
69
69
  let first = true;
70
70
  let sep;
71
71
  while (first || (sep && (p.match(/./y) || p.atExpression))) {
72
- p.eatProduction('Property', { path: '[properties]' });
72
+ p.eatProduction('Property', { path: 'properties[]' });
73
73
  sep = p.eatMatchTrivia(_);
74
74
  first = false;
75
75
  }
@@ -97,7 +97,7 @@ const grammar = class InstructionMiniparserGrammar {
97
97
  let first = true;
98
98
  let sep;
99
99
  while (first || (sep && (p.match(/./y) || p.atExpression))) {
100
- p.eatProduction('Expression', { path: '[elements]' });
100
+ p.eatProduction('Expression', { path: 'elements[]' });
101
101
  sep = p.eatMatchTrivia(_);
102
102
  first = false;
103
103
  }
@@ -113,7 +113,7 @@ const grammar = class InstructionMiniparserGrammar {
113
113
 
114
114
  let i = 0;
115
115
  while (i === 0 || (sep && (p.match(/./y) || p.atExpression))) {
116
- p.eatProduction('Expression', { path: '[values]' });
116
+ p.eatProduction('Expression', { path: 'values[]' });
117
117
  sep = p.eatMatchTrivia(_);
118
118
  i++;
119
119
  }
@@ -128,7 +128,7 @@ const grammar = class InstructionMiniparserGrammar {
128
128
 
129
129
  // @Node
130
130
  Null(p) {
131
- p.eat(/null/y, KW, { path: 'value' });
131
+ p.eat('null', KW, { path: 'value' });
132
132
  }
133
133
  };
134
134
 
@@ -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);
@@ -98,9 +98,9 @@ const grammar = class RegexMiniparserGrammar {
98
98
  // @Node
99
99
  Pattern(p) {
100
100
  p.eat('/', PN, { path: 'open', balanced: '/' });
101
- p.eatProduction('Alternatives', { path: '[alternatives]' });
101
+ p.eatProduction('Alternatives', { path: 'alternatives[]' });
102
102
  p.eat('/', PN, { path: 'close', balancer: true });
103
- p.eatProduction('Flags', { path: '[flags]' });
103
+ p.eatProduction('Flags', { path: 'flags[]' });
104
104
  }
105
105
 
106
106
  Flags(p) {
@@ -116,19 +116,18 @@ const grammar = class RegexMiniparserGrammar {
116
116
  // @Node
117
117
  Flag(p) {
118
118
  const flag = p.eatMatch(/[gimsuy]/y, KW, { path: 'value' });
119
-
120
119
  return { attrs: { kind: flagsReverse[flag] } };
121
120
  }
122
121
 
123
122
  Alternatives(p) {
124
123
  do {
125
124
  p.eatProduction('Alternative');
126
- } while (p.eatMatch('|', PN, { path: '[separators]' }));
125
+ } while (p.eatMatch('|', PN, { path: 'separators[]' }));
127
126
  }
128
127
 
129
128
  // @Node
130
129
  Alternative(p) {
131
- p.eatProduction('Elements', { path: '[elements]' });
130
+ p.eatProduction('Elements', { path: 'elements[]' });
132
131
  }
133
132
 
134
133
  Elements(p) {
@@ -163,14 +162,14 @@ const grammar = class RegexMiniparserGrammar {
163
162
  // @Node
164
163
  Group(p) {
165
164
  p.eat('(?:', PN, { path: 'open', balanced: ')' });
166
- p.eatProduction('Alternatives', { path: '[alternatives]' });
165
+ p.eatProduction('Alternatives', { path: 'alternatives[]' });
167
166
  p.eat(')', PN, { path: 'close', balancer: true });
168
167
  }
169
168
 
170
169
  // @Node
171
170
  CapturingGroup(p) {
172
171
  p.eat('(', PN, { path: 'open', balanced: ')' });
173
- p.eatProduction('Alternatives', { path: '[alternatives]' });
172
+ p.eatProduction('Alternatives', { path: 'alternatives[]' });
174
173
  p.eat(')', PN, { path: 'close', balancer: true });
175
174
  }
176
175
 
@@ -226,7 +225,7 @@ const grammar = class RegexMiniparserGrammar {
226
225
 
227
226
  let first = !negate;
228
227
  while (p.match(/./sy)) {
229
- p.eatProduction('CharacterClassElement', { path: '[elements]' }, { first });
228
+ p.eatProduction('CharacterClassElement', { path: 'elements[]' }, { first });
230
229
  first = false;
231
230
  }
232
231
 
@@ -307,7 +306,7 @@ const grammar = class RegexMiniparserGrammar {
307
306
  max = p.eatMatch(/\d+/y, 'Number', { path: 'max' });
308
307
  }
309
308
 
310
- attrs = { min, max };
309
+ attrs = { min: min && parseInt(min, 10), max: max && parseInt(max, 10) };
311
310
 
312
311
  p.eat('}', PN, { path: 'close', balancer: true });
313
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'],
@@ -54,7 +56,7 @@ const grammar = class SpamexMiniparserGrammar {
54
56
  let sp = p.eatMatchTrivia(_);
55
57
 
56
58
  if ((sp && p.match(/\w+/y)) || p.atExpression) {
57
- p.eatProduction('Attributes', { path: '[attributes]' });
59
+ p.eatProduction('Attributes', { path: 'attributes[]' });
58
60
  sp = p.eatMatchTrivia(_);
59
61
  }
60
62
 
@@ -75,7 +77,7 @@ const grammar = class SpamexMiniparserGrammar {
75
77
  }
76
78
 
77
79
  if (sp && p.match(/\w+/y)) {
78
- p.eatProduction('Attributes', { path: '[attributes]' });
80
+ p.eatProduction('Attributes', { path: 'attributes[]' });
79
81
  sp = p.eatMatchTrivia(_);
80
82
  }
81
83
 
@@ -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;
package/lib/miniparser.js CHANGED
@@ -5,7 +5,7 @@ const isString = require('iter-tools-es/methods/is-string');
5
5
  const isObject = require('iter-tools-es/methods/is-object');
6
6
  const sym = require('./symbols.js');
7
7
  const { Match } = require('./match.js');
8
- const { set, isRegex, isArray, parsePath, getPrototypeOf, buildNode } = require('./utils.js');
8
+ const { set, isRegex, isArray, getPrototypeOf, buildNode, parsePath } = require('./utils.js');
9
9
 
10
10
  class TemplateParser {
11
11
  constructor(rootLanguage, quasis, expressions) {
@@ -172,9 +172,8 @@ class TemplateParser {
172
172
  }
173
173
  } else if (parentPath?.node && (isNode || covers.has(type))) {
174
174
  const { properties, children } = parentPath.node;
175
- const { pathName } = parsePath(this.m.attrs.path);
176
175
 
177
- children.push({ ...ref(pathName), id });
176
+ children.push({ ...ref(this.m.attrs.path), id });
178
177
 
179
178
  set(properties, this.m.attrs.path, result);
180
179
  }
@@ -195,9 +194,7 @@ class TemplateParser {
195
194
  node.attributes = result.attrs;
196
195
  }
197
196
  if (parentPath?.node && !covers.has(type)) {
198
- const { pathName } = parsePath(this.m.attrs.path);
199
-
200
- parentPath.node.children.push(ref(pathName));
197
+ parentPath.node.children.push(ref(this.m.attrs.path));
201
198
 
202
199
  set(parentPath.node.properties, this.m.attrs.path, node);
203
200
  }
@@ -280,16 +277,16 @@ class TemplateParser {
280
277
  }
281
278
 
282
279
  const path = lastChild.value;
283
- const pathIsArray = isArray(properties[path]);
280
+ const { pathIsArray, pathName } = parsePath(path);
284
281
 
285
- this.held = pathIsArray ? arrayLast(properties[path]) : properties[path];
282
+ this.held = pathIsArray ? arrayLast(properties[pathName]) : properties[pathName];
286
283
 
287
284
  children.pop();
288
285
 
289
286
  if (pathIsArray) {
290
- properties[path].pop();
287
+ properties[pathName].pop();
291
288
  } else {
292
- properties[path] = null;
289
+ properties[pathName] = null;
293
290
  }
294
291
 
295
292
  return this.eval(this.buildId(id), attrs, props);
@@ -309,7 +306,7 @@ class TemplateParser {
309
306
 
310
307
  set(this.node.properties, attrs.path, buildNode(this.buildId(type), [lit(result)]));
311
308
 
312
- this.node.children.push(ref(parsePath(attrs.path).pathName));
309
+ this.node.children.push(ref(attrs.path));
313
310
 
314
311
  return result;
315
312
  }
@@ -337,7 +334,7 @@ class TemplateParser {
337
334
 
338
335
  set(this.node.properties, attrs.path, buildNode(this.buildId(type), [lit(result)]));
339
336
 
340
- this.node.children.push(ref(parsePath(attrs.path).pathName));
337
+ this.node.children.push(ref(attrs.path));
341
338
  }
342
339
  return result;
343
340
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/boot",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Compile-time tools for bootstrapping BABLR VM",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -18,7 +18,7 @@
18
18
  "@babel/helper-module-imports": "^7.22.15",
19
19
  "@babel/template": "^7.22.15",
20
20
  "@babel/types": "7.23.0",
21
- "@bablr/boot-helpers": "0.1.0",
21
+ "@bablr/boot-helpers": "0.1.1",
22
22
  "escape-string-regexp": "4.0.0",
23
23
  "iter-tools-es": "^7.5.3"
24
24
  },
@@ -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) {