subscript 7.4.4 → 7.4.6
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/justin.min.js +1 -1
- package/package.json +2 -2
- package/parse.js +12 -2
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ tree // ['+', ['.', 'a', 'b'], 'c']
|
|
|
21
21
|
|
|
22
22
|
// compile tree to evaluable function
|
|
23
23
|
fn = compile(tree)
|
|
24
|
-
fn({a:{b:1}, c:2}) // 3
|
|
24
|
+
fn({a:{b:1}, c:2}) // 3
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Motivation
|
|
@@ -97,7 +97,7 @@ Operators/tokens can be extended via:
|
|
|
97
97
|
* `unary(str, precedence, postfix=false)` − register unary operator, either prefix or postfix.
|
|
98
98
|
* `binary(str, precedence, rightAssoc=false)` − register binary operator, optionally right-associative.
|
|
99
99
|
* `nary(str, precedence, allowSkip=false)` − register n-ary (sequence) operator, optionally allowing skipping args.
|
|
100
|
-
* `token(str, precedence, map)` − register custom token or literal. `map` takes last token argument and returns
|
|
100
|
+
* `token(str, precedence, map)` − register custom token or literal. `map` takes last token argument and returns tree node.
|
|
101
101
|
* `operator(str, fn)` − register evaluator for operator. `fn` takes node arguments and returns evaluator function.
|
|
102
102
|
|
|
103
103
|
```js
|
|
@@ -124,7 +124,7 @@ See [subscript.js](subscript.js) or [justin.js](./justin.js) for examples.
|
|
|
124
124
|
|
|
125
125
|
Subscript exposes separate `./parse.js` and `./compile.js` entries. Parser builds AST, compiler converts it to evaluable function.
|
|
126
126
|
|
|
127
|
-
AST has simplified lispy
|
|
127
|
+
AST has simplified lispy tree structure (inspired by [frisk](https://ghub.io/frisk) / [nisp](https://github.com/ysmood/nisp)), opposed to [ESTree](https://github.com/estree/estree):
|
|
128
128
|
|
|
129
129
|
* not limited to particular language (JS), can be compiled to different targets;
|
|
130
130
|
* reflects execution sequence, rather than code layout;
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e,t,r=r=>(e=0,t=r,r=s(),t[e]?l():r||""),l=(r="Bad syntax",l=t[e],n=t.slice(0,e).split("\n"),a=n.pop())=>{throw SyntaxError(`${r} ${l?`\`${l}\` `:""}at ${n.length}:${a.length}`,n.length)},n=(r="Bad syntax",l=t[e],n=t.slice(0,e).split("\n"),a=n.pop())=>{let s=t.slice(e-10,e).split("\n").pop(),i=t.slice(e+1,e+10).split("\n").shift(),h=n.length+":"+a.length;throw EvalError(`${r} at ${h} \`${s+l+i}\`\n${" ".repeat(18+r.length+h.length+s.length+1)}^`)},a=(r=1,l=e,n)=>{if("number"==typeof r)e+=r;else for(;n=r(t.charCodeAt(e));)e+=n;return t.slice(l,e)},s=(t=0,n,a,s,i,h)=>{for(;(a=r.space())&&(i=((h=o[a])&&h(s,t))??(!s&&r.id()));)s=i;return n&&(a==n?e++:l()),s},i=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,h=r.space=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},p=r.id=e=>a(i),o=[],c=(r,l=32,n,a=r.charCodeAt(0),s=r.length,h=o[a],p=r.toUpperCase()!==r)=>o[a]=(a,o,c=e)=>o<l&&(s<2||t.substr(e,s)==r)&&(!p||!i(t.charCodeAt(e+s)))&&(e+=s,n(a,o))||(e=c,h?.(a,o)),f=(e,t,r=0)=>c(e,t,((l,n)=>l&&(n=s(t-r/2))&&[e,l,n])),g=(e,t,r)=>c(e,t,(l=>r?l&&[e,l]:!l&&(l=s(t
|
|
1
|
+
let e,t,r=r=>(e=0,t=r,r=s(),t[e]?l():r||""),l=(r="Bad syntax",l=t[e],n=t.slice(0,e).split("\n"),a=n.pop())=>{throw SyntaxError(`${r} ${l?`\`${l}\` `:""}at ${n.length}:${a.length}`,n.length)},n=(r="Bad syntax",l=t[e],n=t.slice(0,e).split("\n"),a=n.pop())=>{let s=t.slice(e-10,e).split("\n").pop(),i=t.slice(e+1,e+10).split("\n").shift(),h=n.length+":"+a.length;throw EvalError(`${r} at ${h} \`${s+l+i}\`\n${" ".repeat(18+r.length+h.length+s.length+1)}^`)},a=(r=1,l=e,n)=>{if("number"==typeof r)e+=r;else for(;n=r(t.charCodeAt(e));)e+=n;return t.slice(l,e)},s=(t=0,n,a,s,i,h)=>{for(;(a=r.space())&&(i=((h=o[a])&&h(s,t))??(!s&&r.id()));)s=i;return n&&(a==n?e++:l()),s},i=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,h=r.space=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},p=r.id=e=>a(i),o=[],c=(r,l=32,n,a=r.charCodeAt(0),s=r.length,h=o[a],p=r.toUpperCase()!==r)=>o[a]=(a,o,c=e)=>o<l&&(s<2||t.substr(e,s)==r)&&(!p||!i(t.charCodeAt(e+s)))&&(e+=s,n(a,o))||(e=c,h?.(a,o)),f=(e,t,r=0)=>c(e,t,((l,n)=>l&&(n=s(t-r/2))&&[e,l,n])),g=(e,t,r)=>c(e,t,(l=>r?l&&[e,l]:!l&&(l=s(t-.5))&&[e,l])),d=(e,t,r)=>{c(e,t,((l,n)=>(l||r)&&((n=s(t))||r)&&((!l||l[0]!==e)&&(l=[e,l]),(n||r)&&l.push(n),l)))};const u=e=>Array.isArray(e)?m[e[0]](...e.slice(1)):t=>t?.[e],m={},A=(e,t,r=m[e])=>m[e]=(...e)=>t(...e)||r&&r(...e),b=e=>(e=r(e),t=>(e.call?e:e=u(e))(t)),y=(e,t,r)=>r[0]||r[1]?(t?c(e,t,r[0]):o[e.charCodeAt(0)||1]=r[0],A(e,r[1])):r.length?r.length>1?(f(e,Math.abs(t),t<0),A(e,((e,t)=>t&&(e=u(e),t=u(t),e.length||t.length?l=>r(e(l),t(l)):(e=r(e(),t()),()=>e))))):(g(e,t),A(e,((e,t)=>!t&&((e=u(e)).length?t=>r(e(t)):(e=r(e()),()=>e))))):(d(e,Math.abs(t),t<0),A(e,((...e)=>(e=e.map(u),t=>r(...e.map((e=>e(t)))))))),$=e=>e?l():["",(e=+a((e=>46===e||e>=48&&e<=57||(69===e||101===e?2:0))))!=e?l():e],C=(e,t,r,l)=>[e,t,[r=>r?["++"===e?"-":"+",[e,r],["",1]]:[e,s(t-1)],l=(e,t)=>"("===e[0]?l(e[1]):"."===e[0]?(t=e[2],e=u(e[1]),l=>r(e(l),t)):"["===e[0]?([,e,t]=e,e=u(e),t=u(t),l=>r(e(l),t(l))):t=>r(t,e)]],x=["",,[,e=>()=>e],'"',,[e=>e?l():["",(a()+a((e=>e-34?1:0))+(a()||l("Bad string"))).slice(1,-1)]],".",,[e=>!e&&$()],...Array(10).fill(0).flatMap(((e,t)=>[""+t,0,[$]])),",",1,(...e)=>e[e.length-1],"||",4,(...e)=>{let t,r=0;for(;!t&&r<e.length;)t=e[r++];return t},"&&",5,(...e)=>{let t=0,r=!0;for(;r&&t<e.length;)r=e[t++];return r},"+",12,(e,t)=>e+t,"-",12,(e,t)=>e-t,"*",13,(e,t)=>e*t,"/",13,(e,t)=>e/t,"%",13,(e,t)=>e%t,"|",6,(e,t)=>e|t,"&",8,(e,t)=>e&t,"^",7,(e,t)=>e^t,"==",9,(e,t)=>e==t,"!=",9,(e,t)=>e!=t,">",10,(e,t)=>e>t,">=",10,(e,t)=>e>=t,"<",10,(e,t)=>e<t,"<=",10,(e,t)=>e<=t,">>",11,(e,t)=>e>>t,">>>",11,(e,t)=>e>>>t,"<<",11,(e,t)=>e<<t,"+",15,e=>+e,"-",15,e=>-e,"!",15,e=>!e,...C("++",15,((e,t)=>++e[t])),...C("--",15,((e,t)=>--e[t])),"[",18,[e=>e&&["[",e,s(0,93)||l()],(e,t)=>t&&(e=u(e),t=u(t),r=>e(r)[t(r)])],".",18,[(e,t)=>e&&(t=s(18))&&[".",e,t],(e,t)=>(e=u(e),t=t[0]?t:t[1],r=>e(r)[t])],"(",18,[e=>!e&&["(",s(0,41)||l()],u],"(",18,[(e,t)=>e&&((t=s(0,41))?["(",e,t]:["(",e,""]),(e,t,r,l)=>null!=t&&(l=""==t?()=>[]:","===t[0]?(t=t.slice(1).map(u),e=>t.map((t=>t(e)))):(t=u(t),e=>[t(e)]),"."===e[0]?(r=e[2],e=u(e[1]),t=>e(t)[r](...l(t))):"["===e[0]?(r=u(e[2]),e=u(e[1]),t=>e(t)[r(t)](...l(t))):(e=u(e),t=>e(t)(...l(t))))]];for(;x[2];)y(...x.splice(0,3));let E={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},v=r=>(n,s,i="")=>{for(n&&l("Unexpected string"),a();(s=t.charCodeAt(e))-r;)92===s?(a(),s=a(),i+=E[s]||s):i+=a();return a(),["",i]},B=["===",9,(e,t)=>e===t,"!==",9,(e,t)=>e!==t,"~",15,e=>~e,"?",3,[(e,t,r)=>e&&(t=s(2,58))&&["?",e,t,s(3)],(e,t,r)=>(e=u(e),t=u(t),r=u(r),l=>e(l)?t(l):r(l))],"??",6,(e,t)=>e??t,"?.",18,[e=>e&&["?.",e],e=>(e=u(e),t=>e(t)||(()=>{}))],"?.",18,[(e,t)=>e&&!(t=s(18))?.map&&["?.",e,t],(e,t)=>t&&(e=u(e),r=>e(r)?.[t])],"in",10,(e,t)=>e in t,'"',,[v(34)],"'",,[v(39)],"/*",20,[(r,l)=>(a((r=>42!==r&&47!==t.charCodeAt(e+1))),a(2),r||s(l))],"//",20,[(e,t)=>(a((e=>e>=32)),e||s(t))],"null",20,[e=>e?l():["",null]],"true",20,[e=>e?l():["",!0]],"false",20,[e=>e?l():["",!1]],"undefined",20,[e=>e?l():["",void 0]],";",-20,(...e)=>{for(let t=e.length;t--;)if(null!=e[t])return e[t]},"**",-14,(e,t)=>e**t,"[",20,[e=>!e&&["[",s(0,93)||""],(e,t)=>!t&&(e?","===e[0]?(e=e.slice(1).map(u),t=>e.map((e=>e(t)))):(e=u(e),t=>[e(t)]):()=>[])],"{",20,[e=>!e&&["{",s(0,125)||""],(e,t)=>e?","===e[0]?(e=e.slice(1).map(u),t=>Object.fromEntries(e.map((e=>e(t))))):":"===e[0]?(e=u(e),t=>Object.fromEntries([e(t)])):(t=u(e),r=>({[e]:t(r)})):e=>({})],":",1.1,[(e,t)=>[":",e,s(1.1)||l()],(e,t)=>(t=u(t),e=Array.isArray(e)?u(e):(e=>e).bind(0,e),r=>[e(r),t(r)])]];for(;B[2];)y(...B.splice(0,3));export{f as binary,u as compile,t as cur,b as default,l as err,s as expr,p as id,e as idx,i as isId,n as longErr,o as lookup,d as nary,A as operator,m as operators,r as parse,y as set,a as skip,h as space,c as token,g as unary};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subscript",
|
|
3
|
-
"version": "7.4.
|
|
3
|
+
"version": "7.4.6",
|
|
4
4
|
"description": "Fast and tiny expression evaluator with minimal syntax.",
|
|
5
5
|
"main": "subscript.js",
|
|
6
6
|
"module": "subscript.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"min-subscript": "terser subscript.min.js -o subscript.min.js --module -c passes=3 -m",
|
|
35
35
|
"build-justin": "rollup justin.js --file justin.min.js --format esm --name \"Justin\"",
|
|
36
36
|
"min-justin": "terser justin.min.js -o justin.min.js --module -c passes=3 -m",
|
|
37
|
-
"test": "node test && node test/jsep && node test/perf",
|
|
37
|
+
"test": "node test/tree && node test/subscript && node test/jsep && node test/perf",
|
|
38
38
|
"check-types": "tsc --noEmit subscript.d.ts"
|
|
39
39
|
},
|
|
40
40
|
"repository": {
|
package/parse.js
CHANGED
|
@@ -79,7 +79,17 @@ token = (
|
|
|
79
79
|
|
|
80
80
|
// right assoc is indicated by negative precedence (meaning go from right to left)
|
|
81
81
|
binary = (op, prec, right=0) => token(op, prec, (a, b) => a && (b=expr(prec-right/2)) && [op,a,b] ),
|
|
82
|
-
unary = (op, prec, post) => token(op, prec, a => post ? (a && [op, a]) : (!a && (a=expr(prec
|
|
83
|
-
nary = (op, prec, skips) =>
|
|
82
|
+
unary = (op, prec, post) => token(op, prec, a => post ? (a && [op, a]) : (!a && (a=expr(prec-.5)) && [op, a])),
|
|
83
|
+
nary = (op, prec, skips) => {
|
|
84
|
+
token(op, prec, (a, b) => (
|
|
85
|
+
(a || skips) && // if lhs exists or we're ok to skip
|
|
86
|
+
(b=expr(prec), b||skips) && // either rhs exists or we're ok to skip rhs
|
|
87
|
+
(
|
|
88
|
+
(!a || a[0] !== op) && (a = [op,a]), // if beginning of sequence - init node
|
|
89
|
+
(b || skips) && a.push(b),
|
|
90
|
+
a
|
|
91
|
+
))
|
|
92
|
+
)
|
|
93
|
+
}
|
|
84
94
|
|
|
85
95
|
export default parse
|
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let t,e,l=l=>(t=0,e=l,l=s(),e[t]?r():l||""),r=(l="Bad syntax",r=e[t],a=e.slice(0,t).split("\n"),n=a.pop())=>{throw SyntaxError(`${l} ${r?`\`${r}\` `:""}at ${a.length}:${n.length}`,a.length)},a=(l="Bad syntax",r=e[t],a=e.slice(0,t).split("\n"),n=a.pop())=>{let s=e.slice(t-10,t).split("\n").pop(),h=e.slice(t+1,t+10).split("\n").shift(),p=a.length+":"+n.length;throw EvalError(`${l} at ${p} \`${s+r+h}\`\n${" ".repeat(18+l.length+p.length+s.length+1)}^`)},n=(l=1,r=t,a)=>{if("number"==typeof l)t+=l;else for(;a=l(e.charCodeAt(t));)t+=a;return e.slice(r,t)},s=(e=0,a,n,s,h,p)=>{for(;(n=l.space())&&(h=((p=i[n])&&p(s,e))??(!s&&l.id()));)s=h;return a&&(n==a?t++:r()),s},h=t=>t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122||36==t||95==t||t>=192&&215!=t&&247!=t,p=l.space=l=>{for(;(l=e.charCodeAt(t))<=32;)t++;return l},o=l.id=t=>n(h),i=[],c=(l,r=32,a,n=l.charCodeAt(0),s=l.length,p=i[n],o=l.toUpperCase()!==l)=>i[n]=(n,i,c=t)=>i<r&&(s<2||e.substr(t,s)==l)&&(!o||!h(e.charCodeAt(t+s)))&&(t+=s,a(n,i))||(t=c,p?.(n,i)),g=(t,e,l=0)=>c(t,e,((r,a)=>r&&(a=s(e-l/2))&&[t,r,a])),f=(t,e,l)=>c(t,e,(r=>l?r&&[t,r]:!r&&(r=s(e
|
|
1
|
+
let t,e,l=l=>(t=0,e=l,l=s(),e[t]?r():l||""),r=(l="Bad syntax",r=e[t],a=e.slice(0,t).split("\n"),n=a.pop())=>{throw SyntaxError(`${l} ${r?`\`${r}\` `:""}at ${a.length}:${n.length}`,a.length)},a=(l="Bad syntax",r=e[t],a=e.slice(0,t).split("\n"),n=a.pop())=>{let s=e.slice(t-10,t).split("\n").pop(),h=e.slice(t+1,t+10).split("\n").shift(),p=a.length+":"+n.length;throw EvalError(`${l} at ${p} \`${s+r+h}\`\n${" ".repeat(18+l.length+p.length+s.length+1)}^`)},n=(l=1,r=t,a)=>{if("number"==typeof l)t+=l;else for(;a=l(e.charCodeAt(t));)t+=a;return e.slice(r,t)},s=(e=0,a,n,s,h,p)=>{for(;(n=l.space())&&(h=((p=i[n])&&p(s,e))??(!s&&l.id()));)s=h;return a&&(n==a?t++:r()),s},h=t=>t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122||36==t||95==t||t>=192&&215!=t&&247!=t,p=l.space=l=>{for(;(l=e.charCodeAt(t))<=32;)t++;return l},o=l.id=t=>n(h),i=[],c=(l,r=32,a,n=l.charCodeAt(0),s=l.length,p=i[n],o=l.toUpperCase()!==l)=>i[n]=(n,i,c=t)=>i<r&&(s<2||e.substr(t,s)==l)&&(!o||!h(e.charCodeAt(t+s)))&&(t+=s,a(n,i))||(t=c,p?.(n,i)),g=(t,e,l=0)=>c(t,e,((r,a)=>r&&(a=s(e-l/2))&&[t,r,a])),f=(t,e,l)=>c(t,e,(r=>l?r&&[t,r]:!r&&(r=s(e-.5))&&[t,r])),d=(t,e,l)=>{c(t,e,((r,a)=>(r||l)&&((a=s(e))||l)&&((!r||r[0]!==t)&&(r=[t,r]),(a||l)&&r.push(a),r)))};const u=t=>Array.isArray(t)?$[t[0]](...t.slice(1)):e=>e?.[t],$={},A=(t,e,l=$[t])=>$[t]=(...t)=>e(...t)||l&&l(...t),y=t=>(t=l(t),e=>(t.call?t:t=u(t))(e)),C=(t,e,l)=>l[0]||l[1]?(e?c(t,e,l[0]):i[t.charCodeAt(0)||1]=l[0],A(t,l[1])):l.length?l.length>1?(g(t,Math.abs(e),e<0),A(t,((t,e)=>e&&(t=u(t),e=u(e),t.length||e.length?r=>l(t(r),e(r)):(t=l(t(),e()),()=>t))))):(f(t,e),A(t,((t,e)=>!e&&((t=u(t)).length?e=>l(t(e)):(t=l(t()),()=>t))))):(d(t,Math.abs(e),e<0),A(t,((...t)=>(t=t.map(u),e=>l(...t.map((t=>t(e)))))))),m=t=>t?r():["",(t=+n((t=>46===t||t>=48&&t<=57||(69===t||101===t?2:0))))!=t?r():t],b=(t,e,l,r)=>[t,e,[l=>l?["++"===t?"-":"+",[t,l],["",1]]:[t,s(e-1)],r=(t,e)=>"("===t[0]?r(t[1]):"."===t[0]?(e=t[2],t=u(t[1]),r=>l(t(r),e)):"["===t[0]?([,t,e]=t,t=u(t),e=u(e),r=>l(t(r),e(r))):e=>l(e,t)]],x=["",,[,t=>()=>t],'"',,[t=>t?r():["",(n()+n((t=>t-34?1:0))+(n()||r("Bad string"))).slice(1,-1)]],".",,[t=>!t&&m()],...Array(10).fill(0).flatMap(((t,e)=>[""+e,0,[m]])),",",1,(...t)=>t[t.length-1],"||",4,(...t)=>{let e,l=0;for(;!e&&l<t.length;)e=t[l++];return e},"&&",5,(...t)=>{let e=0,l=!0;for(;l&&e<t.length;)l=t[e++];return l},"+",12,(t,e)=>t+e,"-",12,(t,e)=>t-e,"*",13,(t,e)=>t*e,"/",13,(t,e)=>t/e,"%",13,(t,e)=>t%e,"|",6,(t,e)=>t|e,"&",8,(t,e)=>t&e,"^",7,(t,e)=>t^e,"==",9,(t,e)=>t==e,"!=",9,(t,e)=>t!=e,">",10,(t,e)=>t>e,">=",10,(t,e)=>t>=e,"<",10,(t,e)=>t<e,"<=",10,(t,e)=>t<=e,">>",11,(t,e)=>t>>e,">>>",11,(t,e)=>t>>>e,"<<",11,(t,e)=>t<<e,"+",15,t=>+t,"-",15,t=>-t,"!",15,t=>!t,...b("++",15,((t,e)=>++t[e])),...b("--",15,((t,e)=>--t[e])),"[",18,[t=>t&&["[",t,s(0,93)||r()],(t,e)=>e&&(t=u(t),e=u(e),l=>t(l)[e(l)])],".",18,[(t,e)=>t&&(e=s(18))&&[".",t,e],(t,e)=>(t=u(t),e=e[0]?e:e[1],l=>t(l)[e])],"(",18,[t=>!t&&["(",s(0,41)||r()],u],"(",18,[(t,e)=>t&&((e=s(0,41))?["(",t,e]:["(",t,""]),(t,e,l,r)=>null!=e&&(r=""==e?()=>[]:","===e[0]?(e=e.slice(1).map(u),t=>e.map((e=>e(t)))):(e=u(e),t=>[e(t)]),"."===t[0]?(l=t[2],t=u(t[1]),e=>t(e)[l](...r(e))):"["===t[0]?(l=u(t[2]),t=u(t[1]),e=>t(e)[l(e)](...r(e))):(t=u(t),e=>t(e)(...r(e))))]];for(;x[2];)C(...x.splice(0,3));export{g as binary,u as compile,e as cur,y as default,r as err,s as expr,o as id,t as idx,h as isId,a as longErr,i as lookup,d as nary,A as operator,$ as operators,l as parse,C as set,n as skip,p as space,c as token,f as unary};
|