subscript 5.2.2 → 5.3.2
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 +4 -4
- package/evaluate.js +13 -13
- package/justin.js +22 -26
- package/justin.min.js +1 -1
- package/package.json +4 -4
- package/parse.js +10 -5
- package/subscript.js +8 -8
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# <img alt="subscript" src="/subscript2.svg" height=42/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
|
|
2
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=
|
|
3
|
+
<a href="http://npmjs.org/subscript"><img src="https://img.shields.io/npm/v/subscript?color=indianred"/></a>
|
|
4
4
|
<a href="http://microjs.com/#subscript"><img src="https://img.shields.io/badge/microjs-subscript-blue?color=darkslateblue"/></a>
|
|
5
5
|
|
|
6
6
|
_Subscript_ is micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust, Swift, Objective C, Kotlin etc.<br/>
|
|
@@ -24,13 +24,13 @@ _Subscript_ is designed to be useful for:
|
|
|
24
24
|
|
|
25
25
|
* templates (perfect match with [template parts](https://github.com/github/template-parts))
|
|
26
26
|
* expressions evaluators, calculators
|
|
27
|
-
* subsets of languages (eg. [justin](#justin)) <!-- see sonr, mineural -->
|
|
28
|
-
*
|
|
27
|
+
* configurable subsets of languages (eg. [justin](#justin)) <!-- see sonr, mineural -->
|
|
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
|
package/evaluate.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
const cache = new WeakMap
|
|
2
2
|
|
|
3
3
|
// calltree → result
|
|
4
|
-
evaluate = (
|
|
5
|
-
if (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
export const evaluate = (node, ctx={},x, fn) => {
|
|
5
|
+
// if (fn=cache.get(node)) return fn(ctx)
|
|
6
|
+
|
|
7
|
+
if (typeof node === 'string')
|
|
8
|
+
return node[0] === '"' ? node.slice(1,-1) : node[0]==='@' ? node.slice(1) : node in ctx ? ctx[node] : node
|
|
9
|
+
|
|
10
|
+
if (Array.isArray(node) && (typeof node[0] === 'string' || Array.isArray(node[0]))) {
|
|
11
|
+
// [[a,b], c] or ['+', a, b] or ['myfn', a, b], or
|
|
12
|
+
let [c, ...args] = node, fn = typeof c === 'string' ? (lookup[c] || ctx[c]) : evaluate(c, ctx)
|
|
13
|
+
args = args.map(a => evaluate(a, ctx))
|
|
14
|
+
return fn.apply(c,args)
|
|
11
15
|
}
|
|
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
16
|
|
|
17
|
-
return
|
|
17
|
+
return node
|
|
18
18
|
},
|
|
19
19
|
lookup = {},
|
|
20
20
|
|
package/justin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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
5
|
const PERIOD=46, OPAREN=40, CPAREN=41, CBRACK=93, SPACE=32,
|
|
6
6
|
|
|
@@ -10,7 +10,6 @@ PREC_EXP=14, PREC_TOKEN=20
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
// tokens
|
|
13
|
-
const v = v => ({valueOf:()=>v})
|
|
14
13
|
parse.token.push(
|
|
15
14
|
// 1.2e+3, .5 - fast & small version, but consumes corrupted nums as well
|
|
16
15
|
(number) => (
|
|
@@ -31,14 +30,6 @@ parse.token.push(
|
|
|
31
30
|
return skip(), qc + str + qc
|
|
32
31
|
},
|
|
33
32
|
|
|
34
|
-
// literal
|
|
35
|
-
c =>
|
|
36
|
-
c === 116 && char(4) === 'true' && skip(4) ? v(true) :
|
|
37
|
-
c === 102 && char(5) === 'false' && skip(5) ? v(false) :
|
|
38
|
-
c === 110 && char(4) === 'null' && skip(4) ? v(null) :
|
|
39
|
-
c === 117 && char(9) === 'undefined' && skip(9) ? v(undefined) :
|
|
40
|
-
null,
|
|
41
|
-
|
|
42
33
|
// id
|
|
43
34
|
c => skip(c =>
|
|
44
35
|
(c >= 48 && c <= 57) || // 0..9
|
|
@@ -54,13 +45,14 @@ const escape = {n:'\n', r:'\r', t:'\t', b:'\b', f:'\f', v:'\v'}
|
|
|
54
45
|
|
|
55
46
|
// /**/, //
|
|
56
47
|
parse.space = cc => {
|
|
57
|
-
while (cc = code(), cc <= 32) {
|
|
58
|
-
skip()
|
|
59
|
-
if (
|
|
48
|
+
while (cc = code(), cc <= 32 || cc === 47) {
|
|
49
|
+
if (cc <= 32) skip()
|
|
50
|
+
else if (cc === 47)
|
|
60
51
|
// /**/
|
|
61
52
|
if (code(1) === 42) skip(2), skip(c => c !== 42 && code(1) !== 47), skip(2)
|
|
62
53
|
// //
|
|
63
54
|
else if (code(1) === 47) skip(2), skip(c => c >= 32)
|
|
55
|
+
else break
|
|
64
56
|
}
|
|
65
57
|
return cc
|
|
66
58
|
}
|
|
@@ -119,15 +111,15 @@ addOps(parse.operator, 3, [
|
|
|
119
111
|
'.', PREC_CALL, (node,b) => node && [skip(),node, typeof (b = expr(PREC_CALL)) === 'string' ? '"' + b + '"' : b.valueOf()],
|
|
120
112
|
|
|
121
113
|
// a[b]
|
|
122
|
-
'[', PREC_CALL, (node) => (skip(), node = ['.', node, expr(0,CBRACK)
|
|
114
|
+
'[', PREC_CALL, (node) => (skip(), node = ['.', node, val(expr(0,CBRACK))], node),
|
|
123
115
|
']',,,
|
|
124
116
|
|
|
125
117
|
// a(b)
|
|
126
|
-
'(', PREC_CALL, (node,b) => ( skip(), b=expr(0,CPAREN),
|
|
127
|
-
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, b
|
|
118
|
+
'(', PREC_CALL, (node,b) => ( skip(), b=expr(0,CPAREN),
|
|
119
|
+
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, val(b)] : [node]
|
|
128
120
|
),
|
|
129
121
|
// (a+b)
|
|
130
|
-
'(', PREC_GROUP, (node,b) => !node && (skip(), b=expr(0,CPAREN) || err(),
|
|
122
|
+
'(', PREC_GROUP, (node,b) => !node && (skip(), b=expr(0,CPAREN) || err(), b),
|
|
131
123
|
')',,,
|
|
132
124
|
|
|
133
125
|
// justin extension
|
|
@@ -140,25 +132,31 @@ addOps(parse.operator, 3, [
|
|
|
140
132
|
if (!node) err('Expected expression')
|
|
141
133
|
let a, b
|
|
142
134
|
skip(), parse.space(), a = expr()
|
|
143
|
-
|
|
144
|
-
skip(), parse.space(), b = expr()
|
|
145
|
-
return ['?:', node, a, b]
|
|
135
|
+
return ['?:', node, a[1], a[2]]
|
|
146
136
|
},
|
|
147
137
|
'}',,,
|
|
148
|
-
':'
|
|
138
|
+
':',2,,
|
|
149
139
|
'in', PREC_COMP, (node) => code(2) <= 32 && [skip(2), '"'+node+'"', expr(PREC_COMP)],
|
|
150
140
|
|
|
141
|
+
// as operator it's faster to lookup (no need to extra rule check), smaller and no conflict with word names
|
|
151
142
|
// [a,b,c]
|
|
152
143
|
'[', PREC_TOKEN, (node,arg) => !node && (
|
|
153
|
-
skip(), arg=expr(0,93),
|
|
144
|
+
skip(), arg=expr(0,93),
|
|
154
145
|
!arg ? ['['] : arg[0] == ',' ? (arg[0]='[',arg) : ['[',arg]
|
|
155
146
|
),
|
|
156
147
|
|
|
157
148
|
// {a:0, b:1}
|
|
158
|
-
'{', PREC_TOKEN, (node,arg) => !node && (skip(), arg=expr(0,125),
|
|
159
|
-
!arg ? ['{'] : arg[0] == ':' ? ['{',arg] : arg[0] == ',' ? (arg[0]='{',arg) : ['
|
|
149
|
+
'{', PREC_TOKEN, (node,arg) => !node && (skip(), arg=expr(0,125),
|
|
150
|
+
!arg ? ['{'] : arg[0] == ':' ? ['{',arg] : arg[0] == ',' ? (arg[0]='{',arg) : ['{',arg])
|
|
160
151
|
,
|
|
152
|
+
|
|
153
|
+
// literals
|
|
154
|
+
'null', PREC_TOKEN, node=>!node&&(skip(4),v(null)),
|
|
155
|
+
'false', PREC_TOKEN, node=>!node&&(skip(5),v(false)),
|
|
156
|
+
'true', PREC_TOKEN, node=>!node&&(skip(4),v(true)),
|
|
157
|
+
'undefined', PREC_TOKEN, node=>!node&&(skip(9),v(undefined)),
|
|
161
158
|
])
|
|
159
|
+
const v = v => ({valueOf:()=>v})
|
|
162
160
|
|
|
163
161
|
addOps(evaluate.operator, 2, [
|
|
164
162
|
// subscript
|
|
@@ -200,9 +198,7 @@ addOps(evaluate.operator, 2, [
|
|
|
200
198
|
'?:', (a,b,c)=>a?b:c,
|
|
201
199
|
'in', (a,b)=>a in b,
|
|
202
200
|
|
|
203
|
-
// []
|
|
204
201
|
'[', (...args) => Array(...args),
|
|
205
|
-
// as operator it's faster to lookup (no need to call extra rule check), smaller and no conflict with word names
|
|
206
202
|
'{', (...args)=>Object.fromEntries(args),
|
|
207
203
|
':', (a,b)=>[a,b]
|
|
208
204
|
])
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
const e=(t,n={},o,s)=>{if("string"==typeof t)return'"'===t[0]?t.slice(1,-1):"@"===t[0]?t.slice(1):t in n?n[t]:t;if(Array.isArray(t)&&("string"==typeof t[0]||Array.isArray(t[0]))){let[o,...s]=t,a="string"==typeof o?r[o]||n[o]:e(o,n);return s=s.map((r=>e(r,n))),a.apply(o,s)}return t},r={};let t,n;e.operator=(e,t)=>r[e]=2==t.length?(...e)=>e.reduce(t):t;const o=(e,r)=>(n=e,t=0,r=l(),t<n.length?s():y(r)),s=(e="Bad syntax")=>{throw Error(e+" `"+n[t]+"` at "+t)},a=(e=1,r=t)=>{if("number"==typeof e)t+=e;else for(;e(i());)t++;return n.slice(r,t)},i=(e=0)=>n.charCodeAt(t+e),f=(e=1)=>n.substr(t,e),l=(e=0,r,n,a,i=0,f,l)=>{for(;(n=o.space())&&(l=c[n]?.(a,e)||!a&&p(n));)a=l;return r&&(n!=r?s("Unclosed paren"):t++),a};o.space=e=>{for(;(e=i())<=32;)t++;return e};const u=o.token=[],p=(e,r=0,t)=>{for(;r<u.length;)if(t=u[r++](e))return t},c=[];o.operator=(e,r=0,n=0,s,u=e.charCodeAt(0),p=e.length,d=c[u],h=n<=0&&e.toUpperCase()!==e)=>(s=n?n>0?e=>e&&[a(p),y(e)]:n<0?e=>!e&&[a(p),y(l(r-1))]:n:n=>{n=[e,y(n)];do{t+=p,n.push(y(l(r)))}while(o.space()==u&&(p<2||f(p)==e)&&(!h||i(p)<=32));return n},c[u]=(t,n)=>n<r&&(p<2||f(p)==e)&&(!h||i(p)<=32)&&s(t)||d&&d(t,n));const y=e=>Array.isArray(e)?e:(e||s()).valueOf();o.token.push((e=>(e=a((e=>e>47&&e<58||46==e)))&&((69==i()||101==i())&&(e+=a(2)+a((e=>e>=48&&e<=57))),isNaN(e=new Number(e))?s("Bad number"):e)),((e,r,t,n)=>{if(34===e||39===e){for(r=f(),a(),n="";(t=i())-e;)92===t?(a(),n+=d[f()]||f()):n+=f(),a();return a(),r+n+r}}),(e=>a((e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e))));const d={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"};o.space=e=>{for(;(e=i())<=32||47===e;)if(e<=32)a();else if(47===e)if(42===i(1))a(2),a((e=>42!==e&&47!==i(1))),a(2);else{if(47!==i(1))break;a(2),a((e=>e>=32))}return e};const h=(e,r=2,t)=>{for(let n=0;n<t.length;n+=r)e(t[n],t[n+1],t[n+2])};h(o.operator,3,[",",1,,"|",6,,"||",4,,"&",8,,"&&",5,,"^",7,,"==",9,,"!=",9,,">",10,,">=",10,,">>",11,,">>>",11,,"<",10,,"<=",10,,"<<",11,,"+",12,,"+",15,-1,"++",15,-1,"++",15,1,"-",12,,"-",15,-1,"--",15,-1,"--",15,1,"!",15,-1,"*",13,,"/",13,,"%",13,,".",18,(e,r)=>e&&[a(),e,"string"==typeof(r=l(18))?'"'+r+'"':r.valueOf()],"[",18,e=>(a(),[".",e,y(l(0,93))]),"]",,,"(",18,(e,r)=>(a(),r=l(0,41),Array.isArray(r)&&","===r[0]?(r[0]=e,r):r?[e,y(r)]:[e]),"(",19,(e,r)=>!e&&(a(),l(0,41)||s()),")",,,";",1,,"===",9,,"!==",9,,"**",14,,"~",15,-1,"?",3,e=>{let r;return e||s("Expected expression"),a(),o.space(),r=l(),["?:",e,r[1],r[2]]},"}",,,":",2,,"in",10,e=>i(2)<=32&&[a(2),'"'+e+'"',l(10)],"[",20,(e,r)=>!e&&(a(),(r=l(0,93))?","==r[0]?(r[0]="[",r):["[",r]:["["]),"{",20,(e,r)=>!e&&(a(),(r=l(0,125))?":"==r[0]?["{",r]:","==r[0]?(r[0]="{",r):["{",r]:["{"]),"null",20,e=>!e&&(a(4),g(null)),"false",20,e=>!e&&(a(5),g(!1)),"true",20,e=>!e&&(a(4),g(!0)),"undefined",20,e=>!e&&(a(9),g(void 0))]);const g=e=>({valueOf:()=>e});h(e.operator,2,["!",e=>!e,"++",e=>++e,"--",e=>--e,".",(e,r)=>e?e[r]:e,"%",(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 A=r=>(r="string"==typeof r?o(r):r,t=>e(r,t));export{A as default,e 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.3.2",
|
|
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
|
@@ -24,7 +24,8 @@ expr = (prec=0, end, cc, node, i=0, map, newNode) => {
|
|
|
24
24
|
(cc=parse.space()) && (newNode = lookup[cc]?.(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') : idx++
|
|
28
29
|
|
|
29
30
|
return node
|
|
30
31
|
},
|
|
@@ -43,11 +44,15 @@ lookup = [],
|
|
|
43
44
|
// @param op is operator string
|
|
44
45
|
// @param prec is operator precedenc to check
|
|
45
46
|
// @param map is either number +1 - postfix unary, -1 prefix unary, 0 binary, else - custom mapper function
|
|
46
|
-
operator = parse.operator =
|
|
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
|
|
51
|
+
) => (
|
|
47
52
|
map = !type ? node => { // binary, consume same-op group
|
|
48
|
-
node = [op, node
|
|
53
|
+
node = [op, val(node)]
|
|
49
54
|
do { idx+=l, node.push(val(expr(prec))) }
|
|
50
|
-
while (parse.space()==c && (l<2||char(l)==op) && (!
|
|
55
|
+
while (parse.space()==c && (l<2||char(l)==op) && (!spaced||code(l)<=SPACE))
|
|
51
56
|
return node
|
|
52
57
|
} :
|
|
53
58
|
type > 0 ? node => node && [skip(l), val(node)] : // postfix unary
|
|
@@ -55,7 +60,7 @@ operator = parse.operator = (op, prec=0, type=0, map, c=op.charCodeAt(0), l=op.
|
|
|
55
60
|
type,
|
|
56
61
|
|
|
57
62
|
lookup[c] = (node, curPrec) =>
|
|
58
|
-
curPrec < prec && (l<2||char(l)==op) && (!
|
|
63
|
+
curPrec < prec && (l<2||char(l)==op) && (!spaced||code(l)<=SPACE) &&
|
|
59
64
|
map(node) || (prev && prev(node, curPrec))
|
|
60
65
|
),
|
|
61
66
|
|
package/subscript.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import parse, {skip, expr, code, tokens, 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,
|
|
@@ -58,11 +58,11 @@ addOps(parseOp, 3, [
|
|
|
58
58
|
'+', PREC_SUM,,
|
|
59
59
|
'+', PREC_UNARY, -1,
|
|
60
60
|
'++', PREC_UNARY, -1,
|
|
61
|
-
'++',
|
|
61
|
+
'++', PREC_POSTFIX, +1,
|
|
62
62
|
'-', PREC_SUM,,
|
|
63
63
|
'-', PREC_UNARY, -1,
|
|
64
64
|
'--', PREC_UNARY, -1,
|
|
65
|
-
'--',
|
|
65
|
+
'--', PREC_POSTFIX, +1,
|
|
66
66
|
|
|
67
67
|
// ! ~
|
|
68
68
|
'!', PREC_UNARY, -1,
|
|
@@ -76,15 +76,15 @@ addOps(parseOp, 3, [
|
|
|
76
76
|
'.', PREC_CALL, (node,b) => node && [skip(),node, typeof (b = expr(PREC_CALL)) === 'string' ? '"' + b + '"' : b.valueOf()],
|
|
77
77
|
|
|
78
78
|
// a[b]
|
|
79
|
-
'[', PREC_CALL, (node) => (skip(), node = ['.', node, expr(0,CBRACK)
|
|
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) => ( skip(), b=expr(0,CPAREN),
|
|
84
|
-
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, b
|
|
83
|
+
'(', PREC_CALL, (node,b) => ( skip(), b=expr(0,CPAREN),
|
|
84
|
+
Array.isArray(b) && b[0]===',' ? (b[0]=node, b) : b ? [node, val(b)] : [node]
|
|
85
85
|
),
|
|
86
86
|
// (a+b)
|
|
87
|
-
'(', PREC_GROUP, (node,b) => !node && (skip(), b=expr(0,CPAREN) || err(),
|
|
87
|
+
'(', PREC_GROUP, (node,b) => !node && (skip(), b=expr(0,CPAREN) || err(), b),
|
|
88
88
|
')',,,
|
|
89
89
|
])
|
|
90
90
|
|
|
@@ -101,7 +101,7 @@ addOps(evalOp, 2, [
|
|
|
101
101
|
'/', (a,b)=>a/b,
|
|
102
102
|
'*', (a,b)=>a*b,
|
|
103
103
|
|
|
104
|
-
'+', (a,b)=>a+b,
|
|
104
|
+
'+', (a,b=0)=>a+b,
|
|
105
105
|
'-', (...a)=>a.length < 2 ? -a : a.reduce((a,b)=>a-b),
|
|
106
106
|
|
|
107
107
|
'>>>', (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():y(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,p,f)=>{for(;(a=t.space())&&(f=u[a]?.(s,e)||!s&&i(a));)s=f;return o&&(a!=o?n("Unclosed paren"):r++),s};t.space=e=>{for(;(e=a())<=32;)r++;return e};const p=t.token=[],i=(r,e=0,t)=>{for(;e<p.length;)if(t=p[e++](r))return t},u=[],f=t.operator=(e,n=0,p=0,i,f=e.charCodeAt(0),c=e.length,h=u[f],g=p<=0&&e.toUpperCase()!==e)=>(i=p?p>0?r=>r&&[o(c),y(r)]:p<0?r=>!r&&[o(c),y(l(n-1))]:p:o=>{o=[e,y(o)];do{r+=c,o.push(y(l(n)))}while(t.space()==f&&(c<2||s(c)==e)&&(!g||a(c)<=32));return o},u[f]=(r,t)=>t<n&&(c<2||s(c)==e)&&(!g||a(c)<=32)&&i(r)||h&&h(r,t)),y=r=>Array.isArray(r)?r:(r||n()).valueOf(),c=(r,e={},t,n)=>{if("string"==typeof r)return'"'===r[0]?r.slice(1,-1):"@"===r[0]?r.slice(1):r in e?e[r]:r;if(Array.isArray(r)&&("string"==typeof r[0]||Array.isArray(r[0]))){let[t,...n]=r,o="string"==typeof t?h[t]||e[t]:c(t,e);return n=n.map((r=>c(r,e))),o.apply(t,n)}return r},h={},g=c.operator=(r,e)=>h[r]=2==e.length?(...r)=>r.reduce(e):e;p.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)=>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))));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(f,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,y(l(0,93))]),"]",,,"(",18,(r,e)=>(o(),e=l(0,41),Array.isArray(e)&&","===e[0]?(e[0]=r,e):e?[r,y(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)=>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 d=r=>(r="string"==typeof r?t(r):r,e=>c(r,e));export{d as default,c as evaluate,t as parse};
|