subscript 7.0.3 → 7.0.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 -4
- package/justin.min.js +1 -1
- package/package.json +1 -1
- package/parse.js +8 -4
- package/subscript.js +1 -1
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
_Subscript_ is expression evaluator / microlanguage with [common syntax](https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)).<br/>
|
|
4
4
|
|
|
5
|
-
* Any fragment can be copy-pasted to any language: C++, JS, Java, Python, Go, Rust etc.
|
|
6
5
|
* Tiny size <sub><a href="https://bundlephobia.com/package/subscript@6.0.0"><img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/subscript/latest?color=brightgreen&label=gzip"/></a></sub>
|
|
7
6
|
* :rocket: Fast [performance](#performance)
|
|
8
7
|
* Configurable & extensible
|
|
@@ -16,7 +15,7 @@ let fn = script('a.b + c(d - 1)')
|
|
|
16
15
|
fn({ a: { b:1 }, c: x => x * 2, d: 3 }) // 5
|
|
17
16
|
|
|
18
17
|
// or
|
|
19
|
-
// parse expression
|
|
18
|
+
// parse expression
|
|
20
19
|
let tree = parse('a.b + c')
|
|
21
20
|
tree // ['+', ['.', 'a', 'b'], 'c']
|
|
22
21
|
|
|
@@ -92,7 +91,7 @@ AST has simplified lispy calltree structure (inspired by [frisk](https://ghub.io
|
|
|
92
91
|
|
|
93
92
|
* is not limited to particular language, can be cross-compiled;
|
|
94
93
|
* reflects execution sequence, rather than code layout;
|
|
95
|
-
* has minimal possible overhead,
|
|
94
|
+
* has minimal possible overhead, directly maps to operators;
|
|
96
95
|
* simplifies manual evaluation and debugging;
|
|
97
96
|
* has conventional form and one-liner docs:
|
|
98
97
|
|
|
@@ -365,4 +364,4 @@ math-parser: -
|
|
|
365
364
|
* [Jessie](https://github.com/endojs/Jessie)
|
|
366
365
|
* [xst](https://github.com/Moddable-OpenSource/moddable-xst)
|
|
367
366
|
|
|
368
|
-
<p align=center>🕉</p>
|
|
367
|
+
<p align=center><a href="https://github.com/krsnzd/license/">🕉</a></p>
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e,r
|
|
1
|
+
let e,t,r=r=>(e=0,t=r,r=a(),t[e]?l():r||""),l=(r="Bad syntax",l=t[e],n=t.slice(0,e).split("\n"),a=n.pop())=>{throw SyntaxError(`${r} \`${a.slice(-10)}${l}\` at ${n.length}:${a.length}`)},n=(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)},a=(t=0,r,n,a,o,c)=>{for(;(n=s())&&(o=((c=i[n])&&c(a,t))??(!a&&i[0]()));)a=o;return r&&(n==r?e++:l()),a},s=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},o=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,i=[e=>n(o)];r.set=(r,l=32,n,a=r.charCodeAt(0),s=r.length,c=i[a],p=r.toUpperCase()!==r)=>i[a]=(a,i,f=e)=>i<l&&(s<2||t.substr(e,s)==r)&&(!p||!o(t.charCodeAt(e+s)))&&(e+=s,n(a,i))||(e=f,c?.(a,i));const c=e=>Array.isArray(e)?p[e[0]](...e.slice(1)):t=>t?.[e];c.set=(e,t,r=p[e])=>p[e]=(...e)=>t(...e)||r&&r(...e);const p={},f=e=>(e=r(e),t=>(e.call?e:e=c(e))(t)),h=f.set=(e,t,l,n=t<0,s=l[0],o=l[1],p=!s&&l.length)=>(s||=p?p>1?(r,l)=>r&&(l=a(t-n))&&[e,r,l]:r=>!r&&(r=a(t-1))&&[e,r]:(r,l)=>r&&(l=a(t))&&(r[0]===e&&r[2]?(r.push(l),r):[e,r,l]),o||=p?p>1?(e,t)=>t&&(e=c(e),t=c(t),e.length||t.length?r=>l(e(r),t(r)):(e=l(e(),t()),()=>e)):(e,t)=>!t&&((e=c(e)).length?t=>l(e(t)):(e=l(e()),()=>e)):(...e)=>(e=e.map(c),t=>l(...e.map((e=>e(t))))),(t=n?-t:t)?r.set(e,t,s):i[e.charCodeAt(0)||1]=s,c.set(e,o)),d=e=>e?l():["",(e=+n((e=>46===e||e>=48&&e<=57||(69===e||101===e?2:0))))!=e?l():e],u=(e,t,r,l)=>[e,t,[r=>r?["++"===e?"-":"+",[e,r],["",1]]:[e,a(t-1)],l=(e,t)=>"("===e[0]?l(e[1]):"."===e[0]?(t=e[2],e=c(e[1]),l=>r(e(l),t)):"["===e[0]?([,e,t]=e,e=c(e),t=c(t),l=>r(e(l),t(l))):t=>r(t,e)]],g=["",,[,e=>()=>e],'"',,[e=>e?l():["",(n()+n((e=>e-34?1:0))+(n()||l("Bad string"))).slice(1,-1)]],".",,[e=>!e&&d()],...Array(10).fill(0).flatMap(((e,t)=>[""+t,0,[d]])),",",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,...u("++",15,((e,t)=>++e[t])),...u("--",15,((e,t)=>--e[t])),"[",18,[e=>e&&["[",e,a(0,93)||l()],(e,t)=>t&&(e=c(e),t=c(t),r=>e(r)[t(r)])],".",18,[(e,t)=>e&&(t=a(18))&&[".",e,t],(e,t)=>(e=c(e),t=t[0]?t:t[1],r=>e(r)[t])],"(",18,[e=>!e&&["(",a(0,41)||l()],c],"(",18,[e=>e&&["(",e,a(0,41)||""],(e,t,r,l)=>null!=t&&(l=""==t?()=>[]:","===t[0]?(t=t.slice(1).map(c),e=>t.map((t=>t(e)))):(t=c(t),e=>[t(e)]),"."===e[0]?(r=e[2],e=c(e[1]),t=>e(t)[r](...l(t))):"["===e[0]?(r=c(e[2]),e=c(e[1]),t=>e(t)[r(t)](...l(t))):(e=c(e),t=>e(t)(...l(t))))]];for(;g[2];)h(...g.splice(0,3));let m={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},A=r=>(a,s,o="")=>{for(a&&l("Unexpected string"),n();(s=t.charCodeAt(e))-r;)92===s?(n(),s=n(),o+=m[s]||s):o+=n();return n(),["",o]},y=["===",9,(e,t)=>e===t,"!==",9,(e,t)=>e!==t,"~",15,e=>~e,"?",3,[(e,t,r)=>e&&(t=a(2,58))&&["?",e,t,a(3)],(e,t,r)=>(e=c(e),t=c(t),r=c(r),l=>e(l)?t(l):r(l))],"??",6,(e,t)=>e??t,"?.",18,[e=>e&&["?.",e],e=>(e=c(e),t=>e(t)||(()=>{}))],"?.",18,[(e,t)=>e&&!(t=a(18))?.map&&["?.",e,t],(e,t)=>t&&(e=c(e),r=>e(r)?.[t])],"in",10,(e,t)=>e in t,'"',,[A(34)],"'",,[A(39)],"/*",20,[(r,l)=>(n((r=>42!==r&&47!==t.charCodeAt(e+1))),n(2),r||a(l))],"//",20,[(e,t)=>(n((e=>e>=32)),e||a(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=>a()||[""]],"**",-14,(e,t)=>e**t,"[",20,[e=>!e&&["[",a(0,93)||""],(e,t)=>!t&&(e?","===e[0]?(e=e.slice(1).map(c),t=>e.map((e=>e(t)))):(e=c(e),t=>[e(t)]):()=>[])],"{",20,[e=>!e&&["{",a(0,125)||""],(e,t)=>e?","===e[0]?(e=e.slice(1).map(c),t=>Object.fromEntries(e.map((e=>e(t))))):":"===e[0]?(e=c(e),t=>Object.fromEntries([e(t)])):(t=c(e),r=>({[e]:t(r)})):e=>({})],":",1.1,[(e,t)=>[":",e,a(1.1)||l()],(e,t)=>(t=c(t),e=Array.isArray(e)?c(e):(e=>e).bind(0,e),r=>[e(r),t(r)])]];for(;y[2];)f.set(...y.splice(0,3));export{c as compile,f as default,r as parse};
|
package/package.json
CHANGED
package/parse.js
CHANGED
|
@@ -6,7 +6,11 @@ export let idx, cur,
|
|
|
6
6
|
// no handling tagged literals since easily done on user side with cache, if needed
|
|
7
7
|
parse = s => (idx=0, cur=s, s = expr(), cur[idx] ? err() : s || ''),
|
|
8
8
|
|
|
9
|
-
err = (msg='Bad syntax',c=cur[idx]) => { throw SyntaxError(msg + ' `' + c + '` at ' + idx) },
|
|
9
|
+
// err = (msg='Bad syntax',c=cur[idx]) => { throw SyntaxError(msg + ' `' + c + '` at ' + idx) },
|
|
10
|
+
|
|
11
|
+
err = (msg='Bad syntax',frag=cur.slice(idx-10,idx+1),prev=cur.slice(0,idx).split('\n'),last=prev.pop()) => {
|
|
12
|
+
throw SyntaxError(`${msg} \`${frag}\` at ${prev.length}:${last.length}`)
|
|
13
|
+
},
|
|
10
14
|
|
|
11
15
|
skip = (is=1, from=idx, l) => {
|
|
12
16
|
if (typeof is == 'number') idx += is
|
|
@@ -23,7 +27,7 @@ expr = (prec=0, end, cc, token, newNode, fn) => {
|
|
|
23
27
|
// FIXME: extra work is happening here, when lookup bails out due to lower precedence -
|
|
24
28
|
// it makes extra `space` call for parent exprs on the same character to check precedence again
|
|
25
29
|
(newNode =
|
|
26
|
-
(fn=lookup[cc]) && fn(token, prec)
|
|
30
|
+
((fn=lookup[cc]) && fn(token, prec)) ?? // if operator with higher precedence isn't found
|
|
27
31
|
(!token && lookup[0]()) // parse literal or quit. token seqs are forbidden: `a b`, `a "b"`, `1.32 a`
|
|
28
32
|
)
|
|
29
33
|
) token = newNode;
|
|
@@ -59,7 +63,7 @@ set = parse.set = (
|
|
|
59
63
|
prev=lookup[c],
|
|
60
64
|
word=op.toUpperCase()!==op // make sure word boundary comes after word operator
|
|
61
65
|
) => lookup[c] = (a, curPrec, from=idx) =>
|
|
62
|
-
curPrec<prec && (l<2||cur.substr(idx,l)==op) && (!word||!isId(cur.charCodeAt(idx+l))) && (idx+=l, map(a, curPrec)) ||
|
|
63
|
-
(idx=from, prev
|
|
66
|
+
(curPrec<prec && (l<2||cur.substr(idx,l)==op) && (!word||!isId(cur.charCodeAt(idx+l))) && (idx+=l, map(a, curPrec))) ||
|
|
67
|
+
(idx=from, prev?.(a, curPrec))
|
|
64
68
|
|
|
65
69
|
export default parse
|
package/subscript.js
CHANGED
|
@@ -24,8 +24,8 @@ set = subscript.set = (op, prec, fn, right=prec<0, parseFn=fn[0], evalFn=fn[1],
|
|
|
24
24
|
compile.set(op, evalFn)
|
|
25
25
|
),
|
|
26
26
|
|
|
27
|
-
// create increment-assign pair from fn
|
|
28
27
|
num = a => a ? err() : ['', (a=+skip(c => c === PERIOD || (c>=_0 && c<=_9) || (c===69||c===101?2:0)))!=a?err():a],
|
|
28
|
+
// create increment-assign pair from fn
|
|
29
29
|
inc = (op, prec, fn, ev) => [op, prec, [
|
|
30
30
|
a => a ? [op==='++'?'-':'+',[op,a],['',1]] : [op,expr(prec-1)], // ++a → [++, a], a++ → [-,[++,a],1]
|
|
31
31
|
ev = (a,b) => (
|
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e,t,r=r=>(e=0,t=r,r=
|
|
1
|
+
let e,t,r=r=>(e=0,t=r,r=a(),t[e]?l():r||""),l=(r="Bad syntax",l=t[e],s=t.slice(0,e).split("\n"),a=s.pop())=>{throw SyntaxError(`${r} \`${a.slice(-10)}${l}\` at ${s.length}:${a.length}`)},s=(r=1,l=e,s)=>{if("number"==typeof r)e+=r;else for(;s=r(t.charCodeAt(e));)e+=s;return t.slice(l,e)},a=(t=0,r,s,a,o,c)=>{for(;(s=n())&&(o=((c=h[s])&&c(a,t))??(!a&&h[0]()));)a=o;return r&&(s==r?e++:l()),a},n=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},o=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,h=[e=>s(o)];r.set=(r,l=32,s,a=r.charCodeAt(0),n=r.length,c=h[a],p=r.toUpperCase()!==r)=>h[a]=(a,h,i=e)=>h<l&&(n<2||t.substr(e,n)==r)&&(!p||!o(t.charCodeAt(e+n)))&&(e+=n,s(a,h))||(e=i,c?.(a,h));const c=e=>Array.isArray(e)?p[e[0]](...e.slice(1)):t=>t?.[e];c.set=(e,t,r=p[e])=>p[e]=(...e)=>t(...e)||r&&r(...e);const p={},i=e=>(e=r(e),t=>(e.call?e:e=c(e))(t)),f=i.set=(e,t,l,s=t<0,n=l[0],o=l[1],p=!n&&l.length)=>(n||=p?p>1?(r,l)=>r&&(l=a(t-s))&&[e,r,l]:r=>!r&&(r=a(t-1))&&[e,r]:(r,l)=>r&&(l=a(t))&&(r[0]===e&&r[2]?(r.push(l),r):[e,r,l]),o||=p?p>1?(e,t)=>t&&(e=c(e),t=c(t),e.length||t.length?r=>l(e(r),t(r)):(e=l(e(),t()),()=>e)):(e,t)=>!t&&((e=c(e)).length?t=>l(e(t)):(e=l(e()),()=>e)):(...e)=>(e=e.map(c),t=>l(...e.map((e=>e(t))))),(t=s?-t:t)?r.set(e,t,n):h[e.charCodeAt(0)||1]=n,c.set(e,o)),g=e=>e?l():["",(e=+s((e=>46===e||e>=48&&e<=57||(69===e||101===e?2:0))))!=e?l():e],u=(e,t,r,l)=>[e,t,[r=>r?["++"===e?"-":"+",[e,r],["",1]]:[e,a(t-1)],l=(e,t)=>"("===e[0]?l(e[1]):"."===e[0]?(t=e[2],e=c(e[1]),l=>r(e(l),t)):"["===e[0]?([,e,t]=e,e=c(e),t=c(t),l=>r(e(l),t(l))):t=>r(t,e)]],d=["",,[,e=>()=>e],'"',,[e=>e?l():["",(s()+s((e=>e-34?1:0))+(s()||l("Bad string"))).slice(1,-1)]],".",,[e=>!e&&g()],...Array(10).fill(0).flatMap(((e,t)=>[""+t,0,[g]])),",",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,...u("++",15,((e,t)=>++e[t])),...u("--",15,((e,t)=>--e[t])),"[",18,[e=>e&&["[",e,a(0,93)||l()],(e,t)=>t&&(e=c(e),t=c(t),r=>e(r)[t(r)])],".",18,[(e,t)=>e&&(t=a(18))&&[".",e,t],(e,t)=>(e=c(e),t=t[0]?t:t[1],r=>e(r)[t])],"(",18,[e=>!e&&["(",a(0,41)||l()],c],"(",18,[e=>e&&["(",e,a(0,41)||""],(e,t,r,l)=>null!=t&&(l=""==t?()=>[]:","===t[0]?(t=t.slice(1).map(c),e=>t.map((t=>t(e)))):(t=c(t),e=>[t(e)]),"."===e[0]?(r=e[2],e=c(e[1]),t=>e(t)[r](...l(t))):"["===e[0]?(r=c(e[2]),e=c(e[1]),t=>e(t)[r(t)](...l(t))):(e=c(e),t=>e(t)(...l(t))))]];for(;d[2];)f(...d.splice(0,3));export{c as compile,i as default,r as parse};
|