subscript 5.3.0 → 5.5.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 +3 -3
- package/evaluate.js +11 -15
- package/justin.js +16 -18
- package/justin.min.js +1 -1
- package/package.json +4 -4
- package/parse.js +9 -12
- package/subscript.js +6 -6
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -25,12 +25,12 @@ _Subscript_ is designed to be useful for:
|
|
|
25
25
|
* templates (perfect match with [template parts](https://github.com/github/template-parts))
|
|
26
26
|
* expressions evaluators, calculators
|
|
27
27
|
* configurable subsets of languages (eg. [justin](#justin)) <!-- see sonr, mineural -->
|
|
28
|
-
*
|
|
28
|
+
* pluggable/mock language features (eg. pipe operator)
|
|
29
29
|
* sandboxes, playgrounds, safe eval
|
|
30
30
|
* custom DSL
|
|
31
31
|
|
|
32
32
|
[_Jsep_](https://github.com/EricSmekens/jsep) is generally fine for the listed tasks, unless you need dependencies as small as possible.
|
|
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
|
|
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_ + [4.5kb](https://npmfs.com/package/expression-eval/5.0.0/dist/expression-eval.module.js) _expression-eval_, with _jsep_ test coverage and better performance.
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
## Evaluation
|
|
@@ -77,7 +77,7 @@ import { parse, evaluate } from 'subscript.js'
|
|
|
77
77
|
parse.operator('=>', 10) // precedence=10, type=default (0 - binary, 1 - postfix, -1 - prefix)
|
|
78
78
|
|
|
79
79
|
evaluate.operator('=>', ( args, body ) => evaluate(body, args))
|
|
80
|
-
evaluate.operator('|', ( a,
|
|
80
|
+
evaluate.operator('|', ( a, b ) => a.pipe(b))
|
|
81
81
|
|
|
82
82
|
let tree = parse(`
|
|
83
83
|
interval(350)
|
package/evaluate.js
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
export const isCmd = a => Array.isArray(a) && (typeof a[0] === 'string' || isCmd(a[0])),
|
|
2
|
-
|
|
3
1
|
// calltree → result
|
|
4
|
-
evaluate = (
|
|
5
|
-
if (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
export const evaluate = (node, ctx={}) => {
|
|
3
|
+
if (typeof node === 'string')
|
|
4
|
+
return node[0]==='@' ? node.slice(1) : ctx[node]
|
|
5
|
+
|
|
6
|
+
if (Array.isArray(node)) {
|
|
7
|
+
// [[a,b], c] or ['+', a, b] or ['myfn', a, b], or
|
|
8
|
+
let c = node[0], fn = Array.isArray(c) ? evaluate(c, ctx) : (lookup[c] || ctx[c] || c), args=[], i = 1
|
|
9
|
+
for (;i<node.length;i++) args.push(evaluate(node[i], ctx))
|
|
10
|
+
return args.length > fn.length && fn.length ? args.reduce(fn) : fn.apply(c,args)
|
|
11
11
|
}
|
|
12
|
-
if (s && typeof s === 'string')
|
|
13
|
-
return s[0] === '"' ? s.slice(1,-1)
|
|
14
|
-
: s[0]==='@' ? s.slice(1)
|
|
15
|
-
: s in ctx ? ctx[s] : s
|
|
16
12
|
|
|
17
|
-
return
|
|
13
|
+
return node
|
|
18
14
|
},
|
|
19
15
|
lookup = {},
|
|
20
16
|
|
|
21
17
|
// op evaluators
|
|
22
18
|
// multiple args allows shortcuts, lisp compatible, easy manual eval, functions anyways take multiple arguments
|
|
23
|
-
operator = evaluate.operator = (op, fn) => lookup[op] = fn
|
|
19
|
+
operator = evaluate.operator = (op, fn) => lookup[op] = fn
|
|
24
20
|
|
|
25
21
|
export default evaluate
|
package/justin.js
CHANGED
|
@@ -27,7 +27,7 @@ parse.token.push(
|
|
|
27
27
|
if (c === 92) skip(), str += escape[char()] || char(); else str+=char()
|
|
28
28
|
skip()
|
|
29
29
|
}
|
|
30
|
-
return skip(),
|
|
30
|
+
return skip(), '@' + str
|
|
31
31
|
},
|
|
32
32
|
|
|
33
33
|
// id
|
|
@@ -65,8 +65,7 @@ const addOps = (add, stride=2, list) => {
|
|
|
65
65
|
|
|
66
66
|
addOps(parse.operator, 3, [
|
|
67
67
|
// subscript ones
|
|
68
|
-
|
|
69
|
-
',', PREC_SEQ,,
|
|
68
|
+
',', PREC_SEQ,,
|
|
70
69
|
|
|
71
70
|
'|', PREC_OR,,
|
|
72
71
|
'||', PREC_SOME,,
|
|
@@ -93,13 +92,13 @@ addOps(parse.operator, 3, [
|
|
|
93
92
|
'+', PREC_SUM,,
|
|
94
93
|
'+', PREC_UNARY, -1,
|
|
95
94
|
'++', PREC_UNARY, -1,
|
|
96
|
-
'++',
|
|
95
|
+
'++', PREC_POSTFIX, +1,
|
|
97
96
|
'-', PREC_SUM,,
|
|
98
97
|
'-', PREC_UNARY, -1,
|
|
99
98
|
'--', PREC_UNARY, -1,
|
|
100
|
-
'--',
|
|
99
|
+
'--', PREC_POSTFIX, +1,
|
|
101
100
|
|
|
102
|
-
// !
|
|
101
|
+
// ! ~
|
|
103
102
|
'!', PREC_UNARY, -1,
|
|
104
103
|
|
|
105
104
|
// * / %
|
|
@@ -108,14 +107,14 @@ addOps(parse.operator, 3, [
|
|
|
108
107
|
'%', PREC_MULT,,
|
|
109
108
|
|
|
110
109
|
// a.b
|
|
111
|
-
'.', PREC_CALL, (node,b) => node && [skip(),node,
|
|
110
|
+
'.', PREC_CALL, (node,b) => node && [skip(), node, '@' + expr(PREC_CALL)],
|
|
112
111
|
|
|
113
112
|
// a[b]
|
|
114
113
|
'[', PREC_CALL, (node) => (skip(), node = ['.', node, val(expr(0,CBRACK))], node),
|
|
115
114
|
']',,,
|
|
116
115
|
|
|
117
116
|
// a(b)
|
|
118
|
-
'(', PREC_CALL, (node,b) => (
|
|
117
|
+
'(', PREC_CALL, (node,b) => (skip(), b=expr(0,CPAREN),
|
|
119
118
|
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, val(b)] : [node]
|
|
120
119
|
),
|
|
121
120
|
// (a+b)
|
|
@@ -132,13 +131,10 @@ addOps(parse.operator, 3, [
|
|
|
132
131
|
if (!node) err('Expected expression')
|
|
133
132
|
let a, b
|
|
134
133
|
skip(), parse.space(), a = expr()
|
|
135
|
-
|
|
136
|
-
skip(), parse.space(), b = expr()
|
|
137
|
-
return ['?:', node, a, b]
|
|
134
|
+
return ['?:', node, a[1], a[2]]
|
|
138
135
|
},
|
|
139
|
-
'
|
|
140
|
-
'
|
|
141
|
-
'in', PREC_COMP, (node) => code(2) <= 32 && [skip(2), '"'+node+'"', expr(PREC_COMP)],
|
|
136
|
+
':', PREC_COMP,,
|
|
137
|
+
'in', PREC_COMP, (node) => code(2)<=32 && [skip(2), '@'+node, expr(PREC_COMP)],
|
|
142
138
|
|
|
143
139
|
// as operator it's faster to lookup (no need to extra rule check), smaller and no conflict with word names
|
|
144
140
|
// [a,b,c]
|
|
@@ -149,8 +145,9 @@ addOps(parse.operator, 3, [
|
|
|
149
145
|
|
|
150
146
|
// {a:0, b:1}
|
|
151
147
|
'{', PREC_TOKEN, (node,arg) => !node && (skip(), arg=expr(0,125),
|
|
152
|
-
!arg ? ['{'] : arg[0] == ':' ? ['{',arg] : arg[0] == ',' ? (arg[0]='{',arg) : ['{',arg])
|
|
153
|
-
|
|
148
|
+
!arg ? ['{'] : arg[0] == ':' ? ['{',strkey(arg)] : arg[0] == ',' ? (arg[0]='{',arg.map(strkey)) : ['{',arg]),
|
|
149
|
+
'}',,,
|
|
150
|
+
|
|
154
151
|
|
|
155
152
|
// literals
|
|
156
153
|
'null', PREC_TOKEN, node=>!node&&(skip(4),v(null)),
|
|
@@ -158,6 +155,7 @@ addOps(parse.operator, 3, [
|
|
|
158
155
|
'true', PREC_TOKEN, node=>!node&&(skip(4),v(true)),
|
|
159
156
|
'undefined', PREC_TOKEN, node=>!node&&(skip(9),v(undefined)),
|
|
160
157
|
])
|
|
158
|
+
const strkey = a => Array.isArray(a) ? (a[1]=(a[1][0]==='@'?'':'@')+a[1],a) : a
|
|
161
159
|
const v = v => ({valueOf:()=>v})
|
|
162
160
|
|
|
163
161
|
addOps(evaluate.operator, 2, [
|
|
@@ -172,8 +170,8 @@ addOps(evaluate.operator, 2, [
|
|
|
172
170
|
'/', (a,b)=>a/b,
|
|
173
171
|
'*', (a,b)=>a*b,
|
|
174
172
|
|
|
175
|
-
'+', (a,b)=>a+b,
|
|
176
|
-
'-', (
|
|
173
|
+
'+', (a,b=0)=>a+b,
|
|
174
|
+
'-', (a,b)=>b==null ? -a : a-b,
|
|
177
175
|
|
|
178
176
|
'>>>', (a,b)=>a>>>b,
|
|
179
177
|
'>>', (a,b)=>a>>b,
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const r=(t,n={})=>{if("string"==typeof t)return"@"===t[0]?t.slice(1):n[t];if(Array.isArray(t)){let o=t[0],a=Array.isArray(o)?r(o,n):e[o]||n[o]||o,s=[],l=1;for(;l<t.length;l++)s.push(r(t[l],n));return s.length>a.length&&a.length?s.reduce(a):a.apply(o,s)}return t},e={};let t,n;r.operator=(r,t)=>e[r]=t;const o=(r,e)=>(n=r,t=0,e=i(),t<n.length?a():h(e)),a=(r="Bad syntax")=>{throw Error(r+" `"+n[t]+"` at "+t)},s=(r=1,e=t)=>{if("number"==typeof r)t+=r;else for(;r(l());)t++;return n.slice(e,t)},l=(r=0)=>n.charCodeAt(t+r),f=(r=1)=>n.substr(t,r),i=(r=0,e,n,s,l=0,f,i)=>{for(;(n=o.space())&&(f=(i=c[n])&&i(s,r)||!s&&p(n));)s=f;return e&&(n!=e?a("Unclosed paren"):t++),s};o.space=r=>{for(;(r=l())<=32;)t++;return r};const u=o.token=[],p=(r,e=0,t)=>{for(;e<u.length;)if(t=u[e++](r))return t},c=[];o.operator=(r,e=0,n=0,a,l=r.charCodeAt(0),u=r.length,p=c[l])=>(a=n?n>0?r=>r&&[s(u),h(r)]:n<0?r=>!r&&[s(u),h(i(e-1))]:n:n=>{n=[r,h(n)];do{t+=u,n.push(h(i(e)))}while(o.space()==l&&(u<2||f(u)==r));return n},c[l]=(t,n)=>n<e&&(u<2||f(u)==r)&&a(t)||p&&p(t,n));const h=r=>Array.isArray(r)?r:(r||a()).valueOf();o.token.push((r=>(r=s((r=>r>47&&r<58||46==r)))&&((69==l()||101==l())&&(r+=s(2)+s((r=>r>=48&&r<=57))),isNaN(r=new Number(r))?a("Bad number"):r)),((r,e,t,n)=>{if(34===r||39===r){for(f(),s(),n="";(t=l())-r;)92===t?(s(),n+=y[f()]||f()):n+=f(),s();return s(),"@"+n}}),(r=>s((r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192&&215!=r&&247!=r))));const y={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"};o.space=r=>{for(;(r=l())<=32||47===r;)if(r<=32)s();else if(47===r)if(42===l(1))s(2),s((r=>42!==r&&47!==l(1))),s(2);else{if(47!==l(1))break;s(2),s((r=>r>=32))}return r};const d=(r,e=2,t)=>{for(let n=0;n<t.length;n+=e)r(t[n],t[n+1],t[n+2])};d(o.operator,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&&[s(),r,"@"+i(18)],"[",18,r=>(s(),[".",r,h(i(0,93))]),"]",,,"(",18,(r,e)=>(s(),e=i(0,41),Array.isArray(e)&&","===e[0]?(e[0]=r,e):e?[r,h(e)]:[r]),"(",19,(r,e)=>!r&&(s(),i(0,41)||a()),")",,,";",1,,"===",9,,"!==",9,,"**",14,,"~",15,-1,"?",3,r=>{let e;return r||a("Expected expression"),s(),o.space(),e=i(),["?:",r,e[1],e[2]]},":",10,,"in",10,r=>l(2)<=32&&[s(2),"@"+r,i(10)],"[",20,(r,e)=>!r&&(s(),(e=i(0,93))?","==e[0]?(e[0]="[",e):["[",e]:["["]),"{",20,(r,e)=>!r&&(s(),(e=i(0,125))?":"==e[0]?["{",A(e)]:","==e[0]?(e[0]="{",e.map(A)):["{",e]:["{"]),"}",,,"null",20,r=>!r&&(s(4),g(null)),"false",20,r=>!r&&(s(5),g(!1)),"true",20,r=>!r&&(s(4),g(!0)),"undefined",20,r=>!r&&(s(9),g(void 0))]);const A=r=>Array.isArray(r)?(r[1]=("@"===r[1][0]?"":"@")+r[1],r):r,g=r=>({valueOf:()=>r});d(r.operator,2,["!",r=>!r,"++",r=>++r,"--",r=>--r,".",(r,e)=>r?r[e]:r,"%",(r,e)=>r%e,"/",(r,e)=>r/e,"*",(r,e)=>r*e,"+",(r,e=0)=>r+e,"-",(r,e)=>null==e?-r: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,"**",(...r)=>r.reduceRight(((r,e)=>Math.pow(e,r))),"~",r=>~r,"?:",(r,e,t)=>r?e:t,"in",(r,e)=>r in e,"[",(...r)=>Array(...r),"{",(...r)=>Object.fromEntries(r),":",(r,e)=>[r,e]]);var b=e=>(e="string"==typeof e?o(e):e,t=>r(e,t));export{b as default,r as evaluate,o as parse};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subscript",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "Microlanguage with common syntax for JS/C++/Python/Rust",
|
|
5
5
|
"main": "subscript.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"test": "test"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "
|
|
21
|
+
"build": "rollup subscript.js --file subscript.min.js --format esm --name \"Subscript\"",
|
|
22
22
|
"minify": "terser subscript.min.js -o subscript.min.js --module -c passes=3 -m",
|
|
23
|
-
"build-justin": "
|
|
23
|
+
"build-justin": "rollup justin.js --file justin.min.js --format esm --name \"Justin\"",
|
|
24
24
|
"minify-justin": "terser justin.min.js -o justin.min.js --module -c passes=3 -m",
|
|
25
25
|
"test": "node test"
|
|
26
26
|
},
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://github.com/spectjs/subscript#readme",
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"
|
|
57
|
+
"rollup": "^2.60.2",
|
|
58
58
|
"terser": "^5.10.0"
|
|
59
59
|
}
|
|
60
60
|
}
|
package/parse.js
CHANGED
|
@@ -18,14 +18,14 @@ code = (i=0) => cur.charCodeAt(idx+i),
|
|
|
18
18
|
char = (n=1) => cur.substr(idx, n),
|
|
19
19
|
|
|
20
20
|
// a + b - c
|
|
21
|
-
expr = (prec=0, end, cc, node, i=0,
|
|
21
|
+
expr = (prec=0, end, cc, node, i=0, newNode, op) => {
|
|
22
22
|
// chunk/token parser
|
|
23
23
|
while (
|
|
24
|
-
(cc=parse.space()) && (newNode = lookup[cc]
|
|
24
|
+
(cc=parse.space()) && (newNode = (op=lookup[cc]) && op(node, prec) || (!node && token(cc)) )
|
|
25
25
|
) node = newNode;
|
|
26
26
|
|
|
27
27
|
// skip end character, if expected
|
|
28
|
-
if (end) cc != end ? err('Unclosed paren') :
|
|
28
|
+
if (end) cc != end ? err('Unclosed paren') : idx++
|
|
29
29
|
|
|
30
30
|
return node
|
|
31
31
|
},
|
|
@@ -45,14 +45,12 @@ lookup = [],
|
|
|
45
45
|
// @param prec is operator precedenc to check
|
|
46
46
|
// @param map is either number +1 - postfix unary, -1 prefix unary, 0 binary, else - custom mapper function
|
|
47
47
|
operator = parse.operator = (
|
|
48
|
-
op, prec=0, type=0, map, c=op.charCodeAt(0), l=op.length,
|
|
49
|
-
prev=lookup[c],
|
|
50
|
-
spaced=type<=0&&op.toUpperCase()!==op // non-postfix word operator must have space after
|
|
48
|
+
op, prec=0, type=0, map, c=op.charCodeAt(0), l=op.length, prev=lookup[c]
|
|
51
49
|
) => (
|
|
52
|
-
map = !type ? node => { // binary
|
|
53
|
-
node = [op, node
|
|
54
|
-
do { idx+=l, node.push(val(expr(prec))) }
|
|
55
|
-
while (parse.space()==c && (l<2||char(l)==op)
|
|
50
|
+
map = !type ? node => { // binary
|
|
51
|
+
node = [op, val(node)]
|
|
52
|
+
do { idx+=l, node.push(val(expr(prec))) } // consume same-op group
|
|
53
|
+
while (parse.space()==c && (l<2||char(l)==op))
|
|
56
54
|
return node
|
|
57
55
|
} :
|
|
58
56
|
type > 0 ? node => node && [skip(l), val(node)] : // postfix unary
|
|
@@ -60,8 +58,7 @@ operator = parse.operator = (
|
|
|
60
58
|
type,
|
|
61
59
|
|
|
62
60
|
lookup[c] = (node, curPrec) =>
|
|
63
|
-
curPrec < prec && (l<2||char(l)==op) && (
|
|
64
|
-
map(node) || (prev && prev(node, curPrec))
|
|
61
|
+
curPrec < prec && (l<2||char(l)==op) && map(node) || (prev && prev(node, curPrec))
|
|
65
62
|
),
|
|
66
63
|
|
|
67
64
|
// in order to support literal tokens, we call valueOf any time we create or modify calltree node
|
package/subscript.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import parse, {skip, expr, code, tokens, val, operator as parseOp} from './parse.js'
|
|
1
|
+
import parse, {skip, expr, code, tokens, val, operator as parseOp, err} from './parse.js'
|
|
2
2
|
import evaluate, {operator as evalOp} from './evaluate.js'
|
|
3
3
|
|
|
4
4
|
const PERIOD=46, OPAREN=40, CPAREN=41, CBRACK=93, SPACE=32,
|
|
@@ -15,7 +15,7 @@ tokens.push(
|
|
|
15
15
|
)
|
|
16
16
|
),
|
|
17
17
|
// "a"
|
|
18
|
-
(q, qc) => q == 34 && (skip()
|
|
18
|
+
(q, qc, v) => q == 34 && (skip(), v=skip(c => c-q), skip(), '@'+v),
|
|
19
19
|
// id
|
|
20
20
|
c => skip(c =>
|
|
21
21
|
(c >= 48 && c <= 57) || // 0..9
|
|
@@ -73,14 +73,14 @@ addOps(parseOp, 3, [
|
|
|
73
73
|
'%', PREC_MULT,,
|
|
74
74
|
|
|
75
75
|
// a.b
|
|
76
|
-
'.', PREC_CALL, (node,b) => node && [skip(),node,
|
|
76
|
+
'.', PREC_CALL, (node,b) => node && [skip(), node, '@' + expr(PREC_CALL)],
|
|
77
77
|
|
|
78
78
|
// a[b]
|
|
79
79
|
'[', PREC_CALL, (node) => (skip(), node = ['.', node, val(expr(0,CBRACK))], node),
|
|
80
80
|
']',,,
|
|
81
81
|
|
|
82
82
|
// a(b)
|
|
83
|
-
'(', PREC_CALL, (node,b) => (
|
|
83
|
+
'(', PREC_CALL, (node,b) => (skip(), b=expr(0,CPAREN),
|
|
84
84
|
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, val(b)] : [node]
|
|
85
85
|
),
|
|
86
86
|
// (a+b)
|
|
@@ -101,8 +101,8 @@ addOps(evalOp, 2, [
|
|
|
101
101
|
'/', (a,b)=>a/b,
|
|
102
102
|
'*', (a,b)=>a*b,
|
|
103
103
|
|
|
104
|
-
'+', (a,b)=>a+b,
|
|
105
|
-
'-', (
|
|
104
|
+
'+', (a,b=0)=>a+b,
|
|
105
|
+
'-', (a,b)=>b==null ? -a : a-b,
|
|
106
106
|
|
|
107
107
|
'>>>', (a,b)=>a>>>b,
|
|
108
108
|
'>>', (a,b)=>a>>b,
|
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
let r,e;const t=(t,o)=>(e=t,r=0,o=l(),r<e.length?n():i(o)),n=(t="Bad syntax")=>{throw Error(t+" `"+e[r]+"` at "+r)},o=(t=1,n=r)=>{if("number"==typeof t)r+=t;else for(;t(a());)r++;return e.slice(n,r)},a=(t=0)=>e.charCodeAt(r+t),s=(t=1)=>e.substr(r,t),l=(e=0,o,a,s,l=0,u,p)=>{for(;(a=t.space())&&(u=(p=h[a])&&p(s,e)||!s&&f(a));)s=u;return o&&(a!=o?n("Unclosed paren"):r++),s};t.space=e=>{for(;(e=a())<=32;)r++;return e};const u=t.token=[],f=(r,e=0,t)=>{for(;e<u.length;)if(t=u[e++](r))return t},h=[],p=t.operator=(e,n=0,a=0,u,f=e.charCodeAt(0),p=e.length,y=h[f])=>(u=a?a>0?r=>r&&[o(p),i(r)]:a<0?r=>!r&&[o(p),i(l(n-1))]:a:o=>{o=[e,i(o)];do{r+=p,o.push(i(l(n)))}while(t.space()==f&&(p<2||s(p)==e));return o},h[f]=(r,t)=>t<n&&(p<2||s(p)==e)&&u(r)||y&&y(r,t)),i=r=>Array.isArray(r)?r:(r||n()).valueOf(),y=(r,e={})=>{if("string"==typeof r)return"@"===r[0]?r.slice(1):e[r];if(Array.isArray(r)){let t=r[0],n=Array.isArray(t)?y(t,e):c[t]||e[t]||t,o=[],a=1;for(;a<r.length;a++)o.push(y(r[a],e));return o.length>n.length&&n.length?o.reduce(n):n.apply(t,o)}return r},c={},g=y.operator=(r,e)=>c[r]=e;u.push((r=>(r=o((r=>r>47&&r<58||46==r)))&&((69==a()||101==a())&&(r+=o(2)+o((r=>r>=48&&r<=57))),isNaN(r=new Number(r))?n("Bad number"):r)),((r,e,t)=>34==r&&(o(),t=o((e=>e-r)),o(),"@"+t)),(r=>o((r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192))));const A=(r,e=2,t)=>{for(let n=0;n<t.length;n+=e)r(t[n],t[n+1],t[n+2])};A(p,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,"@"+l(18)],"[",18,r=>(o(),[".",r,i(l(0,93))]),"]",,,"(",18,(r,e)=>(o(),e=l(0,41),Array.isArray(e)&&","===e[0]?(e[0]=r,e):e?[r,i(e)]:[r]),"(",19,(r,e)=>!r&&(o(),l(0,41)||n()),")",,,]),A(g,2,["!",r=>!r,"++",r=>++r,"--",r=>--r,".",(r,e)=>r?r[e]:r,"%",(r,e)=>r%e,"/",(r,e)=>r/e,"*",(r,e)=>r*e,"+",(r,e=0)=>r+e,"-",(r,e)=>null==e?-r: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 d=r=>(r="string"==typeof r?t(r):r,e=>y(r,e));export{d as default,y as evaluate,t as parse};
|