subscript 5.2.1 → 5.2.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/package.json +1 -1
- package/parse.js +12 -11
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ _Subscript_ is designed to be useful for:
|
|
|
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_, with _jsep+_ test coverage and better performance.
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
## Evaluation
|
|
@@ -285,7 +285,7 @@ Subscript shows relatively good performance within other evaluators:
|
|
|
285
285
|
// 1 + (a * b / c % d) - 2.0 + -3e-3 * +4.4e4 / f.g[0] - i.j(+k == 1)(0)
|
|
286
286
|
// parse 30k times
|
|
287
287
|
|
|
288
|
-
subscript: ~
|
|
288
|
+
subscript: ~230 ms
|
|
289
289
|
jsep: ~280 ms
|
|
290
290
|
expr-eval: ~480 ms
|
|
291
291
|
jexl: ~1200 ms
|
package/package.json
CHANGED
package/parse.js
CHANGED
|
@@ -3,7 +3,7 @@ const SPACE=32
|
|
|
3
3
|
// current string & index
|
|
4
4
|
let idx, cur
|
|
5
5
|
|
|
6
|
-
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)),
|
|
7
7
|
|
|
8
8
|
err = (msg='Bad syntax') => { throw Error(msg + ' `' + cur[idx] + '` at ' + idx) },
|
|
9
9
|
|
|
@@ -44,21 +44,22 @@ lookup = [],
|
|
|
44
44
|
// @param prec is operator precedenc to check
|
|
45
45
|
// @param map is either number +1 - postfix unary, -1 prefix unary, 0 binary, else - custom mapper function
|
|
46
46
|
operator = parse.operator = (op, prec=0, type=0, map, c=op.charCodeAt(0), l=op.length, prev=lookup[c], word=op.toUpperCase()!==op, isop) => (
|
|
47
|
-
isop = l<2 ? // word operator must have space after
|
|
48
|
-
!word ? c=>1 : c=>code(1)<=SPACE :
|
|
49
|
-
!word ? c=>char(l)==op : c=>char(l)==op&&code(l)<=SPACE,
|
|
50
|
-
|
|
51
47
|
map = !type ? node => { // binary, consume same-op group
|
|
52
48
|
node = [op, node || err()]
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
do { idx+=l, node.push(val(expr(prec))) }
|
|
50
|
+
while (parse.space()==c && (l<2||char(l)==op) && (!word||code(l)<=SPACE)) // word operator must have space after
|
|
55
51
|
return node
|
|
56
52
|
} :
|
|
57
|
-
type > 0 ? node => node && [skip(l), node] : // postfix unary
|
|
58
|
-
type < 0 ? node => !node && [skip(l), (expr(prec-1)
|
|
53
|
+
type > 0 ? node => node && [skip(l), val(node)] : // postfix unary
|
|
54
|
+
type < 0 ? node => !node && [skip(l), val(expr(prec-1))] : // prefix unary
|
|
59
55
|
type,
|
|
60
56
|
|
|
61
|
-
lookup[c] = (node, curPrec) =>
|
|
62
|
-
)
|
|
57
|
+
lookup[c] = (node, curPrec) =>
|
|
58
|
+
curPrec < prec && (l<2||char(l)==op) && (!word||code(l)<=SPACE) &&
|
|
59
|
+
map(node) || (prev && prev(node, curPrec))
|
|
60
|
+
),
|
|
61
|
+
|
|
62
|
+
// in order to support literal tokens, we call valueOf any time we create or modify calltree node
|
|
63
|
+
val = node => Array.isArray(node) ? node : (node || err()).valueOf()
|
|
63
64
|
|
|
64
65
|
export default parse
|
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,r,a=(a,o)=>(r=a,e=0,o=l(),e<r.length?t():o
|
|
1
|
+
var e,r,a=(a,o)=>(r=a,e=0,o=l(),e<r.length?t():y(o)),t=(a="Bad syntax")=>{throw Error(a+" `"+r[e]+"` at "+e)},o=(a=1,t=e)=>{if("number"==typeof a)e+=a;else for(;a(n());)e++;return r.slice(t,e)},n=(a=0)=>r.charCodeAt(e+a),s=(a=1)=>r.substr(e,a),l=(e=0,r,o,n,s=0,l,f)=>{for(;(o=a.space())&&(f=u[o]?.(n,e)||!n&&p(o));)n=f;return r&&o!==r&&t("Unclosed paren"),n},f=(a.space=r=>{for(;(r=n())<=32;)e++;return r},a.token=[]),p=(e,r=0,a)=>{for(;r<f.length;)if(a=f[r++](e))return a},u=[],i=a.operator=(r,f=0,p=0,i,c=r.charCodeAt(0),h=r.length,g=u[c],d=r.toUpperCase()!==r,v)=>(i=p?p>0?e=>e&&[o(h),y(e)]:p<0?e=>!e&&[o(h),y(l(f-1))]:p:o=>{o=[r,o||t()];do{e+=h,o.push(y(l(f)))}while(a.space()==c&&(h<2||s(h)==r)&&(!d||n(h)<=32));return o},u[c]=(e,a)=>a<f&&(h<2||s(h)==r)&&(!d||n(h)<=32)&&i(e)||g&&g(e,a)),y=e=>Array.isArray(e)?e:(e||t()).valueOf(),c=a,h=e=>Array.isArray(e)&&("string"==typeof e[0]||h(e[0])),g=(e,r={},a,t)=>h(e)?("string"==typeof(a=e[0])&&(t=d[a]),"function"!=typeof(a=t||g(a,r))?a:a.call(...e.map((e=>g(e,r))))):e&&"string"==typeof e?'"'===e[0]?e.slice(1,-1):"@"===e[0]?e.slice(1):e in r?r[e]:e:e,d={},v=g.operator=(e,r)=>d[e]=2==r.length?(...e)=>e.reduce(r):r,A=g,m=15;f.push((e=>(e=o((e=>e>47&&e<58||46==e)))&&((69==n()||101==n())&&(e+=o(2)+o((e=>e>=48&&e<=57))),isNaN(e=new Number(e))?err("Bad number"):e)),((e,r)=>34==e&&o()+o((r=>r-e))+o()),(e=>o((e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192))));var b=(e,r=2,a)=>{for(let t=0;t<a.length;t+=r)e(a[t],a[t+1],a[t+2])};b(i,3,[",",1,,"|",6,,"||",4,,"&",8,,"&&",5,,"^",7,,"==",9,,"!=",9,,">",10,,">=",10,,">>",11,,">>>",11,,"<",10,,"<=",10,,"<<",11,,"+",12,,"+",m,-1,"++",m,-1,"++",m,1,"-",12,,"-",m,-1,"--",m,-1,"--",m,1,"!",m,-1,"*",13,,"/",13,,"%",13,,".",18,(e,r)=>e&&[o(),e,"string"==typeof(r=l(18))?'"'+r+'"':r.valueOf()],"[",18,e=>(o(),e=[".",e,l(0,93).valueOf()],o(),e),"]",,,"(",18,(e,r)=>(o(),r=l(0,41),o(),Array.isArray(r)&&","===r[0]?(r[0]=e,r):r?[e,r.valueOf()]:[e]),"(",19,(e,r)=>!e&&(o(),r=l(0,41)||err(),o(),r),")",,,]),b(v,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]);var B=e=>(e="string"==typeof e?c(e):e,r=>A(e,r));export{B as default,A as evaluate,c as parse};
|