subscript 3.0.2 → 3.0.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 +5 -4
- package/{src/evaluate.js → evaluate.js} +0 -0
- package/justin.js +31 -7
- package/justin.min.js +1 -1
- package/package.json +3 -2
- package/{src/parse.js → parse.js} +51 -44
- package/subscript.js +2 -2
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# <!--<img alt="subscript" src="/subscript2.svg" height=42/>--> sub͘<em>script</em> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
|
|
2
2
|
|
|
3
|
-
_Subscript_ is micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust.<br/>
|
|
3
|
+
_Subscript_ is micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust, Swift, Objective C, Kotlin etc.<br/>
|
|
4
4
|
|
|
5
|
-
*
|
|
5
|
+
* Well-known syntax
|
|
6
6
|
* Any _subscript_ fragment can be copy-pasted to any target language
|
|
7
7
|
* It's tiny <sub></sub>
|
|
8
8
|
* It's very fast ([see performance](#performance))
|
|
@@ -104,6 +104,7 @@ It adds support for:
|
|
|
104
104
|
+ `{...}` Object literal
|
|
105
105
|
+ `in` binary operator
|
|
106
106
|
+ `;` expression separator
|
|
107
|
+
+ unary word operators
|
|
107
108
|
<!-- + `//, /* */` comments -->
|
|
108
109
|
<!-- + `undefined` literal -->
|
|
109
110
|
<!-- + `?` chaining operator -->
|
|
@@ -263,7 +264,7 @@ Subscript shows relatively good performance within other evaluators:
|
|
|
263
264
|
// parse 30k times
|
|
264
265
|
|
|
265
266
|
subscript: ~280 ms
|
|
266
|
-
jsep: ~
|
|
267
|
+
jsep: ~281 ms
|
|
267
268
|
expr-eval: ~480 ms
|
|
268
269
|
jexl: ~1200 ms
|
|
269
270
|
new Function: ~1400 ms
|
|
@@ -278,6 +279,6 @@ new Function: ~1400 ms
|
|
|
278
279
|
* [expression-eval](https://github.com/donmccurdy/expression-eval)
|
|
279
280
|
* [jsep](https://github.com/EricSmekens/jsep)
|
|
280
281
|
* [string-math](https://github.com/devrafalko/string-math)
|
|
281
|
-
|
|
282
|
+
* [nerdamer](https://github.com/jiggzson/nerdamer)
|
|
282
283
|
|
|
283
284
|
<p align=center>🕉</p>
|
|
File without changes
|
package/justin.js
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
// justin lang https://github.com/endojs/Jessie/issues/66
|
|
2
|
-
import {evaluate, operator} from './
|
|
2
|
+
import {evaluate, operator} from './evaluate.js'
|
|
3
3
|
import {parse, binary, unary, postfix, token, literal,
|
|
4
|
-
code, char, skip, space, expr} from './
|
|
4
|
+
code, char, skip, space, expr} from './parse.js'
|
|
5
5
|
|
|
6
6
|
// undefined
|
|
7
7
|
literal['undefined'] = undefined
|
|
8
8
|
|
|
9
|
-
// '
|
|
10
|
-
token
|
|
9
|
+
// "' with /
|
|
10
|
+
token[2] = (q, qc, c, str) => {
|
|
11
|
+
if (q !== 34 && q !== 39) return
|
|
12
|
+
qc = char(), skip(), str = ''
|
|
13
|
+
while (c=code(), c-q) {
|
|
14
|
+
if (c === 92) skip(), str += escape[char()] || char(); else str+=char()
|
|
15
|
+
skip()
|
|
16
|
+
}
|
|
17
|
+
return skip(), qc + str + qc
|
|
18
|
+
}
|
|
19
|
+
const escape = {n:'\n', r:'\r', t:'\t', b:'\b', f:'\f', v:'\v'}
|
|
20
|
+
|
|
21
|
+
// unary word
|
|
22
|
+
postfix.push((node, prec) => typeof node === 'string' && (prec=unary[node]) ? [node, expr(prec)] : node)
|
|
23
|
+
|
|
24
|
+
// detect custom operators
|
|
25
|
+
token[3] = name => (name = skip(c =>
|
|
26
|
+
(
|
|
27
|
+
(c >= 48 && c <= 57) || // 0..9
|
|
28
|
+
(c >= 65 && c <= 90) || // A...Z
|
|
29
|
+
(c >= 97 && c <= 122) || // a...z
|
|
30
|
+
c == 36 || c == 95 || // $, _,
|
|
31
|
+
c >= 192 // any non-ASCII
|
|
32
|
+
) && !binary[String.fromCharCode(c)]
|
|
33
|
+
)),
|
|
34
|
+
|
|
11
35
|
|
|
12
36
|
// **
|
|
13
37
|
binary['**'] = 16
|
|
@@ -28,7 +52,7 @@ operator['?:']=(a,b,c)=>a?b:c
|
|
|
28
52
|
postfix.push(node => {
|
|
29
53
|
let a, b
|
|
30
54
|
if (code() !== 63) return node
|
|
31
|
-
skip(), space(), a = expr(58)
|
|
55
|
+
skip(), space(), a = expr(-1,58)
|
|
32
56
|
if (code() !== 58) return node
|
|
33
57
|
skip(), space(), b = expr()
|
|
34
58
|
return ['?:',node, a, b]
|
|
@@ -47,7 +71,7 @@ operator['['] = (...args) => Array(...args)
|
|
|
47
71
|
token.push((node, arg) =>
|
|
48
72
|
code() === 91 ?
|
|
49
73
|
(
|
|
50
|
-
skip(), arg=expr(93),
|
|
74
|
+
skip(), arg=expr(-1,93),
|
|
51
75
|
node = arg==null ? ['['] : arg[0] === ',' ? (arg[0]='[',arg) : ['[',arg],
|
|
52
76
|
skip(), node
|
|
53
77
|
) : null
|
|
@@ -55,7 +79,7 @@ token.push((node, arg) =>
|
|
|
55
79
|
|
|
56
80
|
// {}
|
|
57
81
|
binary[':'] = 2
|
|
58
|
-
token.unshift((node) => code() === 123 ? (skip(), node = map(['{',expr(125)]), skip(), node) : null)
|
|
82
|
+
token.unshift((node) => code() === 123 ? (skip(), node = map(['{',expr(-1,125)]), skip(), node) : null)
|
|
59
83
|
operator['{'] = (...args)=>Object.fromEntries(args)
|
|
60
84
|
operator[':'] = (a,b)=>[a,b]
|
|
61
85
|
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,
|
|
1
|
+
var r,e,n,t,l=r=>Array.isArray(r)&&("string"==typeof r[0]||l(r[0])),o=(r,e={},n,t)=>l(r)?("string"==typeof(n=r[0])&&(t=u[n]),"function"!=typeof(n=t||o(n,e))?n:n.call(...r.map((r=>o(r,e))))):r&&"string"==typeof r?'"'===r[0]?r.slice(1,-1):"@"===r[0]?r.slice(1):r in e?e[r]:r:r,u=o.operator={"!":r=>!r,"++":r=>++r,"--":r=>--r,".":(...r)=>r.reduce(((r,e)=>r&&r[e])),"%":(...r)=>r.reduce(((r,e)=>r%e)),"/":(...r)=>r.reduce(((r,e)=>r/e)),"*":(...r)=>r.reduce(((r,e)=>r*e)),"+":(...r)=>r.reduce(((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)=>r.reduce(((r,e)=>e))},i=o,a=(t,l)=>(e=t,r=n=0,l=c(),r<e.length?p():l),s=()=>e.charCodeAt(r),f=(n=1)=>e.substr(r,n),p=(e="Bad syntax "+f())=>{throw Error(e+" at "+r)},d=(n=1,t=r)=>{if("number"==typeof n)r+=n;else for(;n(s());)++r>e.length&&p("End by "+n);return r>t?e.slice(t,r):null},h=()=>{for(;s()<=32;)r++},y=(e,t,l,o=3)=>{if(r&&n&&n[3]===r)return n;for(;o;)if(null!=(l=e[t=f(o--)]))return n=[t,l,t.length,r]},c=(e=-1,n)=>{h();let l,o,u,i,a=s(),d=0,g=r;if(n){if(a===n)return;i=t,t=n}for(;g===r&&d<b.length;)o=b[d++](a);if(g===r)(l=y(m))&&(r+=l[2],o=[l[0],c(l[1])]);else for(h(),a=s(),d=0;d<A.length;)(u=A[d](o,a))!==o?(o=u,h(),a=s()):d++;for(;a=s()&&a!==t&&(l=y(w))&&l[1]>e;){o=[l[0],o];do{r+=l[2],o.push(c(l[1]))}while(f(l[2])===l[0]);h()}return n&&(t=s()!==n?p("Unclosed paren"):i),o},g=r=>d((r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192)),b=a.token=[r=>{if(r=d((r=>r>=48&&r<=57||46===r)))return(69===s()||101===s())&&(r+=d(2)+d((r=>r>=48&&r<=57))),isNaN(r=parseFloat(r))?p("Bad number"):r},(e,n)=>40===e?(r++,n=c(-1,41),r++,n):null,(e,n)=>34===e?(n=f(),r++,n+d((r=>r-e))+(r++,n)):null,g],v=a.literal={true:!0,false:!1,null:null},A=a.postfix=[(n,t,l)=>(46===t?(r++,h(),n=[".",n,'"'+g()+'"']):91===t?(r++,n=[".",n,c(-1,93)],r++):40===t?(r++,l=c(-1,41),n=Array.isArray(l)&&","===l[0]?(l[0]=n,l):null==l?[n]:[n,l],r++):43!==t&&45!==t||e.charCodeAt(r+1)!==t?"string"==typeof n&&v.hasOwnProperty(n)&&(n=v[n]):n=[d(2),n],n)],m=a.unary={"-":17,"!":17,"+":17,"++":17,"--":17},w=a.binary={",":1,"||":6,"&&":7,"|":8,"^":9,"&":10,"==":11,"!=":11,"<":12,">":12,"<=":12,">=":12,"<<":13,">>":13,">>>":13,"+":14,"-":14,"*":15,"/":15,"%":15},x=a,B=r=>(r="string"==typeof r?x(r):r,e=>i(r,e));v.undefined=void 0,b[2]=(r,e,n,t)=>{if(34===r||39===r){for(e=f(),d(),t="";(n=s())-r;)92===n?(d(),t+=C[f()]||f()):t+=f(),d();return d(),e+t+e}};var C={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"};A.push(((r,e)=>"string"==typeof r&&(e=m[r])?[r,c(e)]:r)),b[3]=r=>d((r=>(r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192)&&!w[String.fromCharCode(r)])),w["**"]=16,u["**"]=(...r)=>r.reduceRight(((r,e)=>Math.pow(e,r))),m["~"]=17,u["~"]=r=>~r,w[";"]=1,u["?:"]=(r,e,n)=>r?e:n,A.push((r=>{let e,n;return 63!==s()||(d(),h(),e=c(-1,58),58!==s())?r:(d(),h(),n=c(),["?:",r,e,n])})),o.operator.in=(r,e)=>r in e,a.postfix.unshift((r=>"in"===f(2)?(d(2),["in",'"'+r+'"',c()]):r)),u["["]=(...r)=>Array(...r),b.push(((r,e)=>91===s()?(d(),r=null==(e=c(-1,93))?["["]:","===e[0]?(e[0]="[",e):["[",e],d(),r):null)),w[":"]=2,b.unshift((r=>123===s()?(d(),r=E(["{",c(-1,125)]),d(),r):null)),u["{"]=(...r)=>Object.fromEntries(r),u[":"]=(r,e)=>[r,e];var E=(r,e)=>(null==r[1]?e=[]:":"==r[1][0]?e=[r[1]]:","==r[1][0]&&(e=r[1].slice(1)),["{",...e]);export{B as default,o as evaluate,a as parse};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subscript",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "Microlanguage with common syntax for JS/C++/Python/Rust",
|
|
5
5
|
"main": "subscript.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
8
|
-
"
|
|
8
|
+
"parse.js",
|
|
9
|
+
"evaluate.js",
|
|
9
10
|
"subscript.js",
|
|
10
11
|
"subscript.min.js",
|
|
11
12
|
"justin.js",
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
const PERIOD = 46, OPAREN = 40, CPAREN = 41, OBRACK = 91, CBRACK = 93, PLUS = 43, MINUS = 45
|
|
2
2
|
|
|
3
|
-
export let index, current, lastOp
|
|
3
|
+
export let index, current, lastOp, end
|
|
4
4
|
|
|
5
|
-
export const parse = str => (current=str, index=lastOp=0, expr()),
|
|
5
|
+
export const parse = (str, tree) => (current=str, index=lastOp=0, tree=expr(), index < current.length ? err() : tree),
|
|
6
6
|
|
|
7
|
+
// ------------ util
|
|
8
|
+
code = () => current.charCodeAt(index), // current char code
|
|
9
|
+
char = (n=1) => current.substr(index, n), // skip n chars
|
|
10
|
+
err = (msg='Bad syntax '+char()) => { throw Error(msg + ' at ' + index) },
|
|
11
|
+
skip = (is=1, from=index) => { // consume N or until condition matches
|
|
12
|
+
if (typeof is === 'number') index += is
|
|
13
|
+
else while (is(code())) ++index > current.length && err('End by ' + is) // 1 + true === 2;
|
|
14
|
+
return index > from ? current.slice(from, index) : null
|
|
15
|
+
},
|
|
7
16
|
space = () => { while (code() <= 32) index++ },
|
|
8
17
|
|
|
18
|
+
// ------------- expr
|
|
9
19
|
// consume operator
|
|
10
20
|
operator = (ops, op, prec, l=3) => {
|
|
11
21
|
// memoize by index - saves 20% to perf
|
|
@@ -15,95 +25,91 @@ operator = (ops, op, prec, l=3) => {
|
|
|
15
25
|
while (l) if ((prec=ops[op=char(l--)])!=null) return lastOp = [op, prec, op.length, index] //opinfo
|
|
16
26
|
},
|
|
17
27
|
|
|
18
|
-
expr = (
|
|
28
|
+
expr = (prec=-1, curEnd) => {
|
|
19
29
|
space()
|
|
20
30
|
|
|
21
|
-
let cc = code(), op, node, i=0, mapped, from=index
|
|
31
|
+
let cc = code(), op, node, i=0, mapped, from=index, prevEnd
|
|
22
32
|
|
|
23
|
-
if (cc ===
|
|
33
|
+
if (curEnd) if (cc === curEnd) return; else prevEnd = end, end = curEnd // global end marker saves operator lookups
|
|
24
34
|
|
|
25
35
|
// parse node by token parsers (direct loop is faster than token.find)
|
|
26
36
|
while (from===index && i < token.length) node = token[i++](cc)
|
|
27
37
|
|
|
28
38
|
// unary prefix
|
|
29
|
-
if (from===index) (op = operator(unary)) && (index += op[2], node = [op[0], expr(
|
|
39
|
+
if (from===index) (op = operator(unary)) && (index += op[2], node = [op[0], expr(op[1])])
|
|
30
40
|
|
|
31
|
-
// postfix handlers
|
|
41
|
+
// postfix handlers
|
|
32
42
|
else {
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
for (space(), cc=code(), i=0; i < postfix.length;)
|
|
44
|
+
if ((mapped = postfix[i](node, cc)) !== node) node = mapped, space(), cc=code(); else i++
|
|
35
45
|
}
|
|
36
46
|
// ALT: seems to be slower
|
|
37
47
|
// else do {space(), cc=code()} while (postfix.find((parse, mapped) => (mapped = parse(node, cc)) !== node && (node = mapped)))
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// consume expression for current precedence or higher
|
|
42
|
-
while ((cc = code()) && cc !== end && (op = operator(binary)) && op[1] > prec) {
|
|
49
|
+
// consume binary expression for current precedence or higher
|
|
50
|
+
while (cc = code() && (cc !== end) && (op = operator(binary)) && op[1] > prec) {
|
|
43
51
|
node = [op[0], node]
|
|
44
52
|
// consume same-op group, do..while both saves op lookups and space
|
|
45
|
-
do { index += op[2], node.push(expr(
|
|
53
|
+
do { index += op[2], node.push(expr(op[1])) } while (char(op[2]) === op[0])
|
|
46
54
|
space()
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
if (curEnd) end = code() !== curEnd ? err('Unclosed paren') : prevEnd
|
|
58
|
+
// if (node == null) err('Missing argument')
|
|
59
|
+
|
|
49
60
|
return node;
|
|
50
61
|
},
|
|
51
62
|
|
|
52
63
|
// ------------------- tokens
|
|
53
64
|
// 1.2e+3, .5 - fast & small version, but consumes corrupted nums as well
|
|
54
|
-
float = (number
|
|
65
|
+
float = (number) => {
|
|
55
66
|
if (number = skip(c => (c >= 48 && c <= 57) || c === PERIOD)) {
|
|
56
67
|
if (code() === 69 || code() === 101) number += skip(2) + skip(c => c >= 48 && c <= 57)
|
|
57
|
-
return parseFloat(number)
|
|
68
|
+
return isNaN(number = parseFloat(number)) ? err('Bad number') : number
|
|
58
69
|
}
|
|
59
70
|
},
|
|
60
71
|
|
|
61
72
|
// "a"
|
|
62
|
-
string = (q, qc) => q === 34 ? (qc = char(), index++, qc) + skip(c => c
|
|
73
|
+
string = (q, qc) => q === 34 ? (qc = char(), index++, qc) + skip(c => c-q) + (index++, qc) : null,
|
|
63
74
|
|
|
64
75
|
// (...exp)
|
|
65
|
-
group = (c, node) => c === OPAREN ? (index++, node = expr(CPAREN), index++, node) : null,
|
|
76
|
+
group = (c, node) => c === OPAREN ? (index++, node = expr(-1,CPAREN), index++, node) : null,
|
|
66
77
|
|
|
67
78
|
// var or literal
|
|
68
79
|
id = name => (name = skip(c =>
|
|
69
|
-
(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// ------------ util
|
|
78
|
-
code = () => current.charCodeAt(index), // current char code
|
|
79
|
-
char = (n=1) => current.substr(index, n), // skip n chars
|
|
80
|
-
err = (msg) => { throw Error(msg + ' at ' + index) },
|
|
81
|
-
skip = (is=1, from=index) => { // consume N or until condition matches
|
|
82
|
-
if (typeof is === 'number') index += is
|
|
83
|
-
else while (is(code())) ++index > current.length && err('Unexpected end ' + is) // 1 + true === 2;
|
|
84
|
-
return index > from ? current.slice(from, index) : null
|
|
85
|
-
},
|
|
86
|
-
|
|
80
|
+
(
|
|
81
|
+
(c >= 48 && c <= 57) || // 0..9
|
|
82
|
+
(c >= 65 && c <= 90) || // A...Z
|
|
83
|
+
(c >= 97 && c <= 122) || // a...z
|
|
84
|
+
c == 36 || c == 95 || // $, _,
|
|
85
|
+
c >= 192 // any non-ASCII
|
|
86
|
+
)
|
|
87
|
+
)),
|
|
87
88
|
|
|
88
89
|
// ----------- config
|
|
89
|
-
token = parse.token = [
|
|
90
|
+
token = parse.token = [ float, group, string, id ],
|
|
90
91
|
|
|
91
92
|
literal = parse.literal = {true:true, false:false, null:null},
|
|
92
93
|
|
|
93
94
|
postfix = parse.postfix = [
|
|
94
|
-
//
|
|
95
|
+
// postfix parsers merged into 1 for performance & compactness
|
|
95
96
|
(node, cc, arg) => {
|
|
97
|
+
// a.b[c](d)
|
|
96
98
|
if (cc === PERIOD) index++, space(), node = ['.', node, '"'+id()+'"']
|
|
97
|
-
else if (cc === OBRACK) index++, node = ['.', node, expr(CBRACK)], index++
|
|
99
|
+
else if (cc === OBRACK) index++, node = ['.', node, expr(-1,CBRACK)], index++
|
|
98
100
|
else if (cc === OPAREN)
|
|
99
|
-
index++, arg=expr(CPAREN),
|
|
101
|
+
index++, arg=expr(-1,CPAREN),
|
|
100
102
|
node = Array.isArray(arg) && arg[0]===',' ? (arg[0]=node, arg) : arg == null ? [node] : [node, arg],
|
|
101
103
|
index++
|
|
102
|
-
return node
|
|
103
|
-
},
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
// a++, a--
|
|
106
|
+
else if ((cc===0x2b || cc===0x2d) && current.charCodeAt(index+1)===cc) node = [skip(2), node]
|
|
107
|
+
|
|
108
|
+
// literal
|
|
109
|
+
else if (typeof node === 'string' && literal.hasOwnProperty(node)) node = literal[node]
|
|
110
|
+
|
|
111
|
+
return node
|
|
112
|
+
}
|
|
107
113
|
],
|
|
108
114
|
|
|
109
115
|
unary = parse.unary = {
|
|
@@ -124,4 +130,5 @@ binary = parse.binary = {
|
|
|
124
130
|
'*': 15, '/': 15, '%': 15
|
|
125
131
|
}
|
|
126
132
|
|
|
133
|
+
|
|
127
134
|
export default parse
|
package/subscript.js
CHANGED
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,r,t,l=l=>(r=
|
|
1
|
+
var e,r,t,n,l=(n,l)=>(r=n,e=t=0,l=y(),e<r.length?u():l),a=()=>r.charCodeAt(e),o=(t=1)=>r.substr(e,t),u=(r="Bad syntax "+o())=>{throw Error(r+" at "+e)},s=(t=1,n=e)=>{if("number"==typeof t)e+=t;else for(;t(a());)++e>r.length&&u("End by "+t);return e>n?r.slice(n,e):null},f=()=>{for(;a()<=32;)e++},i=(r,n,l,a=3)=>{if(e&&t&&t[3]===e)return t;for(;a;)if(null!=(l=r[n=o(a--)]))return t=[n,l,n.length,e]},y=(r=-1,t)=>{f();let l,s,p,d,b=a(),m=0,B=e;if(t){if(b===t)return;d=n,n=t}for(;B===e&&m<c.length;)s=c[m++](b);if(B===e)(l=i(g))&&(e+=l[2],s=[l[0],y(l[1])]);else for(f(),b=a(),m=0;m<h.length;)(p=h[m](s,b))!==s?(s=p,f(),b=a()):m++;for(;b=a()&&b!==n&&(l=i(A))&&l[1]>r;){s=[l[0],s];do{e+=l[2],s.push(y(l[1]))}while(o(l[2])===l[0]);f()}return t&&(n=a()!==t?u("Unclosed paren"):d),s},p=e=>s((e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192)),c=l.token=[e=>{if(e=s((e=>e>=48&&e<=57||46===e)))return(69===a()||101===a())&&(e+=s(2)+s((e=>e>=48&&e<=57))),isNaN(e=parseFloat(e))?u("Bad number"):e},(r,t)=>40===r?(e++,t=y(-1,41),e++,t):null,(r,t)=>34===r?(t=o(),e++,t+s((e=>e-r))+(e++,t)):null,p],d=l.literal={true:!0,false:!1,null:null},h=l.postfix=[(t,n,l)=>(46===n?(e++,f(),t=[".",t,'"'+p()+'"']):91===n?(e++,t=[".",t,y(-1,93)],e++):40===n?(e++,l=y(-1,41),t=Array.isArray(l)&&","===l[0]?(l[0]=t,l):null==l?[t]:[t,l],e++):43!==n&&45!==n||r.charCodeAt(e+1)!==n?"string"==typeof t&&d.hasOwnProperty(t)&&(t=d[t]):t=[s(2),t],t)],g=l.unary={"-":17,"!":17,"+":17,"++":17,"--":17},A=l.binary={",":1,"||":6,"&&":7,"|":8,"^":9,"&":10,"==":11,"!=":11,"<":12,">":12,"<=":12,">=":12,"<<":13,">>":13,">>>":13,"+":14,"-":14,"*":15,"/":15,"%":15},b=l,m=e=>Array.isArray(e)&&("string"==typeof e[0]||m(e[0])),B=(e,r={},t,n)=>m(e)?("string"==typeof(t=e[0])&&(n=v[t]),"function"!=typeof(t=n||B(t,r))?t:t.call(...e.map((e=>B(e,r))))):e&&"string"==typeof e?'"'===e[0]?e.slice(1,-1):"@"===e[0]?e.slice(1):e in r?r[e]:e:e,v=B.operator={"!":e=>!e,"++":e=>++e,"--":e=>--e,".":(...e)=>e.reduce(((e,r)=>e&&e[r])),"%":(...e)=>e.reduce(((e,r)=>e%r)),"/":(...e)=>e.reduce(((e,r)=>e/r)),"*":(...e)=>e.reduce(((e,r)=>e*r)),"+":(...e)=>e.reduce(((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)=>e.reduce(((e,r)=>r))},w=B,x=e=>(e="string"==typeof e?b(e):e,r=>w(e,r));export{x as default,w as evaluate,b as parse};
|