affinirum 1.2.1 → 1.2.3
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/README.md +13 -9
- package/dst/Affinirum.d.ts +1 -2
- package/dst/Affinirum.js +106 -62
- package/dst/Jump.d.ts +1 -0
- package/dst/Jump.js +1 -0
- package/dst/JumpException.d.ts +9 -0
- package/dst/JumpException.js +14 -0
- package/dst/Keywords.js +3 -3
- package/dst/Node.d.ts +1 -1
- package/dst/ParserState.d.ts +9 -5
- package/dst/ParserState.js +84 -43
- package/dst/cjs/Affinirum.js +106 -62
- package/dst/cjs/Jump.js +2 -0
- package/dst/cjs/JumpException.js +18 -0
- package/dst/cjs/Keywords.js +3 -3
- package/dst/cjs/ParserState.js +84 -43
- package/dst/cjs/constant/String.js +1 -1
- package/dst/cjs/node/ArrayNode.js +9 -2
- package/dst/cjs/node/BlockNode.js +15 -2
- package/dst/cjs/node/{CallNode.js → FunctionNode.js} +27 -9
- package/dst/cjs/node/JumpNode.js +31 -0
- package/dst/cjs/node/LoopNode.js +18 -4
- package/dst/cjs/node/ObjectNode.js +7 -4
- package/dst/cjs/node/SwitchNode.js +3 -1
- package/dst/constant/String.js +1 -1
- package/dst/node/ArrayNode.js +9 -2
- package/dst/node/BlockNode.js +15 -2
- package/dst/node/{CallNode.d.ts → FunctionNode.d.ts} +1 -1
- package/dst/node/{CallNode.js → FunctionNode.js} +25 -7
- package/dst/node/JumpNode.d.ts +14 -0
- package/dst/node/JumpNode.js +27 -0
- package/dst/node/LoopNode.js +18 -4
- package/dst/node/ObjectNode.js +7 -4
- package/dst/node/SwitchNode.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,13 +22,15 @@ Target: ES2022 [browser+NodeJS][ESM+CJS].
|
|
|
22
22
|
|
|
23
23
|
## Specifications
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
The value of a block is
|
|
25
|
+
A script may contain multiple expressions separated by semicolons, as well as blocks of statements.
|
|
26
|
+
The value of a block is defined by the value of its last expression.
|
|
27
27
|
- Scientific notation is supported for floating point numbers, like *0.1281e+2*.
|
|
28
28
|
- ISO Timestamps prefixed with **@**, like *@2025-05-11T19:09:21.320Z*.
|
|
29
|
-
- Hexadecimal buffer values are enclosed in
|
|
30
|
-
- String literals
|
|
29
|
+
- Hexadecimal buffer values are enclosed in backticks (**\`**), like *\`10ab0901\`*.
|
|
30
|
+
- String literals may be enclosed in single (**'**), or double (**"**) quotes, like *'string value1'*, or *"string value2"*.
|
|
31
|
+
- Line comments begin with a double slash (**//**), while block comments are enclosed in triple slashes (**///**).
|
|
31
32
|
|
|
33
|
+
### Arrays
|
|
32
34
|
Array is an ordered sequence of values of any type.
|
|
33
35
|
It is defined by comma-separated values enclosed in brackets (**[]**),
|
|
34
36
|
like *[0,1,2]*, *["a","b","c"]*.
|
|
@@ -39,6 +41,7 @@ Array elements can be accessed using the access operator (**.**),
|
|
|
39
41
|
|
|
40
42
|
Easy way to check if array contains an index is to use presence operator (**?**), like *theArray?50*.
|
|
41
43
|
|
|
44
|
+
### Objects
|
|
42
45
|
Object is a container of named values of any type.
|
|
43
46
|
It is defined by comma-separated key-value pair enclosed in brackets (**[]**) where key is separated from value by colon (**:**),
|
|
44
47
|
like *["key1":100, "key2":"abc"]*, *["a":0,"b":"str":"c":valueVar]*.
|
|
@@ -50,13 +53,14 @@ Object properties can be accessed using the access operator (**.**) with a strin
|
|
|
50
53
|
|
|
51
54
|
Easy way to check if object contains a key is to use presence operator (**?**), like *theObject?myKey*.
|
|
52
55
|
|
|
56
|
+
### Functions
|
|
53
57
|
A function is a callable code unit that produces a value.
|
|
54
58
|
The set of built-in functions can be extended through configuration entries.
|
|
55
59
|
Additionally, subroutines (functions defined in code) can be created.
|
|
56
60
|
|
|
57
|
-
Valid variable and function names must start with a letter or underscore (**\_**)
|
|
58
|
-
and can be followed by any combination of alphanumeric characters or underscores,
|
|
59
|
-
like *x*, *\_a1
|
|
61
|
+
Valid variable and function names must start with a letter, number sign (**\#**), dollar sign (**\$**), or underscore (**\_**)
|
|
62
|
+
and can be followed by any combination of alphanumeric characters, number signs, dollar signs, or underscores,
|
|
63
|
+
like *x*, *\_a1$*, *abc25*.
|
|
60
64
|
|
|
61
65
|
Whitespace characters are ignored.
|
|
62
66
|
|
|
@@ -118,7 +122,7 @@ Unknown or variant type is declared as **??**.
|
|
|
118
122
|
- Arithmetic division assignment: **/=**
|
|
119
123
|
- Arithmetic remainder assignment: **%=**
|
|
120
124
|
|
|
121
|
-
### Constants
|
|
125
|
+
### Predefined Constants
|
|
122
126
|
|
|
123
127
|
#### Boolean
|
|
124
128
|
- **boolean Boolean.Or(values:array...)** — Boolean disjunction
|
|
@@ -186,7 +190,7 @@ Unknown or variant type is declared as **??**.
|
|
|
186
190
|
- **void | boolean | float | string | array | object JSON.Parse(value: string)** — Parse JSON-formatted string
|
|
187
191
|
|
|
188
192
|
|
|
189
|
-
### Functions
|
|
193
|
+
### Predefined Functions
|
|
190
194
|
|
|
191
195
|
#### General Functions
|
|
192
196
|
- **?? ??.Coalesce(otherwise: ??)** — Null coalescence
|
package/dst/Affinirum.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export declare class Affinirum {
|
|
|
54
54
|
@returns Calculated value.
|
|
55
55
|
*/
|
|
56
56
|
evaluate(values?: Record<string, Value>): Value;
|
|
57
|
-
protected
|
|
57
|
+
protected _list(state: ParserState, scope: StaticScope): Node;
|
|
58
58
|
protected _unit(state: ParserState, scope: StaticScope): Node;
|
|
59
59
|
protected _coalescence(state: ParserState, scope: StaticScope): Node;
|
|
60
60
|
protected _disjunction(state: ParserState, scope: StaticScope): Node;
|
|
@@ -70,6 +70,5 @@ export declare class Affinirum {
|
|
|
70
70
|
protected _function(state: ParserState, scope: StaticScope): Node;
|
|
71
71
|
protected _loop(state: ParserState, scope: StaticScope): LoopNode;
|
|
72
72
|
protected _switch(state: ParserState, scope: StaticScope): SwitchNode;
|
|
73
|
-
protected _call(frame: ParserFrame, func: Constant, subnodes: Node[]): Node;
|
|
74
73
|
protected _type(state: ParserState, scope: StaticScope): Type;
|
|
75
74
|
}
|
package/dst/Affinirum.js
CHANGED
|
@@ -12,13 +12,15 @@ import { Functions } from "./Functions.js";
|
|
|
12
12
|
import { ArrayNode } from "./node/ArrayNode.js";
|
|
13
13
|
import { BlockNode } from "./node/BlockNode.js";
|
|
14
14
|
import { ConstantNode } from "./node/ConstantNode.js";
|
|
15
|
-
import {
|
|
15
|
+
import { FunctionNode } from "./node/FunctionNode.js";
|
|
16
|
+
import { JumpNode } from "./node/JumpNode.js";
|
|
16
17
|
import { LoopNode } from "./node/LoopNode.js";
|
|
17
18
|
import { ObjectNode } from "./node/ObjectNode.js";
|
|
18
19
|
import { SwitchNode } from "./node/SwitchNode.js";
|
|
19
20
|
import { VariableNode } from "./node/VariableNode.js";
|
|
20
21
|
import { ParserState } from "./ParserState.js";
|
|
21
22
|
import { StaticScope } from "./StaticScope.js";
|
|
23
|
+
import { JumpException } from "./JumpException.js";
|
|
22
24
|
export class Affinirum {
|
|
23
25
|
static keywords = [...Keywords, ...Constants.map((c) => c[0])];
|
|
24
26
|
_script;
|
|
@@ -45,8 +47,8 @@ export class Affinirum {
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
const state = new ParserState(this._script);
|
|
48
|
-
this._root = this.
|
|
49
|
-
if (!state.
|
|
50
|
+
this._root = this._list(state.next(), this._scope);
|
|
51
|
+
if (!state.isEmpty) {
|
|
50
52
|
state.throwError("unexpected expression token or expression end");
|
|
51
53
|
}
|
|
52
54
|
this._root = this._root.compile(config?.type ?? Type.Unknown);
|
|
@@ -100,15 +102,34 @@ export class Affinirum {
|
|
|
100
102
|
}
|
|
101
103
|
variable.value = value;
|
|
102
104
|
}
|
|
103
|
-
|
|
105
|
+
try {
|
|
106
|
+
return this._root.evaluate();
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
if (e instanceof JumpException) {
|
|
110
|
+
if (e.jump === "exit") {
|
|
111
|
+
return e.value;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
throw this._root.throwError(`unexpected ${e.jump} jump`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
throw e;
|
|
118
|
+
}
|
|
104
119
|
}
|
|
105
|
-
|
|
120
|
+
_list(state, scope) {
|
|
106
121
|
const frame = state.starts();
|
|
107
|
-
const
|
|
108
|
-
while (state.
|
|
109
|
-
|
|
122
|
+
const subnodes = [];
|
|
123
|
+
while (!state.isEmpty) {
|
|
124
|
+
subnodes.push(this._unit(state, scope));
|
|
125
|
+
if (!state.isSemicolon) {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
state.next();
|
|
130
|
+
}
|
|
110
131
|
}
|
|
111
|
-
return new BlockNode(frame.ends(state),
|
|
132
|
+
return new BlockNode(frame.ends(state), subnodes);
|
|
112
133
|
}
|
|
113
134
|
_unit(state, scope) {
|
|
114
135
|
return this._coalescence(state, scope);
|
|
@@ -116,21 +137,24 @@ export class Affinirum {
|
|
|
116
137
|
_coalescence(state, scope) {
|
|
117
138
|
let node = this._disjunction(state, scope);
|
|
118
139
|
while (state.operator === funcCoalesce) {
|
|
119
|
-
|
|
140
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
141
|
+
node = new FunctionNode(state, fnode, [node, this._disjunction(state.next(), scope)]);
|
|
120
142
|
}
|
|
121
143
|
return node;
|
|
122
144
|
}
|
|
123
145
|
_disjunction(state, scope) {
|
|
124
146
|
let node = this._conjunction(state, scope);
|
|
125
147
|
while (state.operator === funcOr) {
|
|
126
|
-
|
|
148
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
149
|
+
node = new FunctionNode(state, fnode, [node, this._conjunction(state.next(), scope)]);
|
|
127
150
|
}
|
|
128
151
|
return node;
|
|
129
152
|
}
|
|
130
153
|
_conjunction(state, scope) {
|
|
131
154
|
let node = this._negation(state, scope);
|
|
132
155
|
while (state.operator === funcAnd) {
|
|
133
|
-
|
|
156
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
157
|
+
node = new FunctionNode(state, fnode, [node, this._negation(state.next(), scope)]);
|
|
134
158
|
}
|
|
135
159
|
return node;
|
|
136
160
|
}
|
|
@@ -144,7 +168,8 @@ export class Affinirum {
|
|
|
144
168
|
}
|
|
145
169
|
let node = this._comparison(state, scope);
|
|
146
170
|
if (negate) {
|
|
147
|
-
|
|
171
|
+
const fnode = new ConstantNode(frame, funcNot);
|
|
172
|
+
node = new FunctionNode(frame, fnode, [node]);
|
|
148
173
|
}
|
|
149
174
|
return node;
|
|
150
175
|
}
|
|
@@ -153,21 +178,24 @@ export class Affinirum {
|
|
|
153
178
|
while (state.operator === funcGreaterThan || state.operator === funcLessThan
|
|
154
179
|
|| state.operator === funcGreaterOrEqual || state.operator === funcLessOrEqual
|
|
155
180
|
|| state.operator === funcEqual || state.operator === funcNotEqual) {
|
|
156
|
-
|
|
181
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
182
|
+
node = new FunctionNode(state, fnode, [node, this._aggregate(state.next(), scope)]);
|
|
157
183
|
}
|
|
158
184
|
return node;
|
|
159
185
|
}
|
|
160
186
|
_aggregate(state, scope) {
|
|
161
187
|
let node = this._product(state, scope);
|
|
162
188
|
while (state.operator === funcAdd || state.operator === funcSubtract) {
|
|
163
|
-
|
|
189
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
190
|
+
node = new FunctionNode(state, fnode, [node, this._product(state.next(), scope)]);
|
|
164
191
|
}
|
|
165
192
|
return node;
|
|
166
193
|
}
|
|
167
194
|
_product(state, scope) {
|
|
168
195
|
let node = this._signum(state, scope);
|
|
169
196
|
while (state.operator === funcMultiply || state.operator === funcDivide || state.operator === funcRemainder) {
|
|
170
|
-
|
|
197
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
198
|
+
node = new FunctionNode(state, fnode, [node, this._signum(state.next(), scope)]);
|
|
171
199
|
}
|
|
172
200
|
return node;
|
|
173
201
|
}
|
|
@@ -183,14 +211,16 @@ export class Affinirum {
|
|
|
183
211
|
}
|
|
184
212
|
let node = this._factor(state, scope);
|
|
185
213
|
if (negate) {
|
|
186
|
-
|
|
214
|
+
const fnode = new ConstantNode(frame, funcNegate);
|
|
215
|
+
node = new FunctionNode(frame, fnode, [node]);
|
|
187
216
|
}
|
|
188
217
|
return node;
|
|
189
218
|
}
|
|
190
219
|
_factor(state, scope) {
|
|
191
220
|
let node = this._accessor(state, scope);
|
|
192
221
|
while (state.operator === funcPower) {
|
|
193
|
-
|
|
222
|
+
const fnode = new ConstantNode(state, state.operator);
|
|
223
|
+
node = new FunctionNode(state, fnode, [node, this._accessor(state.next(), scope)]);
|
|
194
224
|
}
|
|
195
225
|
return node;
|
|
196
226
|
}
|
|
@@ -201,11 +231,11 @@ export class Affinirum {
|
|
|
201
231
|
if (state.isDot || state.isQuestion) {
|
|
202
232
|
const operator = state.isDot ? funcAt : funcHas;
|
|
203
233
|
if (state.next().isLiteral && (typeof state.literal.value === "string" || typeof state.literal.value === "bigint")) {
|
|
204
|
-
|
|
234
|
+
const fnode = new ConstantNode(frame.ends(state), operator);
|
|
235
|
+
node = new FunctionNode(frame, fnode, [node, new ConstantNode(state, new Constant(state.literal.value))]);
|
|
205
236
|
state.next();
|
|
206
237
|
}
|
|
207
238
|
else if (state.isToken) {
|
|
208
|
-
frame.ends(state);
|
|
209
239
|
const func = this._functions.get(state.token);
|
|
210
240
|
if (func) {
|
|
211
241
|
if (state.next().isParenthesesOpen) {
|
|
@@ -216,15 +246,18 @@ export class Affinirum {
|
|
|
216
246
|
break;
|
|
217
247
|
}
|
|
218
248
|
}
|
|
219
|
-
|
|
249
|
+
const fnode = new ConstantNode(frame.ends(state), func);
|
|
250
|
+
node = new FunctionNode(frame, fnode, subnodes);
|
|
220
251
|
state.closeParentheses().next();
|
|
221
252
|
}
|
|
222
253
|
else {
|
|
223
|
-
|
|
254
|
+
const fnode = new ConstantNode(frame.ends(state), func);
|
|
255
|
+
node = new FunctionNode(frame, fnode, [node]);
|
|
224
256
|
}
|
|
225
257
|
}
|
|
226
258
|
else {
|
|
227
|
-
|
|
259
|
+
const fnode = new ConstantNode(frame.ends(), operator);
|
|
260
|
+
node = new FunctionNode(frame, fnode, [node, new ConstantNode(state, new Constant(state.token))]);
|
|
228
261
|
state.next();
|
|
229
262
|
}
|
|
230
263
|
}
|
|
@@ -240,11 +273,12 @@ export class Affinirum {
|
|
|
240
273
|
break;
|
|
241
274
|
}
|
|
242
275
|
}
|
|
243
|
-
node = new
|
|
276
|
+
node = new FunctionNode(frame.ends(state), node, subnodes);
|
|
244
277
|
state.closeParentheses().next();
|
|
245
278
|
}
|
|
246
279
|
else if (state.isBracketsOpen) {
|
|
247
|
-
|
|
280
|
+
const fnode = new ConstantNode(frame, funcAt);
|
|
281
|
+
node = new FunctionNode(frame, fnode, [node, this._unit(state.next(), scope)]);
|
|
248
282
|
state.closeBrackets().next();
|
|
249
283
|
}
|
|
250
284
|
}
|
|
@@ -296,19 +330,29 @@ export class Affinirum {
|
|
|
296
330
|
}
|
|
297
331
|
if (state.assignment.operator) {
|
|
298
332
|
const operator = state.assignment.operator;
|
|
299
|
-
const
|
|
300
|
-
|
|
333
|
+
const fnode = new ConstantNode(frame, operator);
|
|
334
|
+
const subnode = new FunctionNode(frame, fnode, [new VariableNode(frame, variable), this._unit(state.next(), scope)]);
|
|
335
|
+
return new VariableNode(frame, variable, subnode);
|
|
301
336
|
}
|
|
302
337
|
else {
|
|
303
|
-
|
|
338
|
+
const subnode = this._unit(state.next(), scope);
|
|
339
|
+
return new VariableNode(frame, variable, subnode);
|
|
304
340
|
}
|
|
305
341
|
}
|
|
306
342
|
return new VariableNode(frame, variable);
|
|
307
343
|
}
|
|
308
344
|
else if (state.isBracesOpen) {
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
345
|
+
const frame = state.starts();
|
|
346
|
+
const subnodes = [];
|
|
347
|
+
while (!state.next().isBracesClose) {
|
|
348
|
+
subnodes.push(this._unit(state, scope));
|
|
349
|
+
if (!state.isSemicolon) {
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
frame.ends(state);
|
|
354
|
+
state.next();
|
|
355
|
+
return new BlockNode(frame, subnodes);
|
|
312
356
|
}
|
|
313
357
|
else if (state.isBracesClose) {
|
|
314
358
|
state.throwError("unexpected closing braces");
|
|
@@ -344,7 +388,7 @@ export class Affinirum {
|
|
|
344
388
|
}
|
|
345
389
|
}
|
|
346
390
|
frame.ends(state);
|
|
347
|
-
state.
|
|
391
|
+
state.next();
|
|
348
392
|
if (colon) {
|
|
349
393
|
return new ObjectNode(frame, subnodes.map(([k, v]) => [typeof k === "number" ? new ConstantNode(v, new Constant(String(k))) : k, v]));
|
|
350
394
|
}
|
|
@@ -353,8 +397,8 @@ export class Affinirum {
|
|
|
353
397
|
else if (state.isBracketsClose) {
|
|
354
398
|
state.throwError("unexpected closing brackets");
|
|
355
399
|
}
|
|
356
|
-
else if (state.
|
|
357
|
-
const assignable = state.
|
|
400
|
+
else if (state.isVar || state.isVal) {
|
|
401
|
+
const assignable = state.isVar;
|
|
358
402
|
if (!state.next().isToken) {
|
|
359
403
|
state.throwError("missing variable name");
|
|
360
404
|
}
|
|
@@ -380,13 +424,29 @@ export class Affinirum {
|
|
|
380
424
|
else if (state.isTilda) {
|
|
381
425
|
return this._function(state, scope);
|
|
382
426
|
}
|
|
427
|
+
else if (state.isIf) {
|
|
428
|
+
return this._switch(state, scope);
|
|
429
|
+
}
|
|
383
430
|
else if (state.isWhile) {
|
|
384
431
|
return this._loop(state, scope);
|
|
385
432
|
}
|
|
386
|
-
else if (state.
|
|
387
|
-
return this.
|
|
433
|
+
else if (state.isExit) {
|
|
434
|
+
return new JumpNode(state, "exit", this._unit(state.next(), scope));
|
|
435
|
+
}
|
|
436
|
+
else if (state.isReturn) {
|
|
437
|
+
return new JumpNode(state, "return", this._unit(state.next(), scope));
|
|
388
438
|
}
|
|
389
|
-
else if (state.
|
|
439
|
+
else if (state.isStop) {
|
|
440
|
+
const node = new JumpNode(state, "stop");
|
|
441
|
+
state.next();
|
|
442
|
+
return node;
|
|
443
|
+
}
|
|
444
|
+
else if (state.isNext) {
|
|
445
|
+
const node = new JumpNode(state, "next");
|
|
446
|
+
state.next();
|
|
447
|
+
return node;
|
|
448
|
+
}
|
|
449
|
+
else if (state.isEmpty) {
|
|
390
450
|
state.throwError("unexpected end of expression");
|
|
391
451
|
}
|
|
392
452
|
state.throwError("unexpected expression token");
|
|
@@ -430,45 +490,29 @@ export class Affinirum {
|
|
|
430
490
|
state.closeParentheses();
|
|
431
491
|
frame.ends(state);
|
|
432
492
|
const args = Array.from(variables.values());
|
|
433
|
-
state.next().
|
|
434
|
-
const
|
|
435
|
-
state.closeBraces().next();
|
|
436
|
-
const value = (...values) => {
|
|
493
|
+
const subnode = this._unit(state.next(), scope.subscope(variables));
|
|
494
|
+
const func = (...values) => {
|
|
437
495
|
args.forEach((arg, ix) => arg.value = values[ix]);
|
|
438
496
|
return subnode.evaluate();
|
|
439
497
|
};
|
|
440
|
-
const constant = new Constant(
|
|
498
|
+
const constant = new Constant(func, Type.functionType(retType, args.map((v) => v.type), variadic));
|
|
441
499
|
return new ConstantNode(frame, constant, subnode);
|
|
442
500
|
}
|
|
443
501
|
_loop(state, scope) {
|
|
444
502
|
const frame = state.starts();
|
|
445
503
|
const cnode = this._unit(state.next(), scope);
|
|
446
504
|
frame.ends(state);
|
|
447
|
-
|
|
448
|
-
const subnode = this._block(state, scope);
|
|
449
|
-
state.closeBraces().next();
|
|
450
|
-
return new LoopNode(frame, cnode, subnode);
|
|
505
|
+
return new LoopNode(frame, cnode, this._unit(state, scope));
|
|
451
506
|
}
|
|
452
507
|
_switch(state, scope) {
|
|
453
508
|
const frame = state.starts();
|
|
454
509
|
const cnode = this._unit(state.next(), scope);
|
|
455
510
|
frame.ends(state);
|
|
456
|
-
const
|
|
457
|
-
state.
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
state.next().openBraces().next();
|
|
462
|
-
subnodes.push(this._block(state, scope));
|
|
463
|
-
state.closeBraces().next();
|
|
464
|
-
}
|
|
465
|
-
else {
|
|
466
|
-
subnodes.push(new ConstantNode(state.starts(), Constant.Null));
|
|
467
|
-
}
|
|
468
|
-
return new SwitchNode(frame, cnode, subnodes);
|
|
469
|
-
}
|
|
470
|
-
_call(frame, func, subnodes) {
|
|
471
|
-
return new CallNode(frame, new ConstantNode(frame, func), subnodes);
|
|
511
|
+
const cthen = this._unit(state, scope);
|
|
512
|
+
const celse = state.isElse
|
|
513
|
+
? this._unit(state.next(), scope)
|
|
514
|
+
: new ConstantNode(state.starts(), Constant.Null);
|
|
515
|
+
return new SwitchNode(frame, cnode, [cthen, celse]);
|
|
472
516
|
}
|
|
473
517
|
_type(state, scope) {
|
|
474
518
|
if (state.isType) {
|
package/dst/Jump.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Jump = "exit" | "return" | "stop" | "next";
|
package/dst/Jump.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dst/Keywords.js
CHANGED
package/dst/Node.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ParserFrame } from "./ParserFrame.js";
|
|
2
|
-
import { Value } from "./Value.js";
|
|
3
2
|
import { Type } from "./Type.js";
|
|
3
|
+
import { Value } from "./Value.js";
|
|
4
4
|
export declare abstract class Node extends ParserFrame {
|
|
5
5
|
constructor(frame: ParserFrame);
|
|
6
6
|
abstract type: Type;
|
package/dst/ParserState.d.ts
CHANGED
|
@@ -34,14 +34,18 @@ export declare class ParserState extends ParserFrame {
|
|
|
34
34
|
get isComma(): boolean;
|
|
35
35
|
get isDot(): boolean;
|
|
36
36
|
get isQuestion(): boolean;
|
|
37
|
-
get isTilda(): boolean;
|
|
38
37
|
get isEllipsis(): boolean;
|
|
39
|
-
get
|
|
40
|
-
get
|
|
41
|
-
get
|
|
38
|
+
get isTilda(): boolean;
|
|
39
|
+
get isVar(): boolean;
|
|
40
|
+
get isVal(): boolean;
|
|
42
41
|
get isIf(): boolean;
|
|
43
42
|
get isElse(): boolean;
|
|
44
|
-
get
|
|
43
|
+
get isWhile(): boolean;
|
|
44
|
+
get isExit(): boolean;
|
|
45
|
+
get isReturn(): boolean;
|
|
46
|
+
get isStop(): boolean;
|
|
47
|
+
get isNext(): boolean;
|
|
48
|
+
get isEmpty(): boolean;
|
|
45
49
|
openParentheses(): this;
|
|
46
50
|
closeParentheses(): this;
|
|
47
51
|
openBrackets(): this;
|