subscript 5.1.0 → 5.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 -7
- package/evaluate.js +0 -34
- package/justin.js +172 -58
- package/justin.min.js +1 -1
- package/package.json +1 -1
- package/parse.js +18 -97
- package/subscript.js +125 -2
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
# <img alt="subscript" src="/subscript2.svg" height=42/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
|
|
1
|
+
# <img alt="subscript" src="/subscript2.svg" height=42/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
|
|
2
|
+
<a href="https://github.com/spectjs/subscript/actions/workflows/node.js.yml"><img src="https://github.com/spectjs/subscript/actions/workflows/node.js.yml/badge.svg"/></a>
|
|
3
|
+
<a href="http://npmjs.org/subscript"><img src="https://img.shields.io/npm/v/subscript?color=indianred"/></a>
|
|
4
|
+
<a href="http://microjs.com/#subscript"><img src="https://img.shields.io/badge/microjs-subscript-blue?color=darkslateblue"/></a>
|
|
2
5
|
|
|
3
6
|
_Subscript_ is micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust, Swift, Objective C, Kotlin etc.<br/>
|
|
4
7
|
|
|
@@ -27,7 +30,7 @@ _Subscript_ is designed to be useful for:
|
|
|
27
30
|
* custom DSL
|
|
28
31
|
|
|
29
32
|
[_Jsep_](https://github.com/EricSmekens/jsep) is generally fine for the listed tasks, unless you need dependencies as small as possible.
|
|
30
|
-
_Subscript_ has [2.5kb](https://npmfs.com/package/subscript/5.
|
|
33
|
+
_Subscript_ has [2.5kb](https://npmfs.com/package/subscript/5.2.0/subscript.min.js) footprint vs [11.4kb](https://npmfs.com/package/jsep/1.2.0/dist/jsep.min.js) _jsep_, with _jsep+_ test coverage and better performance.
|
|
31
34
|
|
|
32
35
|
|
|
33
36
|
## Evaluation
|
|
@@ -49,6 +52,8 @@ evaluate(['+', ['*', 'min', 60], '"sec"'], { min: 5 }) // min*60 + "sec" == "300
|
|
|
49
52
|
|
|
50
53
|
## Extending
|
|
51
54
|
|
|
55
|
+
### Operators
|
|
56
|
+
|
|
52
57
|
Default operators include common operators for the listed languages in the following precedence:
|
|
53
58
|
|
|
54
59
|
* `++ --` unary postfix
|
|
@@ -83,14 +88,15 @@ let tree = parse(`
|
|
|
83
88
|
evaluate(tree, { Math, map, take, interval, gaussian })
|
|
84
89
|
```
|
|
85
90
|
|
|
86
|
-
|
|
91
|
+
### Tokens
|
|
87
92
|
|
|
88
|
-
Tokens are extensible via `parse.token` list, can be added support of _literals_, _regexes_, _strings_, _numbers_ and others.
|
|
89
93
|
Default tokens include:
|
|
90
94
|
|
|
91
95
|
* `"abc"` strings
|
|
92
96
|
* `1.2e+3` floats
|
|
93
|
-
* identifiers
|
|
97
|
+
* `name` identifiers
|
|
98
|
+
|
|
99
|
+
Tokens are extensible via `parse.token` list, can be added support of _literals_, _regexes_, _strings_, _numbers_ and others.
|
|
94
100
|
|
|
95
101
|
```js
|
|
96
102
|
import parse, {char} from 'subscript/parse.js'
|
|
@@ -101,7 +107,7 @@ parse.token.unshift(c => char(4) === 'this' ? ctx : null)
|
|
|
101
107
|
evaluate(parse(`this.x`)) // 1
|
|
102
108
|
```
|
|
103
109
|
|
|
104
|
-
|
|
110
|
+
### Spaces/comments
|
|
105
111
|
|
|
106
112
|
Comments can be added via extending `parse.space`. See [justin.js](./justin.js) for more examples.
|
|
107
113
|
|
|
@@ -279,7 +285,7 @@ Subscript shows relatively good performance within other evaluators:
|
|
|
279
285
|
// 1 + (a * b / c % d) - 2.0 + -3e-3 * +4.4e4 / f.g[0] - i.j(+k == 1)(0)
|
|
280
286
|
// parse 30k times
|
|
281
287
|
|
|
282
|
-
subscript: ~
|
|
288
|
+
subscript: ~230 ms
|
|
283
289
|
jsep: ~280 ms
|
|
284
290
|
expr-eval: ~480 ms
|
|
285
291
|
jexl: ~1200 ms
|
package/evaluate.js
CHANGED
|
@@ -22,38 +22,4 @@ lookup = {},
|
|
|
22
22
|
// multiple args allows shortcuts, lisp compatible, easy manual eval, functions anyways take multiple arguments
|
|
23
23
|
operator = evaluate.operator = (op, fn) => lookup[op] = fn.length == 2 ? (...a)=>a.reduce(fn) : fn
|
|
24
24
|
|
|
25
|
-
for (let fn,ops = [
|
|
26
|
-
'!', a=>!a,
|
|
27
|
-
'++', a=>++a,
|
|
28
|
-
'--', a=>--a,
|
|
29
|
-
|
|
30
|
-
'.', (a,b)=>a?a[b]:a,
|
|
31
|
-
|
|
32
|
-
'%', (a,b)=>a%b,
|
|
33
|
-
'/', (a,b)=>a/b,
|
|
34
|
-
'*', (a,b)=>a*b,
|
|
35
|
-
|
|
36
|
-
'+', (a,b)=>a+b,
|
|
37
|
-
'-', (...a)=>a.length < 2 ? -a : a.reduce((a,b)=>a-b),
|
|
38
|
-
|
|
39
|
-
'>>>', (a,b)=>a>>>b,
|
|
40
|
-
'>>', (a,b)=>a>>b,
|
|
41
|
-
'<<', (a,b)=>a<<b,
|
|
42
|
-
|
|
43
|
-
'>=', (a,b)=>a>=b,
|
|
44
|
-
'>', (a,b)=>a>b,
|
|
45
|
-
'<=', (a,b)=>a<=b,
|
|
46
|
-
'<', (a,b)=>a<b,
|
|
47
|
-
|
|
48
|
-
'!=', (a,b)=>a!=b,
|
|
49
|
-
'==', (a,b)=>a==b,
|
|
50
|
-
|
|
51
|
-
'&', (a,b)=>a&b,
|
|
52
|
-
'^', (a,b)=>a^b,
|
|
53
|
-
'|', (a,b)=>a|b,
|
|
54
|
-
'&&', (...a)=>a.every(Boolean),
|
|
55
|
-
'||', (...a)=>a.some(Boolean),
|
|
56
|
-
',', (a,b)=>(a,b)
|
|
57
|
-
]; fn=ops.pop();) operator(ops.pop(),fn)
|
|
58
|
-
|
|
59
25
|
export default evaluate
|
package/justin.js
CHANGED
|
@@ -1,61 +1,134 @@
|
|
|
1
1
|
// justin lang https://github.com/endojs/Jessie/issues/66
|
|
2
2
|
import {evaluate} from './evaluate.js'
|
|
3
|
-
import {parse, code, char, skip, expr, err} from './parse.js'
|
|
3
|
+
import {parse, code, char, skip, expr, err, val} from './parse.js'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
const PERIOD=46, OPAREN=40, CPAREN=41, CBRACK=93, SPACE=32,
|
|
6
|
+
|
|
7
|
+
PREC_SEQ=1, PREC_TERN=3, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
|
|
8
|
+
PREC_EQ=9, PREC_COMP=10, PREC_SHIFT=11, PREC_SUM=12, PREC_MULT=13, PREC_UNARY=15, PREC_POSTFIX=16, PREC_CALL=18, PREC_GROUP=19,
|
|
9
|
+
PREC_EXP=14, PREC_TOKEN=20
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// tokens
|
|
13
|
+
parse.token.push(
|
|
14
|
+
// 1.2e+3, .5 - fast & small version, but consumes corrupted nums as well
|
|
15
|
+
(number) => (
|
|
16
|
+
(number = skip(c => (c > 47 && c < 58) || c == PERIOD)) && (
|
|
17
|
+
(code() == 69 || code() == 101) && (number += skip(2) + skip(c => c >= 48 && c <= 57)),
|
|
18
|
+
isNaN(number = new Number(number)) ? err('Bad number') : number
|
|
19
|
+
)
|
|
20
|
+
),
|
|
21
|
+
|
|
22
|
+
// "' with /
|
|
23
|
+
(q, qc, c, str) => {
|
|
24
|
+
if (q !== 34 && q !== 39) return
|
|
25
|
+
qc = char(), skip(), str = ''
|
|
26
|
+
while (c=code(), c-q) {
|
|
27
|
+
if (c === 92) skip(), str += escape[char()] || char(); else str+=char()
|
|
28
|
+
skip()
|
|
29
|
+
}
|
|
30
|
+
return skip(), qc + str + qc
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// id
|
|
34
|
+
c => skip(c =>
|
|
35
|
+
(c >= 48 && c <= 57) || // 0..9
|
|
36
|
+
(c >= 65 && c <= 90) || // A...Z
|
|
37
|
+
(c >= 97 && c <= 122) || // a...z
|
|
38
|
+
c == 36 || c == 95 || // $, _,
|
|
39
|
+
(c >= 192 && c != 215 && c != 247) // any non-ASCII
|
|
40
|
+
)
|
|
13
41
|
)
|
|
14
42
|
|
|
15
|
-
// "' with /
|
|
16
|
-
parse.token[1] = (q, qc, c, str) => {
|
|
17
|
-
if (q !== 34 && q !== 39) return
|
|
18
|
-
qc = char(), skip(), str = ''
|
|
19
|
-
while (c=code(), c-q) {
|
|
20
|
-
if (c === 92) skip(), str += escape[char()] || char(); else str+=char()
|
|
21
|
-
skip()
|
|
22
|
-
}
|
|
23
|
-
return skip(), qc + str + qc
|
|
24
|
-
}
|
|
25
43
|
const escape = {n:'\n', r:'\r', t:'\t', b:'\b', f:'\f', v:'\v'}
|
|
26
44
|
|
|
45
|
+
|
|
27
46
|
// /**/, //
|
|
28
47
|
parse.space = cc => {
|
|
29
|
-
while (cc = code(), cc <= 32) {
|
|
30
|
-
skip()
|
|
31
|
-
if (
|
|
48
|
+
while (cc = code(), cc <= 32 || cc === 47) {
|
|
49
|
+
if (cc <= 32) skip()
|
|
50
|
+
else if (cc === 47)
|
|
32
51
|
// /**/
|
|
33
52
|
if (code(1) === 42) skip(2), skip(c => c !== 42 && code(1) !== 47), skip(2)
|
|
34
53
|
// //
|
|
35
54
|
else if (code(1) === 47) skip(2), skip(c => c >= 32)
|
|
55
|
+
else break
|
|
36
56
|
}
|
|
37
57
|
return cc
|
|
38
58
|
}
|
|
39
59
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
))
|
|
44
|
-
const map = (n, args) => {
|
|
45
|
-
if (!n[1]) args = []
|
|
46
|
-
else if (n[1][0]==':') args = [n[1]]
|
|
47
|
-
else if (n[1][0]==',') args = n[1].slice(1)
|
|
48
|
-
return ['{', ...args]
|
|
60
|
+
|
|
61
|
+
// operators
|
|
62
|
+
const addOps = (add, stride=2, list) => {
|
|
63
|
+
for (let i = 0; i < list.length; i+=stride) add(list[i], list[i+1], list[i+2])
|
|
49
64
|
}
|
|
50
65
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
'
|
|
55
|
-
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
|
|
66
|
+
addOps(parse.operator, 3, [
|
|
67
|
+
// subscript ones
|
|
68
|
+
// TODO: add ,, as node here?
|
|
69
|
+
',', PREC_SEQ,,
|
|
70
|
+
|
|
71
|
+
'|', PREC_OR,,
|
|
72
|
+
'||', PREC_SOME,,
|
|
73
|
+
|
|
74
|
+
'&', PREC_AND,,
|
|
75
|
+
'&&', PREC_EVERY,,
|
|
76
|
+
|
|
77
|
+
'^', PREC_XOR,,
|
|
78
|
+
|
|
79
|
+
// ==, !=
|
|
80
|
+
'==', PREC_EQ,,
|
|
81
|
+
'!=', PREC_EQ,,
|
|
82
|
+
|
|
83
|
+
// > >= >> >>>, < <= <<
|
|
84
|
+
'>', PREC_COMP,,
|
|
85
|
+
'>=', PREC_COMP,,
|
|
86
|
+
'>>', PREC_SHIFT,,
|
|
87
|
+
'>>>', PREC_SHIFT,,
|
|
88
|
+
'<', PREC_COMP,,
|
|
89
|
+
'<=', PREC_COMP,,
|
|
90
|
+
'<<', PREC_SHIFT,,
|
|
91
|
+
|
|
92
|
+
// + ++ - --
|
|
93
|
+
'+', PREC_SUM,,
|
|
94
|
+
'+', PREC_UNARY, -1,
|
|
95
|
+
'++', PREC_UNARY, -1,
|
|
96
|
+
'++', PREC_UNARY, +1,
|
|
97
|
+
'-', PREC_SUM,,
|
|
98
|
+
'-', PREC_UNARY, -1,
|
|
99
|
+
'--', PREC_UNARY, -1,
|
|
100
|
+
'--', PREC_UNARY, +1,
|
|
101
|
+
|
|
102
|
+
// !
|
|
103
|
+
'!', PREC_UNARY, -1,
|
|
104
|
+
|
|
105
|
+
// * / %
|
|
106
|
+
'*', PREC_MULT,,
|
|
107
|
+
'/', PREC_MULT,,
|
|
108
|
+
'%', PREC_MULT,,
|
|
109
|
+
|
|
110
|
+
// a.b
|
|
111
|
+
'.', PREC_CALL, (node,b) => node && [skip(),node, typeof (b = expr(PREC_CALL)) === 'string' ? '"' + b + '"' : b.valueOf()],
|
|
112
|
+
|
|
113
|
+
// a[b]
|
|
114
|
+
'[', PREC_CALL, (node) => (skip(), node = ['.', node, val(expr(0,CBRACK))], skip(), node),
|
|
115
|
+
']',,,
|
|
116
|
+
|
|
117
|
+
// a(b)
|
|
118
|
+
'(', PREC_CALL, (node,b) => ( skip(), b=expr(0,CPAREN), skip(),
|
|
119
|
+
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, val(b)] : [node]
|
|
120
|
+
),
|
|
121
|
+
// (a+b)
|
|
122
|
+
'(', PREC_GROUP, (node,b) => !node && (skip(), b=expr(0,CPAREN) || err(), skip(), b),
|
|
123
|
+
')',,,
|
|
124
|
+
|
|
125
|
+
// justin extension
|
|
126
|
+
';', PREC_SEQ,,
|
|
127
|
+
'===', PREC_EQ,,
|
|
128
|
+
'!==', PREC_EQ,,
|
|
129
|
+
'**', PREC_EXP,,
|
|
130
|
+
'~', PREC_UNARY, -1,
|
|
131
|
+
'?', PREC_TERN, (node) => {
|
|
59
132
|
if (!node) err('Expected expression')
|
|
60
133
|
let a, b
|
|
61
134
|
skip(), parse.space(), a = expr()
|
|
@@ -64,37 +137,78 @@ for (let i = 0, ops = [
|
|
|
64
137
|
return ['?:', node, a, b]
|
|
65
138
|
},
|
|
66
139
|
'}',,,
|
|
67
|
-
':'
|
|
68
|
-
'in',
|
|
69
|
-
|
|
140
|
+
':',,,
|
|
141
|
+
'in', PREC_COMP, (node) => code(2) <= 32 && [skip(2), '"'+node+'"', expr(PREC_COMP)],
|
|
142
|
+
|
|
143
|
+
// as operator it's faster to lookup (no need to extra rule check), smaller and no conflict with word names
|
|
144
|
+
// [a,b,c]
|
|
145
|
+
'[', PREC_TOKEN, (node,arg) => !node && (
|
|
70
146
|
skip(), arg=expr(0,93), skip(),
|
|
71
|
-
!arg ? ['['] : arg[0]
|
|
72
|
-
)
|
|
73
|
-
]; i < ops.length;) parse.operator(ops[i++],ops[i++],ops[i++])
|
|
147
|
+
!arg ? ['['] : arg[0] == ',' ? (arg[0]='[',arg) : ['[',arg]
|
|
148
|
+
),
|
|
74
149
|
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
150
|
+
// {a:0, b:1}
|
|
151
|
+
'{', PREC_TOKEN, (node,arg) => !node && (skip(), arg=expr(0,125), skip(),
|
|
152
|
+
!arg ? ['{'] : arg[0] == ':' ? ['{',arg] : arg[0] == ',' ? (arg[0]='{',arg) : ['{',arg])
|
|
153
|
+
,
|
|
79
154
|
|
|
80
|
-
//
|
|
81
|
-
'
|
|
155
|
+
// literals
|
|
156
|
+
'null', PREC_TOKEN, node=>!node&&(skip(4),v(null)),
|
|
157
|
+
'false', PREC_TOKEN, node=>!node&&(skip(5),v(false)),
|
|
158
|
+
'true', PREC_TOKEN, node=>!node&&(skip(4),v(true)),
|
|
159
|
+
'undefined', PREC_TOKEN, node=>!node&&(skip(9),v(undefined)),
|
|
160
|
+
])
|
|
161
|
+
const v = v => ({valueOf:()=>v})
|
|
162
|
+
|
|
163
|
+
addOps(evaluate.operator, 2, [
|
|
164
|
+
// subscript
|
|
165
|
+
'!', a=>!a,
|
|
166
|
+
'++', a=>++a,
|
|
167
|
+
'--', a=>--a,
|
|
82
168
|
|
|
83
|
-
|
|
169
|
+
'.', (a,b)=>a?a[b]:a,
|
|
170
|
+
|
|
171
|
+
'%', (a,b)=>a%b,
|
|
172
|
+
'/', (a,b)=>a/b,
|
|
173
|
+
'*', (a,b)=>a*b,
|
|
174
|
+
|
|
175
|
+
'+', (a,b)=>a+b,
|
|
176
|
+
'-', (...a)=>a.length < 2 ? -a : a.reduce((a,b)=>a-b),
|
|
177
|
+
|
|
178
|
+
'>>>', (a,b)=>a>>>b,
|
|
179
|
+
'>>', (a,b)=>a>>b,
|
|
180
|
+
'<<', (a,b)=>a<<b,
|
|
181
|
+
|
|
182
|
+
'>=', (a,b)=>a>=b,
|
|
183
|
+
'>', (a,b)=>a>b,
|
|
184
|
+
'<=', (a,b)=>a<=b,
|
|
185
|
+
'<', (a,b)=>a<b,
|
|
186
|
+
|
|
187
|
+
'!=', (a,b)=>a!=b,
|
|
188
|
+
'==', (a,b)=>a==b,
|
|
189
|
+
|
|
190
|
+
'&', (a,b)=>a&b,
|
|
191
|
+
'^', (a,b)=>a^b,
|
|
192
|
+
'|', (a,b)=>a|b,
|
|
193
|
+
'&&', (...a)=>a.every(Boolean),
|
|
194
|
+
'||', (...a)=>a.some(Boolean),
|
|
195
|
+
',', (a,b)=>(a,b),
|
|
196
|
+
|
|
197
|
+
// justin extension
|
|
198
|
+
'**', (...args)=>args.reduceRight((a,b)=>Math.pow(b,a)),
|
|
199
|
+
'~', a=>~a,
|
|
84
200
|
'?:', (a,b,c)=>a?b:c,
|
|
85
|
-
// parse.operator(':')
|
|
86
|
-
// in
|
|
87
201
|
'in', (a,b)=>a in b,
|
|
88
202
|
|
|
89
|
-
// []
|
|
90
203
|
'[', (...args) => Array(...args),
|
|
91
|
-
// as operator it's faster to lookup (no need to call extra rule check), smaller and no conflict with word names
|
|
92
204
|
'{', (...args)=>Object.fromEntries(args),
|
|
93
205
|
':', (a,b)=>[a,b]
|
|
94
|
-
]
|
|
206
|
+
])
|
|
95
207
|
|
|
96
208
|
// TODO ...
|
|
97
209
|
// TODO: strings interpolation
|
|
98
210
|
|
|
99
|
-
export default parse
|
|
100
211
|
export { parse, evaluate }
|
|
212
|
+
|
|
213
|
+
// code → evaluator
|
|
214
|
+
export default s => (s = typeof s == 'string' ? parse(s) : s, ctx => evaluate(s, ctx))
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=
|
|
1
|
+
var e,r,t=e=>Array.isArray(e)&&("string"==typeof e[0]||t(e[0])),a=(e,r={},o,s)=>t(e)?("string"==typeof(o=e[0])&&(s=n[o]),"function"!=typeof(o=s||a(o,r))?o:o.call(...e.map((e=>a(e,r))))):e&&"string"==typeof e?'"'===e[0]?e.slice(1,-1):"@"===e[0]?e.slice(1):e in r?r[e]:e:e,n={},o=(a.operator=(e,r)=>n[e]=2==r.length?(...e)=>e.reduce(r):r,(t,a)=>(r=t,e=0,a=p(),e<r.length?s():d(a))),s=(t="Bad syntax")=>{throw Error(t+" `"+r[e]+"` at "+e)},f=(t=1,a=e)=>{if("number"==typeof t)e+=t;else for(;t(i());)e++;return r.slice(a,e)},i=(t=0)=>r.charCodeAt(e+t),l=(t=1)=>r.substr(e,t),p=(e=0,r,t,a,n=0,f,i)=>{for(;(t=o.space())&&(i=y[t]?.(a,e)||!a&&c(t));)a=i;return r&&t!==r&&s("Unclosed paren"),a},u=(o.space=r=>{for(;(r=i())<=32;)e++;return r},o.token=[]),c=(e,r=0,t)=>{for(;r<u.length;)if(t=u[r++](e))return t},y=[],d=(o.operator=(r,t=0,a=0,n,u=r.charCodeAt(0),c=r.length,h=y[u],v=a<=0&&r.toUpperCase()!==r)=>(n=a?a>0?e=>e&&[f(c),d(e)]:a<0?e=>!e&&[f(c),d(p(t-1))]:a:a=>{a=[r,a||s()];do{e+=c,a.push(d(p(t)))}while(o.space()==u&&(c<2||l(c)==r)&&(!v||i(c)<=32));return a},y[u]=(e,a)=>a<t&&(c<2||l(c)==r)&&(!v||i(c)<=32)&&n(e)||h&&h(e,a)),e=>Array.isArray(e)?e:(e||s()).valueOf()),h=10,v=15,g=20;o.token.push((e=>(e=f((e=>e>47&&e<58||46==e)))&&((69==i()||101==i())&&(e+=f(2)+f((e=>e>=48&&e<=57))),isNaN(e=new Number(e))?s("Bad number"):e)),((e,r,t,a)=>{if(34===e||39===e){for(r=l(),f(),a="";(t=i())-e;)92===t?(f(),a+=A[l()]||l()):a+=l(),f();return f(),r+a+r}}),(e=>f((e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e))));var A={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"};o.space=e=>{for(;(e=i())<=32||47===e;)if(e<=32)f();else if(47===e)if(42===i(1))f(2),f((e=>42!==e&&47!==i(1))),f(2);else{if(47!==i(1))break;f(2),f((e=>e>=32))}return e};var b=(e,r=2,t)=>{for(let a=0;a<t.length;a+=r)e(t[a],t[a+1],t[a+2])};b(o.operator,3,[",",1,,"|",6,,"||",4,,"&",8,,"&&",5,,"^",7,,"==",9,,"!=",9,,">",h,,">=",h,,">>",11,,">>>",11,,"<",h,,"<=",h,,"<<",11,,"+",12,,"+",v,-1,"++",v,-1,"++",v,1,"-",12,,"-",v,-1,"--",v,-1,"--",v,1,"!",v,-1,"*",13,,"/",13,,"%",13,,".",18,(e,r)=>e&&[f(),e,"string"==typeof(r=p(18))?'"'+r+'"':r.valueOf()],"[",18,e=>(f(),e=[".",e,d(p(0,93))],f(),e),"]",,,"(",18,(e,r)=>(f(),r=p(0,41),f(),Array.isArray(r)&&","===r[0]?(r[0]=e,r):r?[e,d(r)]:[e]),"(",19,(e,r)=>!e&&(f(),r=p(0,41)||s(),f(),r),")",,,";",1,,"===",9,,"!==",9,,"**",14,,"~",v,-1,"?",3,e=>{let r,t;return e||s("Expected expression"),f(),o.space(),r=p(),58!==i()&&s("Expected :"),f(),o.space(),t=p(),["?:",e,r,t]},"}",,,":",,,"in",h,e=>i(2)<=32&&[f(2),'"'+e+'"',p(h)],"[",g,(e,r)=>!e&&(f(),r=p(0,93),f(),r?","==r[0]?(r[0]="[",r):["[",r]:["["]),"{",g,(e,r)=>!e&&(f(),r=p(0,125),f(),r?":"==r[0]?["{",r]:","==r[0]?(r[0]="{",r):["{",r]:["{"]),"null",g,e=>!e&&(f(4),m(null)),"false",g,e=>!e&&(f(5),m(!1)),"true",g,e=>!e&&(f(4),m(!0)),"undefined",g,e=>!e&&(f(9),m(void 0))]);var m=e=>({valueOf:()=>e});b(a.operator,2,["!",e=>!e,"++",e=>++e,"--",e=>--e,".",(e,r)=>e&&e[r],"%",(e,r)=>e%r,"/",(e,r)=>e/r,"*",(e,r)=>e*r,"+",(e,r)=>e+r,"-",(...e)=>e.length<2?-e:e.reduce(((e,r)=>e-r)),">>>",(e,r)=>e>>>r,">>",(e,r)=>e>>r,"<<",(e,r)=>e<<r,">=",(e,r)=>e>=r,">",(e,r)=>e>r,"<=",(e,r)=>e<=r,"<",(e,r)=>e<r,"!=",(e,r)=>e!=r,"==",(e,r)=>e==r,"&",(e,r)=>e&r,"^",(e,r)=>e^r,"|",(e,r)=>e|r,"&&",(...e)=>e.every(Boolean),"||",(...e)=>e.some(Boolean),",",(e,r)=>r,"**",(...e)=>e.reduceRight(((e,r)=>Math.pow(r,e))),"~",e=>~e,"?:",(e,r,t)=>e?r:t,"in",(e,r)=>e in r,"[",(...e)=>Array(...e),"{",(...e)=>Object.fromEntries(e),":",(e,r)=>[e,r]]);var x=e=>(e="string"==typeof e?o(e):e,r=>a(e,r));export{x as default,a as evaluate,o as parse};
|
package/package.json
CHANGED
package/parse.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
PREC_SEQ=1, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
|
|
4
|
-
PREC_EQ=9, PREC_COMP=10, PREC_SHIFT=11, PREC_SUM=12, PREC_MULT=13, PREC_UNARY=15, PREC_POSTFIX=16, PREC_CALL=18, PREC_GROUP=19
|
|
5
|
-
|
|
1
|
+
const SPACE=32
|
|
6
2
|
|
|
7
3
|
// current string & index
|
|
8
4
|
let idx, cur
|
|
9
5
|
|
|
10
|
-
export const parse = (str, tree) => (cur=str, idx=0, tree=expr(), idx<cur.length ? err() : tree
|
|
6
|
+
export const parse = (str, tree) => (cur=str, idx=0, tree=expr(), idx<cur.length ? err() : val(tree)),
|
|
11
7
|
|
|
12
8
|
err = (msg='Bad syntax') => { throw Error(msg + ' `' + cur[idx] + '` at ' + idx) },
|
|
13
9
|
|
|
@@ -37,26 +33,7 @@ expr = (prec=0, end, cc, node, i=0, map, newNode) => {
|
|
|
37
33
|
space = parse.space = cc => { while (cc = code(), cc <= SPACE) idx++; return cc },
|
|
38
34
|
|
|
39
35
|
// tokens
|
|
40
|
-
tokens = parse.token = [
|
|
41
|
-
// 1.2e+3, .5 - fast & small version, but consumes corrupted nums as well
|
|
42
|
-
(number) => (
|
|
43
|
-
(number = skip(c => (c > 47 && c < 58) || c == PERIOD)) && (
|
|
44
|
-
(code() == 69 || code() == 101) && (number += skip(2) + skip(c => c >= 48 && c <= 57)),
|
|
45
|
-
isNaN(number = new Number(number)) ? err('Bad number') : number
|
|
46
|
-
)
|
|
47
|
-
),
|
|
48
|
-
// "a"
|
|
49
|
-
(q, qc) => q == 34 && (skip() + skip(c => c-q) + skip()),
|
|
50
|
-
// id
|
|
51
|
-
c => skip(c =>
|
|
52
|
-
(c >= 48 && c <= 57) || // 0..9
|
|
53
|
-
(c >= 65 && c <= 90) || // A...Z
|
|
54
|
-
(c >= 97 && c <= 122) || // a...z
|
|
55
|
-
c == 36 || c == 95 || // $, _,
|
|
56
|
-
(c >= 192 && c != 215 && c != 247) // any non-ASCII
|
|
57
|
-
)
|
|
58
|
-
],
|
|
59
|
-
|
|
36
|
+
tokens = parse.token = [],
|
|
60
37
|
token = (c,i=0,node) => { while(i<tokens.length) if (node = tokens[i++](c)) return node },
|
|
61
38
|
|
|
62
39
|
// operator lookup table
|
|
@@ -66,83 +43,27 @@ lookup = [],
|
|
|
66
43
|
// @param op is operator string
|
|
67
44
|
// @param prec is operator precedenc to check
|
|
68
45
|
// @param map is either number +1 - postfix unary, -1 prefix unary, 0 binary, else - custom mapper function
|
|
69
|
-
operator = parse.operator =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
46
|
+
operator = parse.operator = (
|
|
47
|
+
op, prec=0, type=0, map, c=op.charCodeAt(0), l=op.length,
|
|
48
|
+
prev=lookup[c],
|
|
49
|
+
spaced=type<=0&&op.toUpperCase()!==op // non-postfix word operator must have space after
|
|
50
|
+
) => (
|
|
74
51
|
map = !type ? node => { // binary, consume same-op group
|
|
75
52
|
node = [op, node || err()]
|
|
76
|
-
|
|
77
|
-
|
|
53
|
+
do { idx+=l, node.push(val(expr(prec))) }
|
|
54
|
+
while (parse.space()==c && (l<2||char(l)==op) && (!spaced||code(l)<=SPACE))
|
|
78
55
|
return node
|
|
79
56
|
} :
|
|
80
|
-
type > 0 ? node => node && [skip(l), node] : // postfix unary
|
|
81
|
-
type < 0 ? node => !node && [skip(l), (expr(prec-1)
|
|
57
|
+
type > 0 ? node => node && [skip(l), val(node)] : // postfix unary
|
|
58
|
+
type < 0 ? node => !node && [skip(l), val(expr(prec-1))] : // prefix unary
|
|
82
59
|
type,
|
|
83
60
|
|
|
84
|
-
lookup[c] = (node, curPrec) =>
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
for (let i = 0, ops = [
|
|
89
|
-
// TODO: add ,, as node here
|
|
90
|
-
',', PREC_SEQ,,
|
|
91
|
-
|
|
92
|
-
'|', PREC_OR,,
|
|
93
|
-
'||', PREC_SOME,,
|
|
94
|
-
|
|
95
|
-
'&', PREC_AND,,
|
|
96
|
-
'&&', PREC_EVERY,,
|
|
97
|
-
|
|
98
|
-
'^', PREC_XOR,,
|
|
99
|
-
|
|
100
|
-
// ==, !=
|
|
101
|
-
'==', PREC_EQ,,
|
|
102
|
-
'!=', PREC_EQ,,
|
|
103
|
-
|
|
104
|
-
// > >= >> >>>, < <= <<
|
|
105
|
-
'>', PREC_COMP,,
|
|
106
|
-
'>=', PREC_COMP,,
|
|
107
|
-
'>>', PREC_SHIFT,,
|
|
108
|
-
'>>>', PREC_SHIFT,,
|
|
109
|
-
'<', PREC_COMP,,
|
|
110
|
-
'<=', PREC_COMP,,
|
|
111
|
-
'<<', PREC_SHIFT,,
|
|
112
|
-
|
|
113
|
-
// + ++ - --
|
|
114
|
-
'+', PREC_SUM,,
|
|
115
|
-
'+', PREC_UNARY, -1,
|
|
116
|
-
'++', PREC_UNARY, -1,
|
|
117
|
-
'++', PREC_UNARY, +1,
|
|
118
|
-
'-', PREC_SUM,,
|
|
119
|
-
'-', PREC_UNARY, -1,
|
|
120
|
-
'--', PREC_UNARY, -1,
|
|
121
|
-
'--', PREC_UNARY, +1,
|
|
122
|
-
|
|
123
|
-
// ! ~
|
|
124
|
-
'!', PREC_UNARY, -1,
|
|
125
|
-
|
|
126
|
-
// * / %
|
|
127
|
-
'*', PREC_MULT,,
|
|
128
|
-
'/', PREC_MULT,,
|
|
129
|
-
'%', PREC_MULT,,
|
|
130
|
-
|
|
131
|
-
// a.b
|
|
132
|
-
'.', PREC_CALL, (node,b) => node && [skip(),node, typeof (b = expr(PREC_CALL)) === 'string' ? '"' + b + '"' : b.valueOf()],
|
|
133
|
-
|
|
134
|
-
// a[b]
|
|
135
|
-
'[', PREC_CALL, (node) => (idx++, node = ['.', node, expr(0,CBRACK).valueOf()], idx++, node),
|
|
136
|
-
']',,,
|
|
137
|
-
|
|
138
|
-
// a(b)
|
|
139
|
-
'(', PREC_CALL, (node,b) => ( idx++, b=expr(0,CPAREN), idx++,
|
|
140
|
-
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, b.valueOf()] : [node]
|
|
141
|
-
),
|
|
142
|
-
// (a+b)
|
|
143
|
-
'(', PREC_GROUP, (node,b) => !node && (++idx, b=expr(0,CPAREN) || err(), ++idx, b),
|
|
144
|
-
')',,,
|
|
145
|
-
]; i < ops.length;) operator(ops[i++],ops[i++],ops[i++])
|
|
61
|
+
lookup[c] = (node, curPrec) =>
|
|
62
|
+
curPrec < prec && (l<2||char(l)==op) && (!spaced||code(l)<=SPACE) &&
|
|
63
|
+
map(node) || (prev && prev(node, curPrec))
|
|
64
|
+
),
|
|
146
65
|
|
|
66
|
+
// in order to support literal tokens, we call valueOf any time we create or modify calltree node
|
|
67
|
+
val = node => Array.isArray(node) ? node : (node || err()).valueOf()
|
|
147
68
|
|
|
148
69
|
export default parse
|
package/subscript.js
CHANGED
|
@@ -1,5 +1,128 @@
|
|
|
1
|
-
import parse from './parse.js'
|
|
2
|
-
import evaluate from './evaluate.js'
|
|
1
|
+
import parse, {skip, expr, code, tokens, val, operator as parseOp} from './parse.js'
|
|
2
|
+
import evaluate, {operator as evalOp} from './evaluate.js'
|
|
3
|
+
|
|
4
|
+
const PERIOD=46, OPAREN=40, CPAREN=41, CBRACK=93, SPACE=32,
|
|
5
|
+
|
|
6
|
+
PREC_SEQ=1, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
|
|
7
|
+
PREC_EQ=9, PREC_COMP=10, PREC_SHIFT=11, PREC_SUM=12, PREC_MULT=13, PREC_UNARY=15, PREC_POSTFIX=16, PREC_CALL=18, PREC_GROUP=19
|
|
8
|
+
|
|
9
|
+
tokens.push(
|
|
10
|
+
// 1.2e+3, .5 - fast & small version, but consumes corrupted nums as well
|
|
11
|
+
(number) => (
|
|
12
|
+
(number = skip(c => (c > 47 && c < 58) || c == PERIOD)) && (
|
|
13
|
+
(code() == 69 || code() == 101) && (number += skip(2) + skip(c => c >= 48 && c <= 57)),
|
|
14
|
+
isNaN(number = new Number(number)) ? err('Bad number') : number
|
|
15
|
+
)
|
|
16
|
+
),
|
|
17
|
+
// "a"
|
|
18
|
+
(q, qc) => q == 34 && (skip() + skip(c => c-q) + skip()),
|
|
19
|
+
// id
|
|
20
|
+
c => skip(c =>
|
|
21
|
+
(c >= 48 && c <= 57) || // 0..9
|
|
22
|
+
(c >= 65 && c <= 90) || // A...Z
|
|
23
|
+
(c >= 97 && c <= 122) || // a...z
|
|
24
|
+
c == 36 || c == 95 || // $, _,
|
|
25
|
+
c >= 192 // any non-ASCII
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
const addOps = (add, stride=2, list) => {
|
|
30
|
+
for (let i = 0; i < list.length; i+=stride) add(list[i], list[i+1], list[i+2])
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
addOps(parseOp, 3, [
|
|
34
|
+
',', PREC_SEQ,,
|
|
35
|
+
|
|
36
|
+
'|', PREC_OR,,
|
|
37
|
+
'||', PREC_SOME,,
|
|
38
|
+
|
|
39
|
+
'&', PREC_AND,,
|
|
40
|
+
'&&', PREC_EVERY,,
|
|
41
|
+
|
|
42
|
+
'^', PREC_XOR,,
|
|
43
|
+
|
|
44
|
+
// ==, !=
|
|
45
|
+
'==', PREC_EQ,,
|
|
46
|
+
'!=', PREC_EQ,,
|
|
47
|
+
|
|
48
|
+
// > >= >> >>>, < <= <<
|
|
49
|
+
'>', PREC_COMP,,
|
|
50
|
+
'>=', PREC_COMP,,
|
|
51
|
+
'>>', PREC_SHIFT,,
|
|
52
|
+
'>>>', PREC_SHIFT,,
|
|
53
|
+
'<', PREC_COMP,,
|
|
54
|
+
'<=', PREC_COMP,,
|
|
55
|
+
'<<', PREC_SHIFT,,
|
|
56
|
+
|
|
57
|
+
// + ++ - --
|
|
58
|
+
'+', PREC_SUM,,
|
|
59
|
+
'+', PREC_UNARY, -1,
|
|
60
|
+
'++', PREC_UNARY, -1,
|
|
61
|
+
'++', PREC_POSTFIX, +1,
|
|
62
|
+
'-', PREC_SUM,,
|
|
63
|
+
'-', PREC_UNARY, -1,
|
|
64
|
+
'--', PREC_UNARY, -1,
|
|
65
|
+
'--', PREC_POSTFIX, +1,
|
|
66
|
+
|
|
67
|
+
// ! ~
|
|
68
|
+
'!', PREC_UNARY, -1,
|
|
69
|
+
|
|
70
|
+
// * / %
|
|
71
|
+
'*', PREC_MULT,,
|
|
72
|
+
'/', PREC_MULT,,
|
|
73
|
+
'%', PREC_MULT,,
|
|
74
|
+
|
|
75
|
+
// a.b
|
|
76
|
+
'.', PREC_CALL, (node,b) => node && [skip(),node, typeof (b = expr(PREC_CALL)) === 'string' ? '"' + b + '"' : b.valueOf()],
|
|
77
|
+
|
|
78
|
+
// a[b]
|
|
79
|
+
'[', PREC_CALL, (node) => (skip(), node = ['.', node, val(expr(0,CBRACK))], skip(), node),
|
|
80
|
+
']',,,
|
|
81
|
+
|
|
82
|
+
// a(b)
|
|
83
|
+
'(', PREC_CALL, (node,b) => ( skip(), b=expr(0,CPAREN), skip(),
|
|
84
|
+
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, val(b)] : [node]
|
|
85
|
+
),
|
|
86
|
+
// (a+b)
|
|
87
|
+
'(', PREC_GROUP, (node,b) => !node && (skip(), b=expr(0,CPAREN) || err(), skip(), b),
|
|
88
|
+
')',,,
|
|
89
|
+
])
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
// evaluators
|
|
93
|
+
addOps(evalOp, 2, [
|
|
94
|
+
'!', a=>!a,
|
|
95
|
+
'++', a=>++a,
|
|
96
|
+
'--', a=>--a,
|
|
97
|
+
|
|
98
|
+
'.', (a,b)=>a?a[b]:a,
|
|
99
|
+
|
|
100
|
+
'%', (a,b)=>a%b,
|
|
101
|
+
'/', (a,b)=>a/b,
|
|
102
|
+
'*', (a,b)=>a*b,
|
|
103
|
+
|
|
104
|
+
'+', (a,b)=>a+b,
|
|
105
|
+
'-', (...a)=>a.length < 2 ? -a : a.reduce((a,b)=>a-b),
|
|
106
|
+
|
|
107
|
+
'>>>', (a,b)=>a>>>b,
|
|
108
|
+
'>>', (a,b)=>a>>b,
|
|
109
|
+
'<<', (a,b)=>a<<b,
|
|
110
|
+
|
|
111
|
+
'>=', (a,b)=>a>=b,
|
|
112
|
+
'>', (a,b)=>a>b,
|
|
113
|
+
'<=', (a,b)=>a<=b,
|
|
114
|
+
'<', (a,b)=>a<b,
|
|
115
|
+
|
|
116
|
+
'!=', (a,b)=>a!=b,
|
|
117
|
+
'==', (a,b)=>a==b,
|
|
118
|
+
|
|
119
|
+
'&', (a,b)=>a&b,
|
|
120
|
+
'^', (a,b)=>a^b,
|
|
121
|
+
'|', (a,b)=>a|b,
|
|
122
|
+
'&&', (...a)=>a.every(Boolean),
|
|
123
|
+
'||', (...a)=>a.some(Boolean),
|
|
124
|
+
',', (a,b)=>(a,b)
|
|
125
|
+
])
|
|
3
126
|
|
|
4
127
|
export { parse, evaluate }
|
|
5
128
|
|
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,
|
|
1
|
+
var r,e,t=(t,o)=>(e=t,r=0,o=l(),r<e.length?a():y(o)),a=(t="Bad syntax")=>{throw Error(t+" `"+e[r]+"` at "+r)},o=(t=1,a=r)=>{if("number"==typeof t)r+=t;else for(;t(n());)r++;return e.slice(a,r)},n=(t=0)=>e.charCodeAt(r+t),s=(t=1)=>e.substr(r,t),l=(r=0,e,o,n,s=0,l,p)=>{for(;(o=t.space())&&(p=u[o]?.(n,r)||!n&&f(o));)n=p;return e&&o!==e&&a("Unclosed paren"),n},p=(t.space=e=>{for(;(e=n())<=32;)r++;return e},t.token=[]),f=(r,e=0,t)=>{for(;e<p.length;)if(t=p[e++](r))return t},u=[],i=t.operator=(e,p=0,f=0,i,c=e.charCodeAt(0),h=e.length,g=u[c],d=f<=0&&e.toUpperCase()!==e)=>(i=f?f>0?r=>r&&[o(h),y(r)]:f<0?r=>!r&&[o(h),y(l(p-1))]:f:o=>{o=[e,o||a()];do{r+=h,o.push(y(l(p)))}while(t.space()==c&&(h<2||s(h)==e)&&(!d||n(h)<=32));return o},u[c]=(r,t)=>t<p&&(h<2||s(h)==e)&&(!d||n(h)<=32)&&i(r)||g&&g(r,t)),y=r=>Array.isArray(r)?r:(r||a()).valueOf(),c=t,h=r=>Array.isArray(r)&&("string"==typeof r[0]||h(r[0])),g=(r,e={},t,a)=>h(r)?("string"==typeof(t=r[0])&&(a=d[t]),"function"!=typeof(t=a||g(t,e))?t:t.call(...r.map((r=>g(r,e))))):r&&"string"==typeof r?'"'===r[0]?r.slice(1,-1):"@"===r[0]?r.slice(1):r in e?e[r]:r:r,d={},A=g.operator=(r,e)=>d[r]=2==e.length?(...r)=>r.reduce(e):e,v=g;p.push((r=>(r=o((r=>r>47&&r<58||46==r)))&&((69==n()||101==n())&&(r+=o(2)+o((r=>r>=48&&r<=57))),isNaN(r=new Number(r))?err("Bad number"):r)),((r,e)=>34==r&&o()+o((e=>e-r))+o()),(r=>o((r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192))));var m=(r,e=2,t)=>{for(let a=0;a<t.length;a+=e)r(t[a],t[a+1],t[a+2])};m(i,3,[",",1,,"|",6,,"||",4,,"&",8,,"&&",5,,"^",7,,"==",9,,"!=",9,,">",10,,">=",10,,">>",11,,">>>",11,,"<",10,,"<=",10,,"<<",11,,"+",12,,"+",15,-1,"++",15,-1,"++",16,1,"-",12,,"-",15,-1,"--",15,-1,"--",16,1,"!",15,-1,"*",13,,"/",13,,"%",13,,".",18,(r,e)=>r&&[o(),r,"string"==typeof(e=l(18))?'"'+e+'"':e.valueOf()],"[",18,r=>(o(),r=[".",r,y(l(0,93))],o(),r),"]",,,"(",18,(r,e)=>(o(),e=l(0,41),o(),Array.isArray(e)&&","===e[0]?(e[0]=r,e):e?[r,y(e)]:[r]),"(",19,(r,e)=>!r&&(o(),e=l(0,41)||err(),o(),e),")",,,]),m(A,2,["!",r=>!r,"++",r=>++r,"--",r=>--r,".",(r,e)=>r&&r[e],"%",(r,e)=>r%e,"/",(r,e)=>r/e,"*",(r,e)=>r*e,"+",(r,e)=>r+e,"-",(...r)=>r.length<2?-r:r.reduce(((r,e)=>r-e)),">>>",(r,e)=>r>>>e,">>",(r,e)=>r>>e,"<<",(r,e)=>r<<e,">=",(r,e)=>r>=e,">",(r,e)=>r>e,"<=",(r,e)=>r<=e,"<",(r,e)=>r<e,"!=",(r,e)=>r!=e,"==",(r,e)=>r==e,"&",(r,e)=>r&e,"^",(r,e)=>r^e,"|",(r,e)=>r|e,"&&",(...r)=>r.every(Boolean),"||",(...r)=>r.some(Boolean),",",(r,e)=>e]);var b=r=>(r="string"==typeof r?c(r):r,e=>v(r,e));export{b as default,v as evaluate,c as parse};
|