@jbrowse/jexl 4.0.1 → 5.0.1
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 +163 -20
- package/dist/Expression.d.ts +16 -0
- package/dist/Expression.js +28 -4
- package/dist/Expression.js.map +1 -1
- package/dist/Jexl.d.ts +20 -8
- package/dist/Jexl.js +34 -15
- package/dist/Jexl.js.map +1 -1
- package/dist/Lexer.d.ts +4 -3
- package/dist/Lexer.js +29 -21
- package/dist/Lexer.js.map +1 -1
- package/dist/analyze.d.ts +84 -0
- package/dist/analyze.js +259 -0
- package/dist/analyze.js.map +1 -0
- package/dist/check.d.ts +109 -0
- package/dist/check.js +1267 -0
- package/dist/check.js.map +1 -0
- package/dist/collections.d.ts +3 -0
- package/dist/collections.js +140 -0
- package/dist/collections.js.map +1 -0
- package/dist/conditions.d.ts +62 -0
- package/dist/conditions.js +207 -0
- package/dist/conditions.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator/compile.d.ts +10 -7
- package/dist/evaluator/compile.js +292 -99
- package/dist/evaluator/compile.js.map +1 -1
- package/dist/grammar.d.ts +22 -9
- package/dist/grammar.js +83 -55
- package/dist/grammar.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/operators.d.ts +34 -0
- package/dist/operators.js +131 -0
- package/dist/operators.js.map +1 -0
- package/dist/parser/Parser.d.ts +48 -91
- package/dist/parser/Parser.js +347 -221
- package/dist/parser/Parser.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/esm/Expression.d.ts +16 -0
- package/esm/Expression.js +28 -4
- package/esm/Expression.js.map +1 -1
- package/esm/Jexl.d.ts +20 -8
- package/esm/Jexl.js +34 -15
- package/esm/Jexl.js.map +1 -1
- package/esm/Lexer.d.ts +4 -3
- package/esm/Lexer.js +29 -21
- package/esm/Lexer.js.map +1 -1
- package/esm/analyze.d.ts +84 -0
- package/esm/analyze.js +256 -0
- package/esm/analyze.js.map +1 -0
- package/esm/check.d.ts +109 -0
- package/esm/check.js +1260 -0
- package/esm/check.js.map +1 -0
- package/esm/collections.d.ts +3 -0
- package/esm/collections.js +137 -0
- package/esm/collections.js.map +1 -0
- package/esm/conditions.d.ts +62 -0
- package/esm/conditions.js +200 -0
- package/esm/conditions.js.map +1 -0
- package/esm/errors.d.ts +5 -0
- package/esm/errors.js +14 -0
- package/esm/errors.js.map +1 -0
- package/esm/evaluator/compile.d.ts +10 -7
- package/esm/evaluator/compile.js +292 -99
- package/esm/evaluator/compile.js.map +1 -1
- package/esm/grammar.d.ts +22 -9
- package/esm/grammar.js +79 -53
- package/esm/grammar.js.map +1 -1
- package/esm/index.d.ts +9 -0
- package/esm/index.js +4 -0
- package/esm/index.js.map +1 -1
- package/esm/operators.d.ts +34 -0
- package/esm/operators.js +123 -0
- package/esm/operators.js.map +1 -0
- package/esm/parser/Parser.d.ts +48 -91
- package/esm/parser/Parser.js +349 -192
- package/esm/parser/Parser.js.map +1 -1
- package/esm/types.d.ts +11 -5
- package/package.json +1 -1
- package/src/Expression.ts +34 -4
- package/src/Jexl.ts +52 -16
- package/src/Lexer.ts +32 -21
- package/src/analyze.ts +378 -0
- package/src/check.ts +1682 -0
- package/src/collections.ts +148 -0
- package/src/conditions.ts +262 -0
- package/src/errors.ts +15 -0
- package/src/evaluator/compile.ts +351 -102
- package/src/grammar.ts +137 -55
- package/src/index.ts +15 -0
- package/src/operators.ts +151 -0
- package/src/parser/Parser.ts +389 -199
- package/src/types.ts +13 -3
- package/dist/parser/handlers.d.ts +0 -115
- package/dist/parser/handlers.js +0 -352
- package/dist/parser/handlers.js.map +0 -1
- package/dist/parser/states.d.ts +0 -47
- package/dist/parser/states.js +0 -176
- package/dist/parser/states.js.map +0 -1
- package/esm/parser/handlers.d.ts +0 -115
- package/esm/parser/handlers.js +0 -328
- package/esm/parser/handlers.js.map +0 -1
- package/esm/parser/states.d.ts +0 -47
- package/esm/parser/states.js +0 -140
- package/esm/parser/states.js.map +0 -1
- package/src/parser/handlers.ts +0 -372
- package/src/parser/states.ts +0 -159
package/esm/grammar.js
CHANGED
|
@@ -2,15 +2,35 @@
|
|
|
2
2
|
* Jexl
|
|
3
3
|
* Copyright 2020 Tom Shawver
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
/* eslint eqeqeq:0 */
|
|
6
|
+
import { collectionFunctions } from "./collections.js";
|
|
7
|
+
import { addsPairwise, anyPair, isIn, isList, matches, pairwise } from "./operators.js";
|
|
8
|
+
const plus = (left, right) => left + right;
|
|
9
|
+
const minus = (left, right) => left - right;
|
|
10
|
+
const times = (left, right) => left * right;
|
|
11
|
+
const divide = (left, right) => left / right;
|
|
12
|
+
const floorDivide = (left, right) => Math.floor(left / right);
|
|
13
|
+
const modulo = (left, right) => left % right;
|
|
14
|
+
const power = (left, right) => left ** right;
|
|
15
|
+
const loose = (left, right) => left == right;
|
|
16
|
+
// a missing value orders against nothing, as bcftools skips one; JavaScript
|
|
17
|
+
// alone would read null as 0, making [null, 0.2] < 0.05 true
|
|
18
|
+
const greater = (left, right) => left != null && right != null && left > right;
|
|
19
|
+
const atLeast = (left, right) => left != null && right != null && left >= right;
|
|
20
|
+
const less = (left, right) => left != null && right != null && left < right;
|
|
21
|
+
const atMost = (left, right) => left != null && right != null && left <= right;
|
|
22
|
+
// named so the compiler can recognize the built-in forms and short-circuit
|
|
23
|
+
// without the thunks a host's evalOnDemand operator is handed
|
|
24
|
+
export const and = (left, right) => {
|
|
25
|
+
const leftVal = left.eval();
|
|
26
|
+
return leftVal ? right.eval() : leftVal;
|
|
27
|
+
};
|
|
28
|
+
export const or = (left, right) => {
|
|
29
|
+
const leftVal = left.eval();
|
|
30
|
+
return leftVal || right.eval();
|
|
31
|
+
};
|
|
32
|
+
export const nullish = (left, right) => left.eval() ?? right.eval();
|
|
33
|
+
const equals = (left, right) => isList(left, right) ? anyPair(loose, left, right) : left == right;
|
|
14
34
|
export const getGrammar = () => ({
|
|
15
35
|
/**
|
|
16
36
|
* A map of all expression elements to their properties. Note that changes
|
|
@@ -29,111 +49,117 @@ export const getGrammar = () => ({
|
|
|
29
49
|
')': { type: 'closeParen' },
|
|
30
50
|
'?': { type: 'question' },
|
|
31
51
|
';': { type: 'semicolon' },
|
|
52
|
+
'=>': { type: 'arrow' },
|
|
32
53
|
'+': {
|
|
33
54
|
type: 'binaryOp',
|
|
34
55
|
precedence: 30,
|
|
35
|
-
eval: (left, right) => left
|
|
56
|
+
eval: (left, right) => addsPairwise(left, right)
|
|
57
|
+
? pairwise(plus, left, right)
|
|
58
|
+
: plus(left, right)
|
|
36
59
|
},
|
|
37
60
|
'-': {
|
|
38
61
|
type: 'binaryOp',
|
|
39
62
|
precedence: 30,
|
|
40
|
-
eval: (left, right) => left
|
|
41
|
-
unaryEval: (right) =>
|
|
63
|
+
eval: (left, right) => isList(left, right) ? pairwise(minus, left, right) : minus(left, right),
|
|
64
|
+
unaryEval: (right) => Array.isArray(right)
|
|
65
|
+
? right.map((value) => -value)
|
|
66
|
+
: -right
|
|
42
67
|
},
|
|
43
68
|
'*': {
|
|
44
69
|
type: 'binaryOp',
|
|
45
70
|
precedence: 40,
|
|
46
|
-
eval: (left, right) => left
|
|
71
|
+
eval: (left, right) => isList(left, right) ? pairwise(times, left, right) : times(left, right)
|
|
47
72
|
},
|
|
48
73
|
'/': {
|
|
49
74
|
type: 'binaryOp',
|
|
50
75
|
precedence: 40,
|
|
51
|
-
eval: (left, right) => left
|
|
76
|
+
eval: (left, right) => isList(left, right)
|
|
77
|
+
? pairwise(divide, left, right)
|
|
78
|
+
: divide(left, right)
|
|
52
79
|
},
|
|
53
80
|
'//': {
|
|
54
81
|
type: 'binaryOp',
|
|
55
82
|
precedence: 40,
|
|
56
|
-
eval: (left, right) =>
|
|
83
|
+
eval: (left, right) => isList(left, right)
|
|
84
|
+
? pairwise(floorDivide, left, right)
|
|
85
|
+
: floorDivide(left, right)
|
|
57
86
|
},
|
|
58
87
|
'%': {
|
|
59
88
|
type: 'binaryOp',
|
|
60
89
|
precedence: 50,
|
|
61
|
-
eval: (left, right) => left
|
|
90
|
+
eval: (left, right) => isList(left, right)
|
|
91
|
+
? pairwise(modulo, left, right)
|
|
92
|
+
: modulo(left, right)
|
|
62
93
|
},
|
|
63
94
|
'^': {
|
|
64
95
|
type: 'binaryOp',
|
|
65
96
|
precedence: 50,
|
|
66
|
-
|
|
97
|
+
rightAssociative: true,
|
|
98
|
+
eval: (left, right) => isList(left, right) ? pairwise(power, left, right) : power(left, right)
|
|
67
99
|
},
|
|
68
100
|
'==': {
|
|
69
101
|
type: 'binaryOp',
|
|
70
102
|
precedence: 20,
|
|
71
|
-
eval:
|
|
103
|
+
eval: equals
|
|
72
104
|
},
|
|
73
105
|
'!=': {
|
|
74
106
|
type: 'binaryOp',
|
|
75
107
|
precedence: 20,
|
|
76
|
-
eval: (left, right) => left
|
|
108
|
+
eval: (left, right) => !equals(left, right)
|
|
109
|
+
},
|
|
110
|
+
'~': {
|
|
111
|
+
type: 'binaryOp',
|
|
112
|
+
precedence: 20,
|
|
113
|
+
eval: matches
|
|
114
|
+
},
|
|
115
|
+
'!~': {
|
|
116
|
+
type: 'binaryOp',
|
|
117
|
+
precedence: 20,
|
|
118
|
+
eval: (left, right) => !matches(left, right)
|
|
77
119
|
},
|
|
78
120
|
'>': {
|
|
79
121
|
type: 'binaryOp',
|
|
80
122
|
precedence: 20,
|
|
81
|
-
eval: (left, right) => left
|
|
123
|
+
eval: (left, right) => isList(left, right)
|
|
124
|
+
? anyPair(greater, left, right)
|
|
125
|
+
: greater(left, right)
|
|
82
126
|
},
|
|
83
127
|
'>=': {
|
|
84
128
|
type: 'binaryOp',
|
|
85
129
|
precedence: 20,
|
|
86
|
-
eval: (left, right) => left
|
|
130
|
+
eval: (left, right) => isList(left, right)
|
|
131
|
+
? anyPair(atLeast, left, right)
|
|
132
|
+
: atLeast(left, right)
|
|
87
133
|
},
|
|
88
134
|
'<': {
|
|
89
135
|
type: 'binaryOp',
|
|
90
136
|
precedence: 20,
|
|
91
|
-
eval: (left, right) => left
|
|
137
|
+
eval: (left, right) => isList(left, right) ? anyPair(less, left, right) : less(left, right)
|
|
92
138
|
},
|
|
93
139
|
'<=': {
|
|
94
140
|
type: 'binaryOp',
|
|
95
141
|
precedence: 20,
|
|
96
|
-
eval: (left, right) => left
|
|
142
|
+
eval: (left, right) => isList(left, right) ? anyPair(atMost, left, right) : atMost(left, right)
|
|
97
143
|
},
|
|
98
144
|
'&&': {
|
|
99
145
|
type: 'binaryOp',
|
|
100
|
-
precedence:
|
|
101
|
-
evalOnDemand:
|
|
102
|
-
const leftVal = left.eval();
|
|
103
|
-
if (!leftVal) {
|
|
104
|
-
return leftVal;
|
|
105
|
-
}
|
|
106
|
-
return right.eval();
|
|
107
|
-
}
|
|
146
|
+
precedence: 11,
|
|
147
|
+
evalOnDemand: and
|
|
108
148
|
},
|
|
109
149
|
'||': {
|
|
110
150
|
type: 'binaryOp',
|
|
111
151
|
precedence: 10,
|
|
112
|
-
evalOnDemand:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
152
|
+
evalOnDemand: or
|
|
153
|
+
},
|
|
154
|
+
'??': {
|
|
155
|
+
type: 'binaryOp',
|
|
156
|
+
precedence: 10,
|
|
157
|
+
evalOnDemand: nullish
|
|
119
158
|
},
|
|
120
159
|
in: {
|
|
121
160
|
type: 'binaryOp',
|
|
122
161
|
precedence: 20,
|
|
123
|
-
eval:
|
|
124
|
-
if (typeof right === 'string') {
|
|
125
|
-
// only a primitive has a meaningful substring form. An absent or
|
|
126
|
-
// structured left operand is not "in" a string, and must not be
|
|
127
|
-
// coerced to '' — every string contains the empty string, so that
|
|
128
|
-
// made `feature.missingAttr in "someString"` true for every feature.
|
|
129
|
-
return typeof left === 'string' ||
|
|
130
|
-
typeof left === 'number' ||
|
|
131
|
-
typeof left === 'boolean'
|
|
132
|
-
? right.includes(String(left))
|
|
133
|
-
: false;
|
|
134
|
-
}
|
|
135
|
-
return Array.isArray(right) ? right.includes(left) : false;
|
|
136
|
-
}
|
|
162
|
+
eval: isIn
|
|
137
163
|
},
|
|
138
164
|
'!': {
|
|
139
165
|
type: 'unaryOp',
|
|
@@ -162,6 +188,6 @@ export const getGrammar = () => ({
|
|
|
162
188
|
* than throw. An error is only appropriate when the function would normally
|
|
163
189
|
* return a value, but cannot due to some other failure.
|
|
164
190
|
*/
|
|
165
|
-
functions: {}
|
|
191
|
+
functions: { ...collectionFunctions }
|
|
166
192
|
});
|
|
167
193
|
//# sourceMappingURL=grammar.js.map
|
package/esm/grammar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grammar.js","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"grammar.js","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"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"}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
export { Jexl, default } from './Jexl.ts';
|
|
2
|
+
export type { JexlOptions } from './Jexl.ts';
|
|
3
|
+
export type { GetMember, VariableReader } from './grammar.ts';
|
|
2
4
|
export { default as Expression } from './Expression.ts';
|
|
5
|
+
export { analyze } from './analyze.ts';
|
|
6
|
+
export { check, print, recordOf, union } from './check.ts';
|
|
7
|
+
export { callSubject, conditions, fromConditions, pathSubject, printCondition } from './conditions.ts';
|
|
3
8
|
export { default as Lexer } from './Lexer.ts';
|
|
9
|
+
export { JexlSyntaxError } from './errors.ts';
|
|
4
10
|
export { getGrammar } from './grammar.ts';
|
|
11
|
+
export type * from './analyze.ts';
|
|
12
|
+
export type * from './check.ts';
|
|
13
|
+
export type * from './conditions.ts';
|
|
5
14
|
export type * from './types.ts';
|
package/esm/index.js
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { Jexl, default } from "./Jexl.js";
|
|
6
6
|
export { default as Expression } from "./Expression.js";
|
|
7
|
+
export { analyze } from "./analyze.js";
|
|
8
|
+
export { check, print, recordOf, union } from "./check.js";
|
|
9
|
+
export { callSubject, conditions, fromConditions, pathSubject, printCondition } from "./conditions.js";
|
|
7
10
|
export { default as Lexer } from "./Lexer.js";
|
|
11
|
+
export { JexlSyntaxError } from "./errors.js";
|
|
8
12
|
export { getGrammar } from "./grammar.js";
|
|
9
13
|
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGzC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EACL,WAAW,EACX,UAAU,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACf,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JexlValue } from './types.ts';
|
|
2
|
+
type Test = (left: JexlValue, right: JexlValue) => boolean;
|
|
3
|
+
type Arithmetic = (left: JexlValue, right: JexlValue) => JexlValue;
|
|
4
|
+
export declare function isList(left: JexlValue, right: JexlValue): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* A comparison over list operands: it holds when it holds for any value, as
|
|
7
|
+
* bcftools compares a multi-valued tag, so `AF > 0.05` is true when any
|
|
8
|
+
* allele's frequency is and `CLNSIG == 'Pathogenic'` when any significance is.
|
|
9
|
+
* Each operator calls this only once {@link isList} says it must, so the
|
|
10
|
+
* comparison of two single values stays a direct call V8 can inline.
|
|
11
|
+
*/
|
|
12
|
+
export declare function anyPair(test: Test, left: JexlValue, right: JexlValue): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether `+` pairs its operands value by value: only when a list is involved
|
|
15
|
+
* and neither side holds text, so `REF + '>' + ALT` still joins as JavaScript
|
|
16
|
+
* joins, `'A>T,C'`, while `DP + 1` adds.
|
|
17
|
+
*/
|
|
18
|
+
export declare function addsPairwise(left: JexlValue, right: JexlValue): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Arithmetic over list operands, value by value, as bcftools and R apply it:
|
|
21
|
+
* `AC / AN` divides each count, and a list of one, or a lone value, pairs with
|
|
22
|
+
* every value of the other side. Lists of two other lengths have no pairing
|
|
23
|
+
* and yield undefined.
|
|
24
|
+
*/
|
|
25
|
+
export declare function pairwise(fn: Arithmetic, left: JexlValue, right: JexlValue): JexlValue;
|
|
26
|
+
/** Whether a value, or any value of a list, matches a pattern string. */
|
|
27
|
+
export declare function matches(value: JexlValue, pattern: JexlValue): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Whether a value is in a container: a substring of a string, a member of a
|
|
30
|
+
* list or Set, or a key of a Map or plain object. A list on the left is in
|
|
31
|
+
* the container when any of its values is.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isIn(left: JexlValue, right: JexlValue): boolean;
|
|
34
|
+
export {};
|
package/esm/operators.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Jexl
|
|
3
|
+
* Copyright 2020 Tom Shawver
|
|
4
|
+
*/
|
|
5
|
+
export function isList(left, right) {
|
|
6
|
+
return Array.isArray(left) || Array.isArray(right);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A comparison over list operands: it holds when it holds for any value, as
|
|
10
|
+
* bcftools compares a multi-valued tag, so `AF > 0.05` is true when any
|
|
11
|
+
* allele's frequency is and `CLNSIG == 'Pathogenic'` when any significance is.
|
|
12
|
+
* Each operator calls this only once {@link isList} says it must, so the
|
|
13
|
+
* comparison of two single values stays a direct call V8 can inline.
|
|
14
|
+
*/
|
|
15
|
+
export function anyPair(test, left, right) {
|
|
16
|
+
return Array.isArray(left)
|
|
17
|
+
? left.some((l) => anyPair(test, l, right))
|
|
18
|
+
: Array.isArray(right)
|
|
19
|
+
? right.some((r) => anyPair(test, left, r))
|
|
20
|
+
: test(left, right);
|
|
21
|
+
}
|
|
22
|
+
function hasText(value) {
|
|
23
|
+
return (typeof value === 'string' ||
|
|
24
|
+
(Array.isArray(value) && value.some((item) => typeof item === 'string')));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether `+` pairs its operands value by value: only when a list is involved
|
|
28
|
+
* and neither side holds text, so `REF + '>' + ALT` still joins as JavaScript
|
|
29
|
+
* joins, `'A>T,C'`, while `DP + 1` adds.
|
|
30
|
+
*/
|
|
31
|
+
export function addsPairwise(left, right) {
|
|
32
|
+
return isList(left, right) && !hasText(left) && !hasText(right);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Arithmetic over list operands, value by value, as bcftools and R apply it:
|
|
36
|
+
* `AC / AN` divides each count, and a list of one, or a lone value, pairs with
|
|
37
|
+
* every value of the other side. Lists of two other lengths have no pairing
|
|
38
|
+
* and yield undefined.
|
|
39
|
+
*/
|
|
40
|
+
export function pairwise(fn, left, right) {
|
|
41
|
+
const ls = Array.isArray(left) ? left : [left];
|
|
42
|
+
const rs = Array.isArray(right) ? right : [right];
|
|
43
|
+
if (ls.length !== rs.length && ls.length !== 1 && rs.length !== 1) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const length = ls.length === 1 ? rs.length : ls.length;
|
|
47
|
+
const out = new Array(length);
|
|
48
|
+
for (let i = 0; i < length; i++) {
|
|
49
|
+
out[i] = fn(ls.length === 1 ? ls[0] : ls[i], rs.length === 1 ? rs[0] : rs[i]);
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
const patterns = new Map();
|
|
54
|
+
const MAX_PATTERNS = 1000;
|
|
55
|
+
/**
|
|
56
|
+
* The regular expression a pattern string stands for. A leading `(?i)`, the
|
|
57
|
+
* inline flag PCRE, Python and Go read, makes it case-insensitive.
|
|
58
|
+
*/
|
|
59
|
+
function regex(pattern) {
|
|
60
|
+
let re = patterns.get(pattern);
|
|
61
|
+
if (!re) {
|
|
62
|
+
try {
|
|
63
|
+
re = pattern.startsWith('(?i)')
|
|
64
|
+
? new RegExp(pattern.slice(4), 'i')
|
|
65
|
+
: new RegExp(pattern);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
throw new Error(`Invalid regular expression: ${pattern}`);
|
|
69
|
+
}
|
|
70
|
+
if (patterns.size >= MAX_PATTERNS) {
|
|
71
|
+
patterns.clear();
|
|
72
|
+
}
|
|
73
|
+
patterns.set(pattern, re);
|
|
74
|
+
}
|
|
75
|
+
return re;
|
|
76
|
+
}
|
|
77
|
+
/** Whether a value, or any value of a list, matches a pattern string. */
|
|
78
|
+
export function matches(value, pattern) {
|
|
79
|
+
if (typeof pattern !== 'string') {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const re = regex(pattern);
|
|
83
|
+
const test = (v) => (typeof v === 'string' ||
|
|
84
|
+
typeof v === 'number' ||
|
|
85
|
+
typeof v === 'boolean') &&
|
|
86
|
+
re.test(String(v));
|
|
87
|
+
return Array.isArray(value) ? value.some(test) : test(value);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Whether a value is in a container: a substring of a string, a member of a
|
|
91
|
+
* list or Set, or a key of a Map or plain object. A list on the left is in
|
|
92
|
+
* the container when any of its values is.
|
|
93
|
+
*/
|
|
94
|
+
export function isIn(left, right) {
|
|
95
|
+
if (Array.isArray(left)) {
|
|
96
|
+
return left.some((l) => isIn(l, right));
|
|
97
|
+
}
|
|
98
|
+
if (typeof right === 'string') {
|
|
99
|
+
// only a primitive has a meaningful substring form. An absent or
|
|
100
|
+
// structured left operand is not "in" a string, and must not be coerced
|
|
101
|
+
// to '' — every string contains the empty string
|
|
102
|
+
return typeof left === 'string' ||
|
|
103
|
+
typeof left === 'number' ||
|
|
104
|
+
typeof left === 'boolean'
|
|
105
|
+
? right.includes(String(left))
|
|
106
|
+
: false;
|
|
107
|
+
}
|
|
108
|
+
if (Array.isArray(right)) {
|
|
109
|
+
return right.includes(left);
|
|
110
|
+
}
|
|
111
|
+
if (right instanceof Set || right instanceof Map) {
|
|
112
|
+
return right.has(left);
|
|
113
|
+
}
|
|
114
|
+
if (typeof right === 'object' &&
|
|
115
|
+
right !== null &&
|
|
116
|
+
(typeof left === 'string' ||
|
|
117
|
+
typeof left === 'number' ||
|
|
118
|
+
typeof left === 'boolean')) {
|
|
119
|
+
return Object.hasOwn(right, String(left));
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=operators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operators.js","sourceRoot":"","sources":["../src/operators.ts"],"names":[],"mappings":"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"}
|
package/esm/parser/Parser.d.ts
CHANGED
|
@@ -1,104 +1,61 @@
|
|
|
1
|
+
import { JexlSyntaxError } from '../errors.ts';
|
|
1
2
|
import type Lexer from '../Lexer.ts';
|
|
2
3
|
import type { Grammar } from '../grammar.ts';
|
|
3
|
-
import type { AstNode, Token } from '../types.ts';
|
|
4
|
+
import type { AstNode, AstNodeUnion, Lambda, ObjectLiteral, TemplateLiteral, TemplatePart, Token } from '../types.ts';
|
|
5
|
+
export { JexlSyntaxError } from '../errors.ts';
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* unparsable configuration that requires it to throw an Error.
|
|
11
|
-
* @param {{}} grammar The grammar object to use to parse Jexl strings
|
|
12
|
-
* @param {string} [prefix] A string prefix to prepend to the expression string
|
|
13
|
-
* for error messaging purposes. This is useful for when a new Parser is
|
|
14
|
-
* instantiated to parse an subexpression, as the parent Parser's
|
|
15
|
-
* expression string thus far can be passed for a more user-friendly
|
|
16
|
-
* error message.
|
|
17
|
-
* @param {{}} [stopMap] A mapping of token types to any truthy value. When the
|
|
18
|
-
* token type is encountered, the parser will return the mapped value
|
|
19
|
-
* instead of boolean false.
|
|
7
|
+
* Converts the tokens from the {@link Lexer} into an Abstract Syntax Tree, for
|
|
8
|
+
* {@link compileAst} to lower to closures. A Pratt parser: each level of the
|
|
9
|
+
* grammar is a method, from `_sequence` (loosest) down to `_primary`, and
|
|
10
|
+
* binary operators are climbed by the precedence the grammar gives them, so
|
|
11
|
+
* operators a host registers slot in without the parser knowing them.
|
|
20
12
|
*/
|
|
21
13
|
declare class Parser {
|
|
22
14
|
_grammar: Grammar;
|
|
23
15
|
_lexer: Lexer;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
_subParser?: Parser;
|
|
30
|
-
_parentStop?: boolean;
|
|
31
|
-
_nextIdentEncapsulate?: boolean;
|
|
32
|
-
_curObjKey?: string;
|
|
33
|
-
_sequenceExpressions?: AstNode[];
|
|
34
|
-
constructor(grammar: Grammar, lexer: Lexer, prefix?: string, stopMap?: Record<string, string>);
|
|
16
|
+
_tokens: Token[];
|
|
17
|
+
_pos: number;
|
|
18
|
+
_offset: number;
|
|
19
|
+
_grouped?: WeakSet<AstNode>;
|
|
20
|
+
_lambdaDepth: number;
|
|
35
21
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @param {{type: <string>}} token A token object, as provided by the
|
|
39
|
-
* {@link Lexer#tokenize} function.
|
|
40
|
-
* @throws {Error} if a token is added when the Parser has been marked as
|
|
41
|
-
* complete by {@link #complete}, or if an unexpected token type is added.
|
|
42
|
-
* @returns {boolean|*} the stopState value if this parser encountered a token
|
|
43
|
-
* in the stopState mapb false if tokens can continue.
|
|
44
|
-
*/
|
|
45
|
-
addToken(token: Token): string | false;
|
|
46
|
-
/**
|
|
47
|
-
* Processes an array of tokens iteratively through the {@link #addToken}
|
|
48
|
-
* function.
|
|
49
|
-
* @param {Array<{type: <string>}>} tokens An array of tokens, as provided by
|
|
50
|
-
* the {@link Lexer#tokenize} function.
|
|
22
|
+
* @param offset where the tokens start in the source, so that an error
|
|
23
|
+
* inside a template interpolation reports its place in the whole
|
|
51
24
|
*/
|
|
25
|
+
constructor(grammar: Grammar, lexer: Lexer, offset?: number);
|
|
26
|
+
parse(source: string): AstNodeUnion | null;
|
|
52
27
|
addTokens(tokens: Token[]): void;
|
|
53
28
|
/**
|
|
54
|
-
*
|
|
55
|
-
* @
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Sets the parent of a node by creating a non-enumerable _parent property
|
|
87
|
-
* that points to the supplied parent argument.
|
|
88
|
-
* @param {{type: <string>}} node A node of the AST on which to set a new
|
|
89
|
-
* parent
|
|
90
|
-
* @param {{type: <string>}} parent An existing node of the AST to serve as the
|
|
91
|
-
* parent of the new node
|
|
92
|
-
* @private
|
|
93
|
-
*/
|
|
94
|
-
_setParent(node: AstNode, parent: AstNode): void;
|
|
95
|
-
/**
|
|
96
|
-
* Prepares the Parser to accept a subexpression by (re)instantiating the
|
|
97
|
-
* subParser.
|
|
98
|
-
* @param {string} [exprStr] The expression string to prefix to the new Parser
|
|
99
|
-
* @returns {Parser} the new subParser, also stored on this instance
|
|
100
|
-
* @private
|
|
101
|
-
*/
|
|
102
|
-
_startSubExpression(exprStr?: string): Parser;
|
|
29
|
+
* @returns the expression tree, or null for an expression with no tokens
|
|
30
|
+
* @throws {JexlSyntaxError} if the tokens do not form exactly one expression
|
|
31
|
+
*/
|
|
32
|
+
complete(): AstNodeUnion | null;
|
|
33
|
+
_sequence(): AstNodeUnion;
|
|
34
|
+
_assignment(): AstNodeUnion;
|
|
35
|
+
_atLambda(): boolean;
|
|
36
|
+
/** Parses the lambda {@link _atLambda} found, whose shape it has checked. */
|
|
37
|
+
_lambda(): Lambda;
|
|
38
|
+
_ternary(): AstNodeUnion;
|
|
39
|
+
/**
|
|
40
|
+
* Parses operands joined by binary operators that bind tighter than `floor`.
|
|
41
|
+
* One exactly at `floor` binds only when it continues a right-associative
|
|
42
|
+
* chain, which is how `a ^ b ^ c` groups from the right.
|
|
43
|
+
*/
|
|
44
|
+
_binary(floor: number, rightAssociative?: boolean): AstNodeUnion;
|
|
45
|
+
/** `a ?? b || c` has no grouping a reader can guess; JS refuses it too. */
|
|
46
|
+
_mixesNullish(operator: string, ...operands: AstNodeUnion[]): boolean;
|
|
47
|
+
_unary(): AstNodeUnion;
|
|
48
|
+
_postfix(subject: AstNodeUnion): AstNodeUnion;
|
|
49
|
+
_primary(): AstNodeUnion;
|
|
50
|
+
_list(close: string): AstNode[];
|
|
51
|
+
_object(): ObjectLiteral;
|
|
52
|
+
_template(tokenParts: TemplatePart[], index: number): TemplateLiteral;
|
|
53
|
+
_peek(): Token | undefined;
|
|
54
|
+
_next(): Token;
|
|
55
|
+
_eat(type: string): boolean;
|
|
56
|
+
_expect(type: string): Token;
|
|
57
|
+
_unexpected(index: number): JexlSyntaxError;
|
|
58
|
+
_error(message: string, index: number): JexlSyntaxError;
|
|
59
|
+
_offsetOf(index: number): number;
|
|
103
60
|
}
|
|
104
61
|
export default Parser;
|