@bablr/language-en-json 0.9.0 → 0.11.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/grammar.js CHANGED
@@ -1,19 +1,18 @@
1
1
  /* @macrome
2
2
  * @generatedby @bablr/macrome-generator-bablr
3
- * @generatedfrom ./grammar.macro.js#ba23af5f0d351c04f7e57efff1bd6d2d74cbffe3
3
+ * @generatedfrom ./grammar.macro.js#dd06bed2bba53b9dde1ae7cf33f8696edb684bd6
4
4
  * This file is autogenerated. Please do not edit it directly.
5
5
  * When editing run `npx macrome watch` then change the file this is generated from.
6
6
  */
7
7
  import _applyDecs from "@babel/runtime/helpers/applyDecs2305";
8
- let _initProto, _ExpressionDecs, _ArrayDecs, _ObjectDecs, _NumberDecs, _InfinityDecs, _BooleanDecs, _NullDecs, _KeywordDecs, _PunctuatorDecs, _ListDecs, _AnyDecs, _AllDecs;
8
+ let _initProto, _ExpressionDecs, _ArrayDecs, _ObjectDecs, _StringDecs, _NumberDecs, _InfinityDecs, _BooleanDecs, _NullDecs, _KeywordDecs, _PunctuatorDecs, _ListDecs, _AnyDecs, _AllDecs;
9
9
  import { re, spam as m } from '@bablr/boot';
10
- import { triviaEnhancer } from '@bablr/helpers/trivia';
10
+ import { basicTriviaEnhancer } from '@bablr/helpers/trivia';
11
11
  import * as productions from '@bablr/helpers/productions';
12
- import { o, eat, eatMatch, match, fail } from '@bablr/helpers/grammar';
13
- import { buildString, buildIdentifier } from '@bablr/helpers/builders';
14
- import { Node, CoveredBy, AllowEmpty, InjectFrom } from '@bablr/helpers/decorators';
12
+ import { o, eat, eatMatch, match, fail, defineAttribute } from '@bablr/helpers/grammar';
13
+ import { buildString } from '@bablr/helpers/builders';
14
+ import { Node, CoveredBy, AllowEmpty, InjectFrom, Literal } from '@bablr/helpers/decorators';
15
15
  import * as Space from '@bablr/language-en-blank-space';
16
- import { getEmbeddedObject } from '@bablr/agast-vm-helpers/deembed';
17
16
  export const dependencies = {
18
17
  Space
19
18
  };
@@ -31,53 +30,31 @@ const escapables = new Map(Object.entries({
31
30
  function first(iter) {
32
31
  for (let value of iter) return value;
33
32
  }
34
- export const getCooked = (escapeNode, span, ctx) => {
35
- let cooked;
36
- const codeNode = escapeNode.get('code');
37
- if (first(codeNode.children)?.value.flags.token) {
38
- const match_ = ctx.sourceTextFor(codeNode);
39
- cooked = escapables.get(match_) || match_;
40
- } else {
41
- const type = ctx.sourceTextFor(codeNode.get('typeToken'));
42
- const value = ctx.sourceTextFor(codeNode.get('value'));
43
- if (!span.startsWith('String')) {
44
- throw new Error('not implemented');
45
- }
46
- if (type === 'u') {
47
- cooked = parseInt(value, 16);
48
- } else {
49
- throw new Error();
50
- }
51
- }
52
- return cooked.toString(10);
53
- };
54
- export const grammar = triviaEnhancer({
33
+ export const grammar = basicTriviaEnhancer({
55
34
  triviaIsAllowed: s => s.span === 'Bare',
56
- *eatMatchTrivia() {
57
- if (yield match(re`/[ \n\r\t]/`)) {
58
- yield eat(m`#: <*Space:Space />`);
59
- }
60
- }
35
+ triviaMatcher: m`#: :Space: <*Space /[ \n\r\t]/ />`
61
36
  }, class JSONGrammar {
62
37
  static {
63
- [_initProto] = _applyDecs(this, [[_ExpressionDecs, 2, "Expression"], [_ArrayDecs, 2, "Array"], [_ObjectDecs, 2, "Object"], [Node, 2, "Property"], [Node, 2, "Identifier"], [Node, 2, "String"], [[AllowEmpty, Node], 2, "StringContent"], [Node, 2, "EscapeSequence"], [Node, 2, "EscapeCode"], [_NumberDecs, 2, "Number"], [Node, 2, "Integer"], [Node, 2, "UnsignedInteger"], [_InfinityDecs, 2, "Infinity"], [_BooleanDecs, 2, "Boolean"], [_NullDecs, 2, "Null"], [_KeywordDecs, 2, "Keyword"], [_PunctuatorDecs, 2, "Punctuator"], [_ListDecs, 2, "List"], [_AnyDecs, 2, "Any"], [_AllDecs, 2, "All"]], []).e;
38
+ [_initProto] = _applyDecs(this, [[_ExpressionDecs, 2, "Expression"], [_ArrayDecs, 2, "Array"], [_ObjectDecs, 2, "Object"], [Node, 2, "Property"], [_StringDecs, 2, "String"], [[AllowEmpty, Node], 2, "StringContent"], [Node, 2, "EscapeSequence"], [Node, 2, "EscapeCode"], [_NumberDecs, 2, "Number"], [Node, 2, "Integer"], [Node, 2, "UnsignedInteger"], [Node, 2, "UnsignedHexInteger"], [_InfinityDecs, 2, "Infinity"], [_BooleanDecs, 2, "Boolean"], [_NullDecs, 2, "Null"], [_KeywordDecs, 2, "Keyword"], [_PunctuatorDecs, 2, "Punctuator"], [_ListDecs, 2, "List"], [_AnyDecs, 2, "Any"], [_AllDecs, 2, "All"]], []).e;
64
39
  }
65
40
  constructor() {
66
41
  _initProto(this);
67
42
  }
68
- *[(_ExpressionDecs = CoveredBy('Element'), _ArrayDecs = [CoveredBy('Expression'), Node], _ObjectDecs = [CoveredBy('Expression'), Node], _NumberDecs = [CoveredBy('Expression'), Node], _InfinityDecs = [CoveredBy('Expression'), Node], _BooleanDecs = [CoveredBy('Expression'), Node], _NullDecs = [CoveredBy('Expression'), Node], _KeywordDecs = [Node, InjectFrom(productions)], _PunctuatorDecs = [Node, InjectFrom(productions)], _ListDecs = [AllowEmpty, InjectFrom(productions)], _AnyDecs = InjectFrom(productions), _AllDecs = InjectFrom(productions), Symbol.for('@bablr/fragment'))]({
69
- value
43
+ *[(_ExpressionDecs = CoveredBy('Element'), _ArrayDecs = [CoveredBy('Expression'), Node], _ObjectDecs = [CoveredBy('Expression'), Node], _StringDecs = [CoveredBy('Expression'), Node], _NumberDecs = [CoveredBy('Expression'), Node], _InfinityDecs = [CoveredBy('Expression'), Node], _BooleanDecs = [CoveredBy('Expression'), Node], _NullDecs = [CoveredBy('Expression'), Node], _KeywordDecs = [Literal, Node, InjectFrom(productions)], _PunctuatorDecs = [Literal, Node, InjectFrom(productions)], _ListDecs = [AllowEmpty, InjectFrom(productions)], _AnyDecs = InjectFrom(productions), _AllDecs = InjectFrom(productions), Symbol.for('@bablr/fragment'))]({
44
+ props: {
45
+ rootMatcher
46
+ }
70
47
  }) {
71
48
  // needed for the trivia plugin
72
- yield eat(m`<${buildIdentifier(value.productionName)} />`);
49
+ yield eat(rootMatcher);
73
50
  }
74
51
  *Expression() {
75
- yield eat(m`<Any />`, [m`<Array '[' />`, m`<Object '{' />`, m`<String /['"]/ />`, m`<Number /-?\d/ {span: 'Number'} />`, m`<Infinity 'Infinity' />`, m`<Null 'null' />`, m`<Boolean /true|false/ />`]);
52
+ yield eat(m`<_Any />`, [m`<Array '[' />`, m`<Object '{' />`, m`<String /['"]/ />`, m`<Number /\d|-[\d\g]/ {span: 'Number'} />`, m`<Infinity /-?Infinity/ />`, m`<Null 'null' />`, m`<Boolean /true|false/ />`]);
76
53
  }
77
54
  *Array() {
78
55
  yield eat(m`openToken: <*Punctuator '[' { balanced: ']' } />`);
79
- yield eat(m`<List />`, o({
80
- element: m`elements[]$: <Expression />`,
56
+ yield eat(m`<_List />`, o({
57
+ element: m`elements[]+$: <__Expression />`,
81
58
  separator: m`separatorTokens[]: <*Punctuator ',' />`,
82
59
  allowTrailingSeparator: false
83
60
  }));
@@ -89,7 +66,7 @@ export const grammar = triviaEnhancer({
89
66
  yield eatMatch(m`separatorTokens[]: []`);
90
67
  yield eatMatch(m`properties[]$: []`);
91
68
  while (sep && (yield match(re`/.|\g/s`))) {
92
- let suppressGap = !!(yield match(m`<All />`, [m`key: <//>`, m`sigilToken: <*Punctuator ':' />`]));
69
+ let suppressGap = !!(yield match(m`<_All />`, [m`key: <//>`, m`sigilToken: <*Punctuator ':' />`]));
93
70
  yield eat(m`properties[]$: <Property />`, null, o({
94
71
  suppressGap
95
72
  }));
@@ -98,22 +75,14 @@ export const grammar = triviaEnhancer({
98
75
  yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
99
76
  }
100
77
  *Property() {
101
- yield eat(m`key$: <*Identifier />`);
78
+ yield eat(m`key$: <String />`);
102
79
  yield eat(m`sigilToken: <*Punctuator ':' />`);
103
- yield eat(m`value$: <Expression />`);
104
- }
105
- *Identifier() {
106
- yield eat(re`/[a-zA-Z][a-zA-Z_-]*/`);
80
+ yield eat(m`value+$: <__Expression />`);
107
81
  }
108
- *String({
109
- ctx
110
- }) {
111
- let q = yield match(re`/['"]/`);
112
- if (!q) yield fail();
113
- const q_ = ctx.sourceTextFor(q);
114
- yield q_ === "'" ? eat(m`openToken: <*Punctuator "'" { balanced: "'", balancedSpan: 'String:Single' } />`) : eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
82
+ *String() {
83
+ yield eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
115
84
  yield eat(m`content$: <*StringContent />`);
116
- yield q_ === "'" ? eat(m`closeToken: <*Punctuator "'" { balancer: true } />`) : eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
85
+ yield eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
117
86
  }
118
87
  *StringContent({
119
88
  state: {
@@ -137,22 +106,46 @@ export const grammar = triviaEnhancer({
137
106
  }
138
107
  yield eat(m`sigilToken: <*Punctuator '\\' { openSpan: 'Escape' } />`);
139
108
  let match_;
109
+ let cooked;
140
110
  if (match_ = span === 'String:Single' ? yield match(re`/[\\/nrt0']/`) : yield match(re`/[\\/nrt0"]/`)) {
141
111
  const matchText = ctx.sourceTextFor(match_);
142
112
  yield eat(m`code: <*Keyword ${buildString(matchText)} { closeSpan: 'Escape' } />`);
113
+ cooked = escapables.get(matchText) || matchText;
143
114
  } else if (yield match('u')) {
144
- yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
115
+ let codeNode = yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
116
+ if (codeNode && first(codeNode.children)?.value.flags.token) {
117
+ const match_ = ctx.sourceTextFor(codeNode);
118
+ } else {
119
+ const type = ctx.sourceTextFor(codeNode.get('typeToken'));
120
+ if (type) {
121
+ const value = ctx.sourceTextFor(codeNode.get('value'));
122
+ if (!span.startsWith('String')) {
123
+ throw new Error('not implemented');
124
+ }
125
+ if (type === 'u') {
126
+ cooked = String.fromCharCode(parseInt(value, 16));
127
+ } else {
128
+ throw new Error();
129
+ }
130
+ } else {
131
+ let value = ctx.sourceTextFor(codeNode);
132
+ cooked = escapables.get(value) || value;
133
+ }
134
+ }
145
135
  } else {
146
136
  yield fail();
147
137
  }
138
+ yield defineAttribute('cooked', cooked);
148
139
  }
149
140
  *EscapeCode() {
150
141
  if (yield eatMatch(m`typeToken: <*Keyword 'u' />`)) {
151
- if (yield eatMatch(m`openToken: <*Punctuator '{' { balanced: '}' } />`)) {
152
- yield eat(m`value$: <*UnsignedInteger />`);
142
+ if (yield eatMatch(m`openToken: <*Punctuator '{' { balanced: '}' } />`, null, o({
143
+ bind: true
144
+ }))) {
145
+ yield eat(m`value$: <*UnsignedHexInteger />`);
153
146
  yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
154
147
  } else {
155
- yield eat(m`value$: <*UnsignedInteger /\d{4}/ />`);
148
+ yield eat(m`value$: <*UnsignedHexInteger /[\da-fA-F]{4}/ />`);
156
149
  yield eat(m`closeToken: null`);
157
150
  }
158
151
  }
@@ -162,13 +155,17 @@ export const grammar = triviaEnhancer({
162
155
  noDoubleZero: true,
163
156
  matchSign: '-'
164
157
  }));
165
- let fs = yield eatMatch(m`fractionalSeparatorToken: <*Punctuator '.' />`);
158
+ let fs = yield eatMatch(m`fractionalSeparatorToken: <*Punctuator '.' />`, null, o({
159
+ bind: true
160
+ }));
166
161
  if (fs) {
167
- yield eat(m`fractionalPart$: <Integer />`);
162
+ yield eat(m`fractionalPart$: <*UnsignedInteger />`);
168
163
  } else {
169
164
  yield eat(m`fractionalPart$: null`);
170
165
  }
171
- let es = yield eatMatch(m`exponentSeparatorToken: <*Punctuator /[eE]/ />`);
166
+ let es = yield eatMatch(m`exponentSeparatorToken: <*Punctuator /[eE]/ />`, null, o({
167
+ bind: true
168
+ }));
172
169
  if (es) {
173
170
  yield eat(m`exponentPart$: <Integer />`, {
174
171
  matchSign: /[+-]/
@@ -178,14 +175,15 @@ export const grammar = triviaEnhancer({
178
175
  }
179
176
  }
180
177
  *Integer({
181
- value: props
182
- }) {
183
- const {
178
+ props: {
184
179
  matchSign = null,
185
180
  noDoubleZero = false
186
- } = props ? getEmbeddedObject(props) : {};
181
+ }
182
+ }) {
187
183
  if (matchSign) {
188
- yield eatMatch(m`signToken: <*Punctuator ${buildString(matchSign)} />`);
184
+ yield eatMatch(m`signToken: <*Punctuator ${buildString(matchSign)} />`, null, o({
185
+ bind: true
186
+ }));
189
187
  } else {
190
188
  yield eat(m`signToken: null`);
191
189
  }
@@ -194,19 +192,23 @@ export const grammar = triviaEnhancer({
194
192
  }));
195
193
  }
196
194
  *UnsignedInteger({
197
- value: props,
195
+ props: {
196
+ noDoubleZero = false
197
+ },
198
198
  ctx
199
199
  }) {
200
- const {
201
- noDoubleZero = false
202
- } = props || {};
203
200
  let firstDigit = ctx.sourceTextFor(yield eat(re`/\d/`));
204
201
  if (!noDoubleZero || firstDigit.value !== '0') {
205
202
  yield eatMatch(re`/\d+/`);
206
203
  }
207
204
  }
205
+ *UnsignedHexInteger() {
206
+ yield eatMatch(re`/[\da-fA-F]+/`);
207
+ }
208
208
  *Infinity() {
209
- yield eatMatch(m`signToken: <*Punctuator '-' />`);
209
+ yield eatMatch(m`signToken: <*Punctuator '-' />`, null, o({
210
+ bind: true
211
+ }));
210
212
  yield eat(m`sigilToken: <*Keyword 'Infinity' />`);
211
213
  }
212
214
  *Boolean() {
@@ -220,15 +222,4 @@ export const grammar = triviaEnhancer({
220
222
  *List() {}
221
223
  *Any() {}
222
224
  *All() {}
223
- });
224
- export const YJSON = self => {
225
- return {
226
- dependencies: {
227
- ...dependencies,
228
- Y: self
229
- },
230
- canonicalURL,
231
- getCooked,
232
- grammar
233
- };
234
- };
225
+ });
@@ -1,11 +1,10 @@
1
1
  import { re, spam as m } from '@bablr/boot';
2
- import { triviaEnhancer } from '@bablr/helpers/trivia';
2
+ import { basicTriviaEnhancer } from '@bablr/helpers/trivia';
3
3
  import * as productions from '@bablr/helpers/productions';
4
- import { o, eat, eatMatch, match, fail } from '@bablr/helpers/grammar';
5
- import { buildString, buildIdentifier } from '@bablr/helpers/builders';
6
- import { Node, CoveredBy, AllowEmpty, InjectFrom } from '@bablr/helpers/decorators';
4
+ import { o, eat, eatMatch, match, fail, defineAttribute } from '@bablr/helpers/grammar';
5
+ import { buildString } from '@bablr/helpers/builders';
6
+ import { Node, CoveredBy, AllowEmpty, InjectFrom, Literal } from '@bablr/helpers/decorators';
7
7
  import * as Space from '@bablr/language-en-blank-space';
8
- import { getEmbeddedObject } from '@bablr/agast-vm-helpers/deembed';
9
8
 
10
9
  export const dependencies = { Space };
11
10
 
@@ -26,55 +25,25 @@ function first(iter) {
26
25
  for (let value of iter) return value;
27
26
  }
28
27
 
29
- export const getCooked = (escapeNode, span, ctx) => {
30
- let cooked;
31
- const codeNode = escapeNode.get('code');
32
-
33
- if (first(codeNode.children)?.value.flags.token) {
34
- const match_ = ctx.sourceTextFor(codeNode);
35
-
36
- cooked = escapables.get(match_) || match_;
37
- } else {
38
- const type = ctx.sourceTextFor(codeNode.get('typeToken'));
39
- const value = ctx.sourceTextFor(codeNode.get('value'));
40
-
41
- if (!span.startsWith('String')) {
42
- throw new Error('not implemented');
43
- }
44
-
45
- if (type === 'u') {
46
- cooked = parseInt(value, 16);
47
- } else {
48
- throw new Error();
49
- }
50
- }
51
-
52
- return cooked.toString(10);
53
- };
54
-
55
- export const grammar = triviaEnhancer(
28
+ export const grammar = basicTriviaEnhancer(
56
29
  {
57
30
  triviaIsAllowed: (s) => s.span === 'Bare',
58
- *eatMatchTrivia() {
59
- if (yield match(re`/[ \n\r\t]/`)) {
60
- yield eat(m`#: <*Space:Space />`);
61
- }
62
- },
31
+ triviaMatcher: m`#: :Space: <*Space /[ \n\r\t]/ />`,
63
32
  },
64
33
  class JSONGrammar {
65
- *[Symbol.for('@bablr/fragment')]({ value }) {
34
+ *[Symbol.for('@bablr/fragment')]({ props: { rootMatcher } }) {
66
35
  // needed for the trivia plugin
67
- yield eat(m`<${buildIdentifier(value.productionName)} />`);
36
+ yield eat(rootMatcher);
68
37
  }
69
38
 
70
39
  @CoveredBy('Element')
71
40
  *Expression() {
72
- yield eat(m`<Any />`, [
41
+ yield eat(m`<_Any />`, [
73
42
  m`<Array '[' />`,
74
43
  m`<Object '{' />`,
75
44
  m`<String /['"]/ />`,
76
- m`<Number /-?\d/ {span: 'Number'} />`,
77
- m`<Infinity 'Infinity' />`,
45
+ m`<Number /\d|-[\d\g]/ {span: 'Number'} />`,
46
+ m`<Infinity /-?Infinity/ />`,
78
47
  m`<Null 'null' />`,
79
48
  m`<Boolean /true|false/ />`,
80
49
  ]);
@@ -85,9 +54,9 @@ export const grammar = triviaEnhancer(
85
54
  *Array() {
86
55
  yield eat(m`openToken: <*Punctuator '[' { balanced: ']' } />`);
87
56
  yield eat(
88
- m`<List />`,
57
+ m`<_List />`,
89
58
  o({
90
- element: m`elements[]$: <Expression />`,
59
+ element: m`elements[]+$: <__Expression />`,
91
60
  separator: m`separatorTokens[]: <*Punctuator ',' />`,
92
61
  allowTrailingSeparator: false,
93
62
  }),
@@ -105,7 +74,7 @@ export const grammar = triviaEnhancer(
105
74
  yield eatMatch(m`properties[]$: []`);
106
75
 
107
76
  while (sep && (yield match(re`/.|\g/s`))) {
108
- let suppressGap = !!(yield match(m`<All />`, [
77
+ let suppressGap = !!(yield match(m`<_All />`, [
109
78
  m`key: <//>`,
110
79
  m`sigilToken: <*Punctuator ':' />`,
111
80
  ]));
@@ -117,33 +86,19 @@ export const grammar = triviaEnhancer(
117
86
 
118
87
  @Node
119
88
  *Property() {
120
- yield eat(m`key$: <*Identifier />`);
89
+ yield eat(m`key$: <String />`);
121
90
  yield eat(m`sigilToken: <*Punctuator ':' />`);
122
- yield eat(m`value$: <Expression />`);
123
- }
124
-
125
- @Node
126
- *Identifier() {
127
- yield eat(re`/[a-zA-Z][a-zA-Z_-]*/`);
91
+ yield eat(m`value+$: <__Expression />`);
128
92
  }
129
93
 
94
+ @CoveredBy('Expression')
130
95
  @Node
131
- *String({ ctx }) {
132
- let q = yield match(re`/['"]/`);
133
-
134
- if (!q) yield fail();
135
-
136
- const q_ = ctx.sourceTextFor(q);
137
-
138
- yield q_ === "'"
139
- ? eat(m`openToken: <*Punctuator "'" { balanced: "'", balancedSpan: 'String:Single' } />`)
140
- : eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
96
+ *String() {
97
+ yield eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
141
98
 
142
99
  yield eat(m`content$: <*StringContent />`);
143
100
 
144
- yield q_ === "'"
145
- ? eat(m`closeToken: <*Punctuator "'" { balancer: true } />`)
146
- : eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
101
+ yield eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
147
102
  }
148
103
 
149
104
  @AllowEmpty
@@ -168,6 +123,7 @@ export const grammar = triviaEnhancer(
168
123
  yield eat(m`sigilToken: <*Punctuator '\\' { openSpan: 'Escape' } />`);
169
124
 
170
125
  let match_;
126
+ let cooked;
171
127
 
172
128
  if (
173
129
  (match_ =
@@ -175,21 +131,54 @@ export const grammar = triviaEnhancer(
175
131
  ) {
176
132
  const matchText = ctx.sourceTextFor(match_);
177
133
  yield eat(m`code: <*Keyword ${buildString(matchText)} { closeSpan: 'Escape' } />`);
134
+
135
+ cooked = escapables.get(matchText) || matchText;
178
136
  } else if (yield match('u')) {
179
- yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
137
+ let codeNode = yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
138
+
139
+ if (codeNode && first(codeNode.children)?.value.flags.token) {
140
+ const match_ = ctx.sourceTextFor(codeNode);
141
+ } else {
142
+ const type = ctx.sourceTextFor(codeNode.get('typeToken'));
143
+
144
+ if (type) {
145
+ const value = ctx.sourceTextFor(codeNode.get('value'));
146
+
147
+ if (!span.startsWith('String')) {
148
+ throw new Error('not implemented');
149
+ }
150
+
151
+ if (type === 'u') {
152
+ cooked = String.fromCharCode(parseInt(value, 16));
153
+ } else {
154
+ throw new Error();
155
+ }
156
+ } else {
157
+ let value = ctx.sourceTextFor(codeNode);
158
+ cooked = escapables.get(value) || value;
159
+ }
160
+ }
180
161
  } else {
181
162
  yield fail();
182
163
  }
164
+
165
+ yield defineAttribute('cooked', cooked);
183
166
  }
184
167
 
185
168
  @Node
186
169
  *EscapeCode() {
187
170
  if (yield eatMatch(m`typeToken: <*Keyword 'u' />`)) {
188
- if (yield eatMatch(m`openToken: <*Punctuator '{' { balanced: '}' } />`)) {
189
- yield eat(m`value$: <*UnsignedInteger />`);
171
+ if (
172
+ yield eatMatch(
173
+ m`openToken: <*Punctuator '{' { balanced: '}' } />`,
174
+ null,
175
+ o({ bind: true }),
176
+ )
177
+ ) {
178
+ yield eat(m`value$: <*UnsignedHexInteger />`);
190
179
  yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
191
180
  } else {
192
- yield eat(m`value$: <*UnsignedInteger /\d{4}/ />`);
181
+ yield eat(m`value$: <*UnsignedHexInteger /[\da-fA-F]{4}/ />`);
193
182
  yield eat(m`closeToken: null`);
194
183
  }
195
184
  }
@@ -200,15 +189,23 @@ export const grammar = triviaEnhancer(
200
189
  *Number() {
201
190
  yield eat(m`wholePart$: <Integer />`, o({ noDoubleZero: true, matchSign: '-' }));
202
191
 
203
- let fs = yield eatMatch(m`fractionalSeparatorToken: <*Punctuator '.' />`);
192
+ let fs = yield eatMatch(
193
+ m`fractionalSeparatorToken: <*Punctuator '.' />`,
194
+ null,
195
+ o({ bind: true }),
196
+ );
204
197
 
205
198
  if (fs) {
206
- yield eat(m`fractionalPart$: <Integer />`);
199
+ yield eat(m`fractionalPart$: <*UnsignedInteger />`);
207
200
  } else {
208
201
  yield eat(m`fractionalPart$: null`);
209
202
  }
210
203
 
211
- let es = yield eatMatch(m`exponentSeparatorToken: <*Punctuator /[eE]/ />`);
204
+ let es = yield eatMatch(
205
+ m`exponentSeparatorToken: <*Punctuator /[eE]/ />`,
206
+ null,
207
+ o({ bind: true }),
208
+ );
212
209
 
213
210
  if (es) {
214
211
  yield eat(m`exponentPart$: <Integer />`, { matchSign: /[+-]/ });
@@ -218,11 +215,13 @@ export const grammar = triviaEnhancer(
218
215
  }
219
216
 
220
217
  @Node
221
- *Integer({ value: props }) {
222
- const { matchSign = null, noDoubleZero = false } = props ? getEmbeddedObject(props) : {};
223
-
218
+ *Integer({ props: { matchSign = null, noDoubleZero = false } }) {
224
219
  if (matchSign) {
225
- yield eatMatch(m`signToken: <*Punctuator ${buildString(matchSign)} />`);
220
+ yield eatMatch(
221
+ m`signToken: <*Punctuator ${buildString(matchSign)} />`,
222
+ null,
223
+ o({ bind: true }),
224
+ );
226
225
  } else {
227
226
  yield eat(m`signToken: null`);
228
227
  }
@@ -231,9 +230,7 @@ export const grammar = triviaEnhancer(
231
230
  }
232
231
 
233
232
  @Node
234
- *UnsignedInteger({ value: props, ctx }) {
235
- const { noDoubleZero = false } = props || {};
236
-
233
+ *UnsignedInteger({ props: { noDoubleZero = false }, ctx }) {
237
234
  let firstDigit = ctx.sourceTextFor(yield eat(re`/\d/`));
238
235
 
239
236
  if (!noDoubleZero || firstDigit.value !== '0') {
@@ -241,10 +238,15 @@ export const grammar = triviaEnhancer(
241
238
  }
242
239
  }
243
240
 
241
+ @Node
242
+ *UnsignedHexInteger() {
243
+ yield eatMatch(re`/[\da-fA-F]+/`);
244
+ }
245
+
244
246
  @CoveredBy('Expression')
245
247
  @Node
246
248
  *Infinity() {
247
- yield eatMatch(m`signToken: <*Punctuator '-' />`);
249
+ yield eatMatch(m`signToken: <*Punctuator '-' />`, null, o({ bind: true }));
248
250
  yield eat(m`sigilToken: <*Keyword 'Infinity' />`);
249
251
  }
250
252
 
@@ -260,10 +262,12 @@ export const grammar = triviaEnhancer(
260
262
  yield eat(m`sigilToken: <*Keyword 'null' />`);
261
263
  }
262
264
 
265
+ @Literal
263
266
  @Node
264
267
  @InjectFrom(productions)
265
268
  *Keyword() {}
266
269
 
270
+ @Literal
267
271
  @Node
268
272
  @InjectFrom(productions)
269
273
  *Punctuator() {}
@@ -279,15 +283,3 @@ export const grammar = triviaEnhancer(
279
283
  *All() {}
280
284
  },
281
285
  );
282
-
283
- export const YJSON = (self) => {
284
- return {
285
- dependencies: {
286
- ...dependencies,
287
- Y: self,
288
- },
289
- canonicalURL,
290
- getCooked,
291
- grammar,
292
- };
293
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/language-en-json",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "A BABLR language for JSON",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -21,19 +21,19 @@
21
21
  },
22
22
  "sideEffects": false,
23
23
  "dependencies": {
24
- "@bablr/agast-helpers": "0.6.0",
25
- "@bablr/agast-vm-helpers": "0.6.0",
26
- "@bablr/boot": "0.7.0",
27
- "@bablr/helpers": "0.21.1",
28
- "@bablr/language-en-blank-space": "0.6.0",
24
+ "@bablr/agast-helpers": "0.8.0",
25
+ "@bablr/agast-vm-helpers": "0.8.0",
26
+ "@bablr/boot": "0.9.0",
27
+ "@bablr/helpers": "0.23.0",
28
+ "@bablr/language-en-blank-space": "0.8.0",
29
29
  "@babel/runtime": "^7.22.15"
30
30
  },
31
31
  "devDependencies": {
32
- "@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#49f5952efed27f94ee9b94340eb1563c440bf64e",
32
+ "@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#c97bfa4b3663f8378e9b3e42bb5a41e685406cf9",
33
33
  "@bablr/macrome": "^0.1.3",
34
34
  "@bablr/macrome-generator-bablr": "^0.3.2",
35
35
  "@qnighy/dedent": "0.1.1",
36
- "bablr": "^0.6.0",
36
+ "bablr": "^0.7.0",
37
37
  "enhanced-resolve": "^5.12.0",
38
38
  "eslint": "^7.32.0",
39
39
  "eslint-import-resolver-enhanced-resolve": "^1.0.5",