@jbrowse/jexl 3.0.2 → 3.2.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/README.md +26 -2
- package/dist/Expression.d.ts +19 -7
- package/dist/Expression.js +32 -11
- package/dist/Expression.js.map +1 -1
- package/dist/Jexl.d.ts +13 -12
- package/dist/Jexl.js +31 -30
- package/dist/Jexl.js.map +1 -1
- package/dist/Lexer.d.ts +9 -9
- package/dist/Lexer.js +61 -24
- package/dist/Lexer.js.map +1 -1
- package/dist/evaluator/Evaluator.d.ts +20 -34
- package/dist/evaluator/Evaluator.js +19 -64
- package/dist/evaluator/Evaluator.js.map +1 -1
- package/dist/evaluator/compile.d.ts +27 -0
- package/dist/evaluator/compile.js +279 -0
- package/dist/evaluator/compile.js.map +1 -0
- package/dist/grammar.d.ts +29 -9
- package/dist/grammar.js +23 -7
- package/dist/grammar.js.map +1 -1
- package/dist/parser/Parser.d.ts +7 -8
- package/dist/parser/Parser.js +46 -14
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/handlers.d.ts +8 -8
- package/dist/parser/handlers.js +84 -51
- package/dist/parser/handlers.js.map +1 -1
- package/dist/parser/states.d.ts +2 -2
- package/dist/parser/states.js +19 -40
- package/dist/parser/states.js.map +1 -1
- package/dist/types.d.ts +18 -7
- package/esm/Expression.d.ts +19 -7
- package/esm/Expression.js +32 -11
- package/esm/Expression.js.map +1 -1
- package/esm/Jexl.d.ts +13 -12
- package/esm/Jexl.js +31 -30
- package/esm/Jexl.js.map +1 -1
- package/esm/Lexer.d.ts +9 -9
- package/esm/Lexer.js +61 -24
- package/esm/Lexer.js.map +1 -1
- package/esm/evaluator/Evaluator.d.ts +20 -34
- package/esm/evaluator/Evaluator.js +19 -31
- package/esm/evaluator/Evaluator.js.map +1 -1
- package/esm/evaluator/compile.d.ts +27 -0
- package/esm/evaluator/compile.js +276 -0
- package/esm/evaluator/compile.js.map +1 -0
- package/esm/grammar.d.ts +29 -9
- package/esm/grammar.js +22 -7
- package/esm/grammar.js.map +1 -1
- package/esm/parser/Parser.d.ts +7 -8
- package/esm/parser/Parser.js +46 -14
- package/esm/parser/Parser.js.map +1 -1
- package/esm/parser/handlers.d.ts +8 -8
- package/esm/parser/handlers.js +81 -50
- package/esm/parser/handlers.js.map +1 -1
- package/esm/parser/states.d.ts +2 -2
- package/esm/parser/states.js +19 -40
- package/esm/parser/states.js.map +1 -1
- package/esm/types.d.ts +18 -7
- package/package.json +25 -28
- package/src/Expression.ts +31 -17
- package/src/Jexl.ts +59 -21
- package/src/Lexer.ts +63 -33
- package/src/evaluator/Evaluator.ts +27 -44
- package/src/evaluator/compile.ts +317 -0
- package/src/grammar.ts +69 -21
- package/src/parser/Parser.ts +50 -28
- package/src/parser/handlers.ts +122 -76
- package/src/parser/states.ts +22 -42
- package/src/types.ts +22 -7
- package/CHANGELOG.md +0 -249
- package/dist/evaluator/handlers.d.ts +0 -112
- package/dist/evaluator/handlers.js +0 -208
- package/dist/evaluator/handlers.js.map +0 -1
- package/esm/evaluator/handlers.d.ts +0 -112
- package/esm/evaluator/handlers.js +0 -194
- package/esm/evaluator/handlers.js.map +0 -1
- package/src/evaluator/handlers.ts +0 -212
package/esm/parser/Parser.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type Lexer from '../Lexer.ts';
|
|
2
|
+
import type { Grammar } from '../grammar.ts';
|
|
2
3
|
import type { AstNode, Token } from '../types.ts';
|
|
3
|
-
interface Grammar {
|
|
4
|
-
elements: Record<string, any>;
|
|
5
|
-
}
|
|
6
4
|
/**
|
|
7
5
|
* The Parser is a state machine that converts tokens from the {@link Lexer}
|
|
8
6
|
* into an Abstract Syntax Tree (AST), capable of being evaluated in any
|
|
@@ -27,7 +25,7 @@ declare class Parser {
|
|
|
27
25
|
_tree: AstNode | null;
|
|
28
26
|
_exprStr: string;
|
|
29
27
|
_relative: boolean;
|
|
30
|
-
_stopMap: Record<string,
|
|
28
|
+
_stopMap: Record<string, string>;
|
|
31
29
|
_cursor?: AstNode | null;
|
|
32
30
|
_subParser?: Parser;
|
|
33
31
|
_parentStop?: boolean;
|
|
@@ -35,7 +33,7 @@ declare class Parser {
|
|
|
35
33
|
_nextIdentRelative?: boolean;
|
|
36
34
|
_curObjKey?: string;
|
|
37
35
|
_sequenceExpressions?: AstNode[];
|
|
38
|
-
constructor(grammar: Grammar, lexer: Lexer, prefix?: string, stopMap?: Record<string,
|
|
36
|
+
constructor(grammar: Grammar, lexer: Lexer, prefix?: string, stopMap?: Record<string, string>);
|
|
39
37
|
/**
|
|
40
38
|
* Processes a new token into the AST and manages the transitions of the state
|
|
41
39
|
* machine.
|
|
@@ -46,7 +44,7 @@ declare class Parser {
|
|
|
46
44
|
* @returns {boolean|*} the stopState value if this parser encountered a token
|
|
47
45
|
* in the stopState mapb false if tokens can continue.
|
|
48
46
|
*/
|
|
49
|
-
addToken(token: Token):
|
|
47
|
+
addToken(token: Token): string | false;
|
|
50
48
|
/**
|
|
51
49
|
* Processes an array of tokens iteratively through the {@link #addToken}
|
|
52
50
|
* function.
|
|
@@ -62,7 +60,7 @@ declare class Parser {
|
|
|
62
60
|
* @throws {Error} if the parser is not in a state where it's legal to end
|
|
63
61
|
* the expression, indicating that the expression is incomplete
|
|
64
62
|
*/
|
|
65
|
-
complete():
|
|
63
|
+
complete(): AstNode | null;
|
|
66
64
|
/**
|
|
67
65
|
* Indicates whether the expression tree contains a relative path identifier.
|
|
68
66
|
* @returns {boolean} true if a relative identifier exists false otherwise.
|
|
@@ -105,8 +103,9 @@ declare class Parser {
|
|
|
105
103
|
* Prepares the Parser to accept a subexpression by (re)instantiating the
|
|
106
104
|
* subParser.
|
|
107
105
|
* @param {string} [exprStr] The expression string to prefix to the new Parser
|
|
106
|
+
* @returns {Parser} the new subParser, also stored on this instance
|
|
108
107
|
* @private
|
|
109
108
|
*/
|
|
110
|
-
_startSubExpression(exprStr?: string):
|
|
109
|
+
_startSubExpression(exprStr?: string): Parser;
|
|
111
110
|
}
|
|
112
111
|
export default Parser;
|
package/esm/parser/Parser.js
CHANGED
|
@@ -4,6 +4,21 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import * as handlers from "./handlers.js";
|
|
6
6
|
import { states } from "./states.js";
|
|
7
|
+
/**
|
|
8
|
+
* The handler to run for a token type when the state it appears in doesn't
|
|
9
|
+
* name one of its own. Token types absent here — the brackets, parens and
|
|
10
|
+
* separators — carry no behavior beyond the state transition the state machine
|
|
11
|
+
* gives them.
|
|
12
|
+
*/
|
|
13
|
+
const tokenHandlers = {
|
|
14
|
+
binaryOp: handlers.binaryOp,
|
|
15
|
+
dot: handlers.dot,
|
|
16
|
+
identifier: handlers.identifier,
|
|
17
|
+
literal: handlers.literal,
|
|
18
|
+
semicolon: handlers.semicolon,
|
|
19
|
+
templateString: handlers.templateString,
|
|
20
|
+
unaryOp: handlers.unaryOp
|
|
21
|
+
};
|
|
7
22
|
/**
|
|
8
23
|
* The Parser is a state machine that converts tokens from the {@link Lexer}
|
|
9
24
|
* into an Abstract Syntax Tree (AST), capable of being evaluated in any
|
|
@@ -22,6 +37,20 @@ import { states } from "./states.js";
|
|
|
22
37
|
* instead of boolean false.
|
|
23
38
|
*/
|
|
24
39
|
class Parser {
|
|
40
|
+
_grammar;
|
|
41
|
+
_lexer;
|
|
42
|
+
_state;
|
|
43
|
+
_tree;
|
|
44
|
+
_exprStr;
|
|
45
|
+
_relative;
|
|
46
|
+
_stopMap;
|
|
47
|
+
_cursor;
|
|
48
|
+
_subParser;
|
|
49
|
+
_parentStop;
|
|
50
|
+
_nextIdentEncapsulate;
|
|
51
|
+
_nextIdentRelative;
|
|
52
|
+
_curObjKey;
|
|
53
|
+
_sequenceExpressions;
|
|
25
54
|
constructor(grammar, lexer, prefix, stopMap) {
|
|
26
55
|
this._grammar = grammar;
|
|
27
56
|
this._lexer = lexer;
|
|
@@ -49,10 +78,8 @@ class Parser {
|
|
|
49
78
|
const startExpr = this._exprStr;
|
|
50
79
|
this._exprStr += token.raw;
|
|
51
80
|
if (state.subHandler) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
const stopState = this._subParser.addToken(token);
|
|
81
|
+
const subParser = this._subParser ?? this._startSubExpression(startExpr);
|
|
82
|
+
const stopState = subParser.addToken(token);
|
|
56
83
|
if (stopState) {
|
|
57
84
|
this._endSubExpression();
|
|
58
85
|
if (stopState === '_semicolon') {
|
|
@@ -71,13 +98,10 @@ class Parser {
|
|
|
71
98
|
}
|
|
72
99
|
else if (state.tokenTypes?.[token.type]) {
|
|
73
100
|
const typeOpts = state.tokenTypes[token.type];
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (handleFunc) {
|
|
79
|
-
handleFunc.call(this, token);
|
|
80
|
-
}
|
|
101
|
+
// the state's own handler wins over the token type's default one, and a
|
|
102
|
+
// token type with neither only drives the transition below
|
|
103
|
+
const handleFunc = typeOpts.handler ?? tokenHandlers[token.type];
|
|
104
|
+
handleFunc?.call(this, token);
|
|
81
105
|
if (typeOpts.toState) {
|
|
82
106
|
this._state = typeOpts.toState;
|
|
83
107
|
}
|
|
@@ -97,7 +121,9 @@ class Parser {
|
|
|
97
121
|
* the {@link Lexer#tokenize} function.
|
|
98
122
|
*/
|
|
99
123
|
addTokens(tokens) {
|
|
100
|
-
|
|
124
|
+
for (const token of tokens) {
|
|
125
|
+
this.addToken(token);
|
|
126
|
+
}
|
|
101
127
|
}
|
|
102
128
|
/**
|
|
103
129
|
* Marks this Parser instance as completed and retrieves the full AST.
|
|
@@ -108,7 +134,12 @@ class Parser {
|
|
|
108
134
|
* the expression, indicating that the expression is incomplete
|
|
109
135
|
*/
|
|
110
136
|
complete() {
|
|
111
|
-
|
|
137
|
+
// `_subParser` counts as unfinished business alongside `_cursor`: a group
|
|
138
|
+
// that opened before anything was placed in the tree, as in "(1", leaves
|
|
139
|
+
// the cursor null, and testing the cursor alone let the missing ")" pass
|
|
140
|
+
// silently and evaluate as if it were closed.
|
|
141
|
+
if ((this._cursor || this._subParser) &&
|
|
142
|
+
!states[this._state].completable) {
|
|
112
143
|
throw new Error(`Unexpected end of expression: ${this._exprStr}`);
|
|
113
144
|
}
|
|
114
145
|
if (this._subParser) {
|
|
@@ -156,7 +187,6 @@ class Parser {
|
|
|
156
187
|
this._tree = node;
|
|
157
188
|
}
|
|
158
189
|
else {
|
|
159
|
-
;
|
|
160
190
|
this._cursor.right = node;
|
|
161
191
|
this._setParent(node, this._cursor);
|
|
162
192
|
}
|
|
@@ -193,6 +223,7 @@ class Parser {
|
|
|
193
223
|
* Prepares the Parser to accept a subexpression by (re)instantiating the
|
|
194
224
|
* subParser.
|
|
195
225
|
* @param {string} [exprStr] The expression string to prefix to the new Parser
|
|
226
|
+
* @returns {Parser} the new subParser, also stored on this instance
|
|
196
227
|
* @private
|
|
197
228
|
*/
|
|
198
229
|
_startSubExpression(exprStr) {
|
|
@@ -205,6 +236,7 @@ class Parser {
|
|
|
205
236
|
endStates = { ...endStates, semicolon: '_semicolon' };
|
|
206
237
|
}
|
|
207
238
|
this._subParser = new Parser(this._grammar, this._lexer, exprStr, endStates);
|
|
239
|
+
return this._subParser;
|
|
208
240
|
}
|
|
209
241
|
}
|
|
210
242
|
export default Parser;
|
package/esm/parser/Parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/parser/Parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../src/parser/Parser.ts"],"names":[],"mappings":"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"}
|
package/esm/parser/handlers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import Parser from './Parser.ts';
|
|
1
2
|
import type { AstNode, Token } from '../types.ts';
|
|
2
|
-
import type Parser from './Parser.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Handles a subexpression that's used to define a transform argument's value.
|
|
5
5
|
* @param {{type: <string>}} ast The subexpression tree
|
|
@@ -36,7 +36,13 @@ export declare function filter(this: Parser, ast: AstNode | null): void;
|
|
|
36
36
|
/**
|
|
37
37
|
* Handles identifier tokens when used to indicate the name of a function to
|
|
38
38
|
* be called.
|
|
39
|
-
*
|
|
39
|
+
*
|
|
40
|
+
* A call written against a value, `a.b(x)`, becomes `b(a, x)`: jexl functions
|
|
41
|
+
* live in one global pool and have no receiver, so the value the name was read
|
|
42
|
+
* from is passed as the first argument instead. Every function in the pool is
|
|
43
|
+
* already written that way — `get(feature, key)`, `split(str, sep)` — which is
|
|
44
|
+
* what makes the two spellings equivalent. Previously the receiver was simply
|
|
45
|
+
* dropped, so `refName.split(' ')` quietly called `split(' ')`.
|
|
40
46
|
*/
|
|
41
47
|
export declare function functionCall(this: Parser): void;
|
|
42
48
|
/**
|
|
@@ -94,12 +100,6 @@ export declare function ternaryMid(this: Parser, ast: AstNode | null): void;
|
|
|
94
100
|
* test element.
|
|
95
101
|
*/
|
|
96
102
|
export declare function ternaryStart(this: Parser): void;
|
|
97
|
-
/**
|
|
98
|
-
* Handles identifier tokens when used to indicate the name of a transform to
|
|
99
|
-
* be applied.
|
|
100
|
-
* @param {{type: <string>}} token A token object
|
|
101
|
-
*/
|
|
102
|
-
export declare function transform(this: Parser, token: Token): void;
|
|
103
103
|
/**
|
|
104
104
|
* Handles token of type 'unaryOp', indicating that the operation has only
|
|
105
105
|
* one input: a right side.
|
package/esm/parser/handlers.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* Jexl
|
|
3
3
|
* Copyright 2020 Tom Shawver
|
|
4
4
|
*/
|
|
5
|
+
import { precedenceOf } from "../grammar.js";
|
|
6
|
+
// circular with Parser.ts, which is fine: the binding is only read from inside
|
|
7
|
+
// a handler, long after both modules have finished evaluating
|
|
8
|
+
import Parser from "./Parser.js";
|
|
5
9
|
/**
|
|
6
10
|
* Handles a subexpression that's used to define a transform argument's value.
|
|
7
11
|
* @param {{type: <string>}} ast The subexpression tree
|
|
@@ -17,10 +21,11 @@ export function argVal(ast) {
|
|
|
17
21
|
* initialized with an empty array.
|
|
18
22
|
*/
|
|
19
23
|
export function arrayStart() {
|
|
20
|
-
|
|
24
|
+
const node = {
|
|
21
25
|
type: 'ArrayLiteral',
|
|
22
26
|
value: []
|
|
23
|
-
}
|
|
27
|
+
};
|
|
28
|
+
this._placeAtCursor(node);
|
|
24
29
|
}
|
|
25
30
|
/**
|
|
26
31
|
* Handles a subexpression representing an element of an array literal.
|
|
@@ -39,7 +44,10 @@ export function arrayVal(ast) {
|
|
|
39
44
|
*/
|
|
40
45
|
export function binaryOp(token) {
|
|
41
46
|
if (token.value === '=') {
|
|
42
|
-
|
|
47
|
+
// `from` marks a member access such as `a.b`; only a bare name can be
|
|
48
|
+
// assigned to, since the Evaluator writes straight into the context
|
|
49
|
+
if (this._cursor?.type !== 'Identifier' ||
|
|
50
|
+
this._cursor.from) {
|
|
43
51
|
throw new Error('Left side of assignment must be a variable name');
|
|
44
52
|
}
|
|
45
53
|
const node = {
|
|
@@ -51,17 +59,23 @@ export function binaryOp(token) {
|
|
|
51
59
|
this._placeAtCursor(node);
|
|
52
60
|
return;
|
|
53
61
|
}
|
|
54
|
-
const
|
|
62
|
+
const tokenValue = token.value;
|
|
63
|
+
const precedence = precedenceOf(this._grammar.elements[tokenValue]);
|
|
55
64
|
let parent = this._cursor?._parent;
|
|
56
|
-
while (parent
|
|
57
|
-
parent
|
|
58
|
-
|
|
65
|
+
while (parent) {
|
|
66
|
+
const parentExpr = parent;
|
|
67
|
+
if (!parentExpr.operator) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
if (precedenceOf(this._grammar.elements[parentExpr.operator]) < precedence) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
59
73
|
this._cursor = parent;
|
|
60
74
|
parent = parent._parent;
|
|
61
75
|
}
|
|
62
76
|
const node = {
|
|
63
77
|
type: 'BinaryExpression',
|
|
64
|
-
operator:
|
|
78
|
+
operator: tokenValue,
|
|
65
79
|
left: this._cursor
|
|
66
80
|
};
|
|
67
81
|
this._setParent(this._cursor, node);
|
|
@@ -74,13 +88,15 @@ export function binaryOp(token) {
|
|
|
74
88
|
* AST.
|
|
75
89
|
*/
|
|
76
90
|
export function dot() {
|
|
77
|
-
const
|
|
91
|
+
const cursor = this._cursor;
|
|
92
|
+
// the dot continues an identifier chain unless the cursor is an operator
|
|
93
|
+
// still waiting on its right-hand side, in which case it opens a relative
|
|
94
|
+
// path instead — as in the leading dot of `list[.price > 5]`
|
|
78
95
|
this._nextIdentEncapsulate =
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
(
|
|
82
|
-
|
|
83
|
-
this._nextIdentRelative = !this._cursor || !this._nextIdentEncapsulate;
|
|
96
|
+
!!cursor &&
|
|
97
|
+
cursor.type !== 'UnaryExpression' &&
|
|
98
|
+
(cursor.type !== 'BinaryExpression' || !!cursor.right);
|
|
99
|
+
this._nextIdentRelative = !this._nextIdentEncapsulate;
|
|
84
100
|
if (this._nextIdentRelative) {
|
|
85
101
|
this._relative = true;
|
|
86
102
|
}
|
|
@@ -91,25 +107,40 @@ export function dot() {
|
|
|
91
107
|
* @param {{type: <string>}} ast The subexpression tree
|
|
92
108
|
*/
|
|
93
109
|
export function filter(ast) {
|
|
94
|
-
|
|
110
|
+
const node = {
|
|
95
111
|
type: 'FilterExpression',
|
|
96
112
|
expr: ast,
|
|
97
113
|
relative: this._subParser.isRelative(),
|
|
98
114
|
subject: this._cursor
|
|
99
|
-
}
|
|
115
|
+
};
|
|
116
|
+
this._placeBeforeCursor(node);
|
|
100
117
|
}
|
|
101
118
|
/**
|
|
102
119
|
* Handles identifier tokens when used to indicate the name of a function to
|
|
103
120
|
* be called.
|
|
104
|
-
*
|
|
121
|
+
*
|
|
122
|
+
* A call written against a value, `a.b(x)`, becomes `b(a, x)`: jexl functions
|
|
123
|
+
* live in one global pool and have no receiver, so the value the name was read
|
|
124
|
+
* from is passed as the first argument instead. Every function in the pool is
|
|
125
|
+
* already written that way — `get(feature, key)`, `split(str, sep)` — which is
|
|
126
|
+
* what makes the two spellings equivalent. Previously the receiver was simply
|
|
127
|
+
* dropped, so `refName.split(' ')` quietly called `split(' ')`.
|
|
105
128
|
*/
|
|
106
129
|
export function functionCall() {
|
|
107
|
-
this.
|
|
130
|
+
const cursor = this._cursor;
|
|
131
|
+
if (cursor?.type !== 'Identifier') {
|
|
132
|
+
// reached by `a[expr]()`, whose subject is a filter rather than a name;
|
|
133
|
+
// there is nothing to look up in the function pool
|
|
134
|
+
throw new Error(`Functions must be called by name: ${this._exprStr}`);
|
|
135
|
+
}
|
|
136
|
+
const { from } = cursor;
|
|
137
|
+
const node = {
|
|
108
138
|
type: 'FunctionCall',
|
|
109
|
-
name:
|
|
110
|
-
args: [],
|
|
139
|
+
name: cursor.value,
|
|
140
|
+
args: from ? [from] : [],
|
|
111
141
|
pool: 'functions'
|
|
112
|
-
}
|
|
142
|
+
};
|
|
143
|
+
this._placeBeforeCursor(node);
|
|
113
144
|
}
|
|
114
145
|
/**
|
|
115
146
|
* Handles identifier tokens by adding them as a new node in the AST.
|
|
@@ -139,10 +170,11 @@ export function identifier(token) {
|
|
|
139
170
|
* @param {{type: <string>}} token A token object
|
|
140
171
|
*/
|
|
141
172
|
export function literal(token) {
|
|
142
|
-
|
|
173
|
+
const node = {
|
|
143
174
|
type: 'Literal',
|
|
144
175
|
value: token.value
|
|
145
|
-
}
|
|
176
|
+
};
|
|
177
|
+
this._placeAtCursor(node);
|
|
146
178
|
}
|
|
147
179
|
/**
|
|
148
180
|
* Handles template string tokens by parsing their interpolation expressions
|
|
@@ -151,7 +183,8 @@ export function literal(token) {
|
|
|
151
183
|
*/
|
|
152
184
|
export function templateString(token) {
|
|
153
185
|
const parts = [];
|
|
154
|
-
|
|
186
|
+
const tokenParts = Array.isArray(token.value) ? token.value : [];
|
|
187
|
+
for (const part of tokenParts) {
|
|
155
188
|
if (part.type === 'static') {
|
|
156
189
|
parts.push({
|
|
157
190
|
type: 'static',
|
|
@@ -160,7 +193,7 @@ export function templateString(token) {
|
|
|
160
193
|
}
|
|
161
194
|
else {
|
|
162
195
|
const subTokens = this._lexer.tokenize(part.value);
|
|
163
|
-
const subParser = new
|
|
196
|
+
const subParser = new Parser(this._grammar, this._lexer);
|
|
164
197
|
subParser.addTokens(subTokens);
|
|
165
198
|
const subAst = subParser.complete();
|
|
166
199
|
if (!subAst) {
|
|
@@ -172,10 +205,11 @@ export function templateString(token) {
|
|
|
172
205
|
});
|
|
173
206
|
}
|
|
174
207
|
}
|
|
175
|
-
|
|
208
|
+
const node = {
|
|
176
209
|
type: 'TemplateLiteral',
|
|
177
|
-
parts
|
|
178
|
-
}
|
|
210
|
+
parts
|
|
211
|
+
};
|
|
212
|
+
this._placeAtCursor(node);
|
|
179
213
|
}
|
|
180
214
|
/**
|
|
181
215
|
* Queues a new object literal key to be written once a value is collected.
|
|
@@ -189,10 +223,11 @@ export function objKey(token) {
|
|
|
189
223
|
* initialized with an empty object.
|
|
190
224
|
*/
|
|
191
225
|
export function objStart() {
|
|
192
|
-
|
|
226
|
+
const node = {
|
|
193
227
|
type: 'ObjectLiteral',
|
|
194
228
|
value: {}
|
|
195
|
-
}
|
|
229
|
+
};
|
|
230
|
+
this._placeAtCursor(node);
|
|
196
231
|
}
|
|
197
232
|
/**
|
|
198
233
|
* Handles an object value by adding its AST to the queued key on the object
|
|
@@ -200,8 +235,15 @@ export function objStart() {
|
|
|
200
235
|
* @param {{type: <string>}} ast The subexpression tree
|
|
201
236
|
*/
|
|
202
237
|
export function objVal(ast) {
|
|
203
|
-
|
|
204
|
-
|
|
238
|
+
// defined rather than assigned so that the key "__proto__" becomes an
|
|
239
|
+
// ordinary entry of the node's key map instead of re-pointing its prototype,
|
|
240
|
+
// which dropped the entry before the Evaluator ever saw it
|
|
241
|
+
Object.defineProperty(this._cursor.value, this._curObjKey, {
|
|
242
|
+
value: ast,
|
|
243
|
+
writable: true,
|
|
244
|
+
enumerable: true,
|
|
245
|
+
configurable: true
|
|
246
|
+
});
|
|
205
247
|
}
|
|
206
248
|
/**
|
|
207
249
|
* Handles traditional subexpressions, delineated with the groupStart and
|
|
@@ -217,7 +259,7 @@ export function subExpression(ast) {
|
|
|
217
259
|
*/
|
|
218
260
|
export function ternaryEnd(ast) {
|
|
219
261
|
;
|
|
220
|
-
this._cursor.alternate = ast;
|
|
262
|
+
this._cursor.alternate = ast ?? undefined;
|
|
221
263
|
}
|
|
222
264
|
/**
|
|
223
265
|
* Handles a completed consequent subexpression of a ternary operator.
|
|
@@ -225,7 +267,7 @@ export function ternaryEnd(ast) {
|
|
|
225
267
|
*/
|
|
226
268
|
export function ternaryMid(ast) {
|
|
227
269
|
;
|
|
228
|
-
this._cursor.consequent = ast;
|
|
270
|
+
this._cursor.consequent = ast ?? undefined;
|
|
229
271
|
}
|
|
230
272
|
/**
|
|
231
273
|
* Handles the start of a new ternary expression by encapsulating the entire
|
|
@@ -233,35 +275,24 @@ export function ternaryMid(ast) {
|
|
|
233
275
|
* test element.
|
|
234
276
|
*/
|
|
235
277
|
export function ternaryStart() {
|
|
236
|
-
|
|
278
|
+
const node = {
|
|
237
279
|
type: 'ConditionalExpression',
|
|
238
280
|
test: this._tree
|
|
239
281
|
};
|
|
282
|
+
this._tree = node;
|
|
240
283
|
this._cursor = this._tree;
|
|
241
284
|
}
|
|
242
|
-
/**
|
|
243
|
-
* Handles identifier tokens when used to indicate the name of a transform to
|
|
244
|
-
* be applied.
|
|
245
|
-
* @param {{type: <string>}} token A token object
|
|
246
|
-
*/
|
|
247
|
-
export function transform(token) {
|
|
248
|
-
this._placeBeforeCursor({
|
|
249
|
-
type: 'FunctionCall',
|
|
250
|
-
name: token.value,
|
|
251
|
-
args: [this._cursor],
|
|
252
|
-
pool: 'transforms'
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
285
|
/**
|
|
256
286
|
* Handles token of type 'unaryOp', indicating that the operation has only
|
|
257
287
|
* one input: a right side.
|
|
258
288
|
* @param {{type: <string>}} token A token object
|
|
259
289
|
*/
|
|
260
290
|
export function unaryOp(token) {
|
|
261
|
-
|
|
291
|
+
const node = {
|
|
262
292
|
type: 'UnaryExpression',
|
|
263
293
|
operator: token.value
|
|
264
|
-
}
|
|
294
|
+
};
|
|
295
|
+
this._placeAtCursor(node);
|
|
265
296
|
}
|
|
266
297
|
/**
|
|
267
298
|
* Handles semicolon separator between expressions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/parser/handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/parser/handlers.ts"],"names":[],"mappings":"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"}
|
package/esm/parser/states.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AstNode } from '../types.ts';
|
|
1
|
+
import type { AstNode, Token } from '../types.ts';
|
|
2
2
|
import type Parser from './Parser.ts';
|
|
3
3
|
interface TokenTypeOptions {
|
|
4
4
|
toState?: string;
|
|
5
|
-
handler?: (this: Parser,
|
|
5
|
+
handler?: (this: Parser, token: Token) => void;
|
|
6
6
|
}
|
|
7
7
|
interface StateDefinition {
|
|
8
8
|
tokenTypes?: Record<string, TokenTypeOptions>;
|
package/esm/parser/states.js
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
* Copyright 2020 Tom Shawver
|
|
4
4
|
*/
|
|
5
5
|
import * as h from "./handlers.js";
|
|
6
|
+
/**
|
|
7
|
+
* The tokens that may follow a finished operand: an operator to combine it
|
|
8
|
+
* with, a dot or subscript to keep drilling into it, a question mark opening a
|
|
9
|
+
* ternary, or a semicolon ending the statement. Shared by every state that
|
|
10
|
+
* sits on a complete value, which is also why each of them is completable.
|
|
11
|
+
*/
|
|
12
|
+
const afterOperand = {
|
|
13
|
+
binaryOp: { toState: 'expectOperand' },
|
|
14
|
+
dot: { toState: 'traverse' },
|
|
15
|
+
openBracket: { toState: 'filter' },
|
|
16
|
+
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
17
|
+
semicolon: { handler: h.semicolon }
|
|
18
|
+
};
|
|
6
19
|
/**
|
|
7
20
|
* A mapping of all states in the finite state machine to a set of instructions
|
|
8
21
|
* for handling or transitioning into other states. Each state can be handled
|
|
@@ -49,21 +62,9 @@ export const states = {
|
|
|
49
62
|
}
|
|
50
63
|
},
|
|
51
64
|
expectBinOp: {
|
|
52
|
-
tokenTypes:
|
|
53
|
-
binaryOp: { toState: 'expectOperand' },
|
|
54
|
-
pipe: { toState: 'expectTransform' },
|
|
55
|
-
dot: { toState: 'traverse' },
|
|
56
|
-
openBracket: { toState: 'filter' },
|
|
57
|
-
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
58
|
-
semicolon: { handler: h.semicolon }
|
|
59
|
-
},
|
|
65
|
+
tokenTypes: afterOperand,
|
|
60
66
|
completable: true
|
|
61
67
|
},
|
|
62
|
-
expectTransform: {
|
|
63
|
-
tokenTypes: {
|
|
64
|
-
identifier: { toState: 'postTransform', handler: h.transform }
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
68
|
expectObjKey: {
|
|
68
69
|
tokenTypes: {
|
|
69
70
|
literal: { toState: 'expectKeyValSep', handler: h.objKey },
|
|
@@ -76,38 +77,16 @@ export const states = {
|
|
|
76
77
|
colon: { toState: 'objVal' }
|
|
77
78
|
}
|
|
78
79
|
},
|
|
79
|
-
postTransform: {
|
|
80
|
-
tokenTypes: {
|
|
81
|
-
openParen: { toState: 'argVal' },
|
|
82
|
-
binaryOp: { toState: 'expectOperand' },
|
|
83
|
-
dot: { toState: 'traverse' },
|
|
84
|
-
openBracket: { toState: 'filter' },
|
|
85
|
-
pipe: { toState: 'expectTransform' },
|
|
86
|
-
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
87
|
-
semicolon: { handler: h.semicolon }
|
|
88
|
-
},
|
|
89
|
-
completable: true
|
|
90
|
-
},
|
|
91
80
|
postArgs: {
|
|
92
|
-
tokenTypes:
|
|
93
|
-
binaryOp: { toState: 'expectOperand' },
|
|
94
|
-
dot: { toState: 'traverse' },
|
|
95
|
-
openBracket: { toState: 'filter' },
|
|
96
|
-
pipe: { toState: 'expectTransform' },
|
|
97
|
-
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
98
|
-
semicolon: { handler: h.semicolon }
|
|
99
|
-
},
|
|
81
|
+
tokenTypes: afterOperand,
|
|
100
82
|
completable: true
|
|
101
83
|
},
|
|
102
84
|
identifier: {
|
|
103
85
|
tokenTypes: {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
openParen: { toState: 'argVal', handler: h.functionCall }
|
|
108
|
-
pipe: { toState: 'expectTransform' },
|
|
109
|
-
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
110
|
-
semicolon: { handler: h.semicolon }
|
|
86
|
+
...afterOperand,
|
|
87
|
+
// a name is the only operand that can be followed by an argument list,
|
|
88
|
+
// since a function is called by name rather than evaluated as a value
|
|
89
|
+
openParen: { toState: 'argVal', handler: h.functionCall }
|
|
111
90
|
},
|
|
112
91
|
completable: true
|
|
113
92
|
},
|
package/esm/parser/states.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"states.js","sourceRoot":"","sources":["../../src/parser/states.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,CAAC,MAAM,eAAe,CAAA;AAmBlC
|
|
1
|
+
{"version":3,"file":"states.js","sourceRoot":"","sources":["../../src/parser/states.ts"],"names":[],"mappings":"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"}
|