@bablr/language-en-spamex 0.5.0 → 0.7.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.
@@ -1,130 +1,146 @@
1
- import { i } from '@bablr/boot/shorthand.macro';
2
- import { Node, CoveredBy, InjectFrom } from '@bablr/helpers/decorators';
1
+ import { re, spam as m } from '@bablr/boot';
2
+ import { Node, CoveredBy, InjectFrom, UnboundAttributes } from '@bablr/helpers/decorators';
3
3
  import * as productions from '@bablr/helpers/productions';
4
+ import { o, eat, eatMatch, match, bindAttribute, fail } from '@bablr/helpers/grammar';
4
5
  import * as Regex from '@bablr/language-en-regex-vm-pattern';
5
6
  import * as CSTML from '@bablr/language-en-cstml';
7
+ import * as JSON from '@bablr/language-en-cstml-json';
6
8
  import * as Space from '@bablr/language-en-blank-space';
7
9
  import { notNull } from '@bablr/agast-helpers/tree';
8
10
 
9
11
  export const canonicalURL = 'https://bablr.org/languages/core/en/spamex';
10
12
 
11
- export const dependencies = { Regex, CSTML, Space };
13
+ export const dependencies = { Regex, CSTML, JSON, Space };
12
14
 
13
15
  const { eatMatchTrivia } = CSTML;
14
16
 
15
17
  export const grammar = class SpamexGrammar {
18
+ @CoveredBy('Expression')
19
+ *Matcher() {
20
+ yield eat(m`<Any />`, [m`<PropertyMatcher /[a-zA-Z.@#<]/ />`, m`<StringMatcher /[/'"]/ />`]);
21
+ }
22
+
23
+ *NodeMatcher() {
24
+ yield eat(m`<Any />`, [
25
+ m`<GapNodeMatcher '<//>' />`,
26
+ m`<BasicNodeMatcher '<' />`,
27
+ m`<ArrayNodeMatcher '[' />`,
28
+ m`<NullNodeMatcher 'null' />`,
29
+ ]);
30
+ }
31
+
16
32
  @Node
17
- *Pattern() {
18
- yield i`eat(<Matcher /> 'matcher')`;
33
+ @CoveredBy('NodeMatcher')
34
+ *GapNodeMatcher() {
35
+ yield eat(m`sigilToken: <*Punctuator '<//>' />`);
19
36
  }
20
37
 
21
- @CoveredBy('Expression')
22
- *Matcher() {
23
- yield i`eat(<Any /> null [
24
- <NodeMatcher '<' />
25
- <CSTML:String /['"]/ />
26
- <Regex:Pattern '/' />
27
- ])`;
38
+ @Node
39
+ @CoveredBy('NodeMatcher')
40
+ *ArrayNodeMatcher() {
41
+ yield eat(m`sigilToken: <*Punctuator '[]' />`);
42
+ }
43
+
44
+ @Node
45
+ @CoveredBy('NodeMatcher')
46
+ *NullNodeMatcher() {
47
+ yield eat(m`sigilToken: <*Punctuator 'null' />`);
28
48
  }
29
49
 
30
50
  @Node
31
51
  @CoveredBy('Matcher')
32
- *NodeMatcher() {
33
- let open = yield i`eat(<OpenNodeMatcher /> 'open')`;
52
+ *PropertyMatcher() {
53
+ yield eatMatch(m`refMatcher: <ReferenceMatcher />`);
54
+ yield* eatMatchTrivia();
55
+ yield eat(m`nodeMatcher: <NodeMatcher />`);
56
+ }
57
+
58
+ @Node
59
+ *ReferenceMatcher() {
60
+ let name;
61
+ if (yield match(re`/[.#@]/`)) {
62
+ name = yield eatMatch(m`name$: <*Punctuator /[.#@]/ />`);
63
+ } else {
64
+ name = yield eatMatch(m`name$: <*CSTML:Identifier />`);
65
+ }
66
+
67
+ if (name && (yield eatMatch(m`openIndexToken: <*Punctuator '[' { balanced: ']' } />`))) {
68
+ yield* eatMatchTrivia();
69
+ yield eatMatch(m`closeIndexToken: <*Punctuator ']' { balancer: true } />`);
70
+ } else {
71
+ yield eatMatch(m`closeIndexToken: null`);
72
+ }
73
+
74
+ yield* eatMatchTrivia();
75
+ yield eatMatch(m`flags: <CSTML:ReferenceFlags />`);
76
+ yield* eatMatchTrivia();
77
+ yield eat(m`sigilToken: <*Punctuator ':' />`);
78
+ }
79
+
80
+ @Node
81
+ @CoveredBy('NodeMatcher')
82
+ *BasicNodeMatcher() {
83
+ let open = yield eat(m`open: <OpenNodeMatcher />`);
34
84
 
35
- // Problem: not handling gaps
36
- // gaps have a non-nullish representation
37
- //
38
- const { selfClosingTagToken } = open.properties;
39
- const selfClosing = notNull(selfClosingTagToken);
85
+ const selfClosing = notNull(open.get('selfClosingTagToken'));
40
86
 
41
87
  if (selfClosing) {
42
- yield i`eat([] 'children[]')`;
43
- yield i`eat(null 'close')`;
88
+ yield eat(m`children[]$: []`);
89
+ yield eat(m`close: null`);
44
90
  } else {
45
91
  // TODO
46
92
  yield* eatMatchTrivia();
47
93
 
48
- yield i`eat(<CloseNodeMatcher /> 'close')`;
94
+ yield eat(m`close: <CloseNodeMatcher />`);
49
95
  }
50
96
  }
51
97
 
52
98
  @Node
53
99
  *OpenNodeMatcher() {
54
- yield i`eat(<~*Punctuator '<' balancedSpan='Tag' balanced='>' /> 'open')`;
55
- yield i`eat(<CSTML:Flags /> 'flags')`;
56
- if (yield i`match(/[a-zA-Z]+:/)`) {
57
- yield i`eat(<*CSTML:Identifier /> 'language')`;
58
- yield i`eat(<~*Punctuator ':' /> 'namespaceOperator')`;
59
- yield i`eat(<*CSTML:Identifier /> 'type')`;
60
- } else if (yield i`match(/[a-zA-Z]/)`) {
61
- yield i`eat(null 'language')`;
62
- yield i`eat(null 'namespaceOperator')`;
63
- yield i`eatMatch(<*CSTML:Identifier /> 'type')`;
64
- } else if (yield i`match('?')`) {
65
- yield i`eat(<~*Punctuator '?' /> 'type')`;
66
- } else if (yield i`match(/[ \t]/)`) {
67
- yield i`eatMatch(<~*Punctuator /[ \t]+/ /> 'type')`;
100
+ yield eat(m`open: <*Punctuator '<' { balancedSpan: 'Tag', balanced: '>' } />`);
101
+ yield eat(m`flags: <CSTML:NodeFlags />`);
102
+
103
+ if (yield eatMatch(m`<CSTML:TagType /[a-zA-Z'"\g]/ />`)) {
104
+ // continue
105
+ } else if (yield eatMatch(m`type$: <*Punctuator /[ \t]+|?/ />`)) {
106
+ // continue
107
+ } else {
108
+ yield fail();
68
109
  }
110
+
69
111
  let sp = yield* eatMatchTrivia();
70
112
 
71
- if (sp && (yield i`eatMatch(<StringMatcher /> 'intrinsicValue')`)) {
113
+ if (
114
+ sp &&
115
+ !(yield match(re`/\/$/`)) &&
116
+ (yield eatMatch(m`intrinsicValue$: <StringMatcher />`))
117
+ ) {
72
118
  sp = yield* eatMatchTrivia();
73
119
  }
74
120
 
75
- while (sp && (yield i`match(/!?[a-zA-Z]/)`)) {
76
- yield i`eat(<Attribute /> 'attributes[]')`;
121
+ while (sp && (yield match('{'))) {
122
+ yield eat(m`attributes: <JSON:Object />`);
77
123
  sp = yield* eatMatchTrivia();
78
124
  }
79
125
 
80
- yield i`eatMatch(<~*Punctuator '/' /> 'selfClosingTagToken')`;
81
- yield i`eat(<~*Punctuator '>' balancer /> 'close')`;
126
+ yield eatMatch(m`selfClosingTagToken: <*Punctuator '/' />`);
127
+ yield eat(m`close: <*Punctuator '>' { balancer: true } />`);
82
128
  }
83
129
 
84
130
  @Node
85
131
  @CoveredBy('Matcher')
86
132
  *CloseNodeMatcher() {
87
- yield i`eat(<~*Punctuator '</' balanced='>' /> 'openToken')`;
88
- yield i`eatMatch(<TagType />)`;
89
- yield i`eat(<~*Punctuator '>' balancer /> 'closeToken')`;
90
- }
91
-
92
- *Attributes() {
93
- yield i`eatMatch(<List /> null {
94
- element: <Attribute />
95
- allowTrailingSeparator: false
96
- })`;
97
- }
98
-
99
- *Attribute() {
100
- if (yield i`match(/[a-zA-Z]+\s*=/)`) {
101
- yield i`eat(<MappingAttribute />)`;
102
- } else {
103
- yield i`eat(<BooleanAttribute />)`;
104
- }
105
- }
106
-
107
- @CoveredBy('Attribute')
108
- @Node
109
- *BooleanAttribute() {
110
- yield i`eat(<*CSTML:Identifier /> 'key')`;
111
- }
112
-
113
- @CoveredBy('Attribute')
114
- @Node
115
- *MappingAttribute() {
116
- yield i`eat(<*CSTML:Identifier /> 'key')`;
117
- yield i`eat(<~*Punctuator '=' /> 'mapOperator')`;
118
- yield i`eat(<CSTML:AttributeValue /> 'value')`;
133
+ yield eat(m`openToken: <*Punctuator '</' { balanced: '>' } />`);
134
+ yield eat(m`closeToken: <*Punctuator '>' { balancer: true } />`);
119
135
  }
120
136
 
121
137
  @CoveredBy('Matcher')
122
138
  @CoveredBy('Expression')
123
139
  *StringMatcher() {
124
- if (yield i`match(/['"]/)`) {
125
- yield i`eat(<CSTML:String />)`;
140
+ if (yield match(re`/['"]/`)) {
141
+ yield eat(m`<String />`);
126
142
  } else {
127
- yield i`eat(<Regex:Pattern />)`;
143
+ yield eat(m`<Regex />`);
128
144
  }
129
145
  }
130
146
 
@@ -133,7 +149,7 @@ export const grammar = class SpamexGrammar {
133
149
  @CoveredBy('Expression')
134
150
  @Node
135
151
  *String() {
136
- yield i`eat(<CSTML:String />)`;
152
+ yield eat(m`<JSON:String />`, null, o({ suppressNode: true }));
137
153
  }
138
154
 
139
155
  @CoveredBy('StringMatcher')
@@ -141,10 +157,7 @@ export const grammar = class SpamexGrammar {
141
157
  @CoveredBy('Expression')
142
158
  @Node
143
159
  *Regex() {
144
- yield i`eat(<~*Punctuator '/' balanced='/' /> 'open')`;
145
- yield i`eat(<Regex:Alternatives /> 'alternatives[]')`;
146
- yield i`eat(<~*Punctuator '/' balancer /> 'close')`;
147
- yield i`eat(<Regex:Flags /> 'flags')`;
160
+ yield eat(m`<Regex:Pattern />`, null, o({ suppressNode: true }));
148
161
  }
149
162
 
150
163
  @InjectFrom(productions)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/language-en-spamex",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "A BABLR language for SPAM Expressions",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -22,18 +22,19 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@babel/runtime": "^7.23.2",
25
- "@bablr/agast-helpers": "0.4.0",
26
- "@bablr/agast-vm-helpers": "0.4.0",
27
- "@bablr/helpers": "0.19.0",
28
- "@bablr/language-en-blank-space": "0.4.0",
29
- "@bablr/language-en-cstml": "0.5.0",
30
- "@bablr/language-en-regex-vm-pattern": "0.6.0"
25
+ "@bablr/agast-helpers": "0.6.0",
26
+ "@bablr/agast-vm-helpers": "0.6.0",
27
+ "@bablr/helpers": "0.21.1",
28
+ "@bablr/language-en-blank-space": "0.6.0",
29
+ "@bablr/language-en-cstml": "0.8.0",
30
+ "@bablr/language-en-cstml-json": "0.1.0",
31
+ "@bablr/language-en-regex-vm-pattern": "0.8.0"
31
32
  },
32
33
  "devDependencies": {
33
- "@bablr/boot": "0.5.0",
34
+ "@bablr/boot": "^0.7.0",
34
35
  "@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#49f5952efed27f94ee9b94340eb1563c440bf64e",
35
- "@bablr/macrome": "0.1.3",
36
- "@bablr/macrome-generator-bablr": "0.3.2",
36
+ "@bablr/macrome": "^0.1.3",
37
+ "@bablr/macrome-generator-bablr": "^0.3.2",
37
38
  "enhanced-resolve": "^5.12.0",
38
39
  "eslint": "^7.32.0",
39
40
  "eslint-import-resolver-enhanced-resolve": "^1.0.5",