subscript 5.3.1 → 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 +2 -2
- package/evaluate.js +13 -13
- package/justin.js +2 -4
- package/justin.min.js +1 -1
- package/package.json +1 -1
- package/subscript.js +1 -1
- 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
|
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
|
@@ -132,12 +132,10 @@ addOps(parse.operator, 3, [
|
|
|
132
132
|
if (!node) err('Expected expression')
|
|
133
133
|
let a, b
|
|
134
134
|
skip(), parse.space(), a = expr()
|
|
135
|
-
|
|
136
|
-
skip(), parse.space(), b = expr()
|
|
137
|
-
return ['?:', node, a, b]
|
|
135
|
+
return ['?:', node, a[1], a[2]]
|
|
138
136
|
},
|
|
139
137
|
'}',,,
|
|
140
|
-
':'
|
|
138
|
+
':',2,,
|
|
141
139
|
'in', PREC_COMP, (node) => code(2) <= 32 && [skip(2), '"'+node+'"', expr(PREC_COMP)],
|
|
142
140
|
|
|
143
141
|
// as operator it's faster to lookup (no need to extra rule check), smaller and no conflict with word names
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=
|
|
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
package/subscript.js
CHANGED
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e
|
|
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};
|