subscript 6.1.0 → 6.4.0
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 +8 -3
- package/justin.js +1 -1
- package/justin.min.js +1 -1
- package/package.json +11 -6
- package/{index.js → parser.js} +6 -2
- package/subscript.js +11 -8
- package/subscript.min.js +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# <img alt="subscript" src="/subscript2.svg" height=28/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>--> <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> <a href="http://npmjs.org/subscript"><img src="https://img.shields.io/npm/v/subscript"/></a> <a href="http://microjs.com/#subscript"><img src="https://img.shields.io/badge/microjs-subscript-blue?color=darkslateblue"/></a>
|
|
2
2
|
|
|
3
|
-
_Subscript_ is expression evaluator with standard syntax<br/>
|
|
3
|
+
_Subscript_ is expression evaluator / microlanguage with standard syntax<br/>
|
|
4
4
|
|
|
5
5
|
* Any fragment can be copy-pasted to any language: C++, JS, Java, Python, Go, Rust etc.
|
|
6
6
|
* 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>
|
|
@@ -19,7 +19,7 @@ fn.args // ['a', 'c', 'd']
|
|
|
19
19
|
|
|
20
20
|
_Subscript_ is designed to be useful for:
|
|
21
21
|
|
|
22
|
-
* templates (perfect match with [template parts](https://github.com/github/template-parts))
|
|
22
|
+
* templates (perfect match with [template parts](https://github.com/github/template-parts), [templize](https://github.com/spectjs/templize))
|
|
23
23
|
* expressions evaluators, calculators
|
|
24
24
|
* configurable subsets of languages (eg. [justin](#justin)) <!-- see sonr, mineural -->
|
|
25
25
|
* pluggable/mock language features (eg. pipe operator)
|
|
@@ -317,16 +317,21 @@ math-parser: -
|
|
|
317
317
|
## Alternatives
|
|
318
318
|
|
|
319
319
|
* [jexpr](https://github.com/justinfagnani/jexpr)
|
|
320
|
+
* [jsep](https://github.com/EricSmekens/jsep)
|
|
320
321
|
* [jexl](https://github.com/TomFrost/Jexl)
|
|
321
322
|
* [mozjexl](https://github.com/mozilla/mozjexl)
|
|
322
323
|
* [expr-eval](https://github.com/silentmatt/expr-eval)
|
|
323
324
|
* [expression-eval](https://github.com/donmccurdy/expression-eval)
|
|
324
|
-
* [jsep](https://github.com/EricSmekens/jsep)
|
|
325
325
|
* [string-math](https://github.com/devrafalko/string-math)
|
|
326
326
|
* [nerdamer](https://github.com/jiggzson/nerdamer)
|
|
327
327
|
* [math-codegen](https://github.com/mauriciopoppe/math-codegen)
|
|
328
328
|
* [math-parser](https://www.npmjs.com/package/math-parser)
|
|
329
329
|
* [math.js](https://mathjs.org/docs/expressions/parsing.html)
|
|
330
|
+
|
|
331
|
+
## Next door
|
|
332
|
+
|
|
333
|
+
* [engine262](https://github.com/engine262/engine262)
|
|
330
334
|
* [Jessie](https://github.com/endojs/Jessie)
|
|
335
|
+
* [xst](https://github.com/Moddable-OpenSource/moddable-xst)
|
|
331
336
|
|
|
332
337
|
<p align=center>🕉</p>
|
package/justin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// justin lang https://github.com/endojs/Jessie/issues/66
|
|
2
|
-
import {set, lookup, skip, cur, idx, err, expr, isId, space, args} from './
|
|
2
|
+
import {set, lookup, skip, cur, idx, err, expr, isId, space, args} from './parser.js'
|
|
3
3
|
export { default } from './subscript.js'
|
|
4
4
|
|
|
5
5
|
const PERIOD=46, OPAREN=40, CPAREN=41, OBRACK=91, CBRACK=93, SPACE=32, DQUOTE=34, QUOTE=39, _0=48, _9=57, BSLASH=92,
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e,t,r,l,a,n,d,o=(l,a
|
|
1
|
+
let e,t,r,l,a,n,d,o=(l,a)=>(e=0,r=[],t=l.trim(),!(l=t?c():e=>{})||t[e]?f():a=e=>l(e||{}),a.args=r,a),i=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,f=(r="Bad syntax",l=t[e])=>{throw SyntaxError(r+" `"+l+"` at "+e)},p=(r=1,l=e,a)=>{if("number"==typeof r)e+=r;else for(;r(t.charCodeAt(e));)e++;return t.slice(l,e)},c=(t=0,r,l,a,n,d)=>{for(;(l=s())&&(n=(d=h[l])&&d(a,t)||!a&&u());)a=n;return r&&(l==r?e++:f()),a},s=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},u=(e=p(i),t)=>e?(t=t=>t[e],r.push(e),t.id=()=>e,t):0,h=[],g=o.set=(r,l,a=32,n=r.charCodeAt(0),d=r.length,o=h[n],f=a.length||([a,l]=[l,a],0),p=r.toUpperCase()!==r,s=(f>1?(e,t)=>e&&(t=c(l))&&(e.length||t.length?r=>a(e(r),t(r),e.id?.(r),t.id?.(r)):(e=a(e(),t()),()=>e)):f?e=>!e&&(e=c(l-1))&&(t=>a(e(t))):a))=>h[n]=(a,n,f=e)=>n<l&&(d<2||t.substr(e,d)==r)&&(!p||!i(t.charCodeAt(e+d)))&&(e+=d,s(a,n))||(e=f,o&&o(a,n)),x=e=>e>=48&&e<=57,C=r=>(r&&f("Unexpected number"),r=p((e=>46==e||x(e))),(69==t.charCodeAt(e)||101==t.charCodeAt(e))&&(r+=p(2)+p(x)),(r=+r)!=r?f("Bad number"):()=>r),A=(e,t)=>r=>t(e.of?e.of(r):r,e.id(r));for(a=48;a<=57;)h[a++]=C;for(l=['"',e=>(e=e?f("Unexpected string"):p((e=>e-34)),p()||f("Bad string"),()=>e),,".",(e,t)=>(s(),t=p(i)||f(),d=r=>e(r)[t],d.id=()=>t,d.of=e,d),18,".",e=>!e&&C(p(-1)),,"[",(e,t,r)=>e&&(t=c(0,93)||f(),(r=r=>e(r)[t(r)]).id=t,r.of=e,r),18,"(",(e,t,r)=>(t=c(0,41),e?r=>e(r).apply(e.of?.(r),t?t.all?t.all(r):[t(r)]:[]):t||f()),18,",",(e,t,r=c(1),l=(t=>(e(t),r(t))))=>(r?l.all=e.all?t=>[...e.all(t),r(t)]:t=>[e(t),r(t)]:f("Skipped argument"),l),1,"|",6,(e,t)=>e|t,"||",4,(e,t)=>e||t,"&",8,(e,t)=>e&t,"&&",5,(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,">>",11,(e,t)=>e>>t,">>>",11,(e,t)=>e>>>t,"<",10,(e,t)=>e<t,"<=",10,(e,t)=>e<=t,"<<",11,(e,t)=>e<<t,"+",12,(e,t)=>e+t,"+",15,e=>+e,"++",e=>A(e||c(14),e?(e,t)=>e[t]++:(e,t)=>++e[t]),15,"-",12,(e,t)=>e-t,"-",15,e=>-e,"--",e=>A(e||c(14),e?(e,t)=>e[t]--:(e,t)=>--e[t]),15,"!",15,e=>!e,"*",13,(e,t)=>e*t,"/",13,(e,t)=>e/t,"%",13,(e,t)=>e%t];[a,n,d,...l]=l,a;)g(a,n,d);let U,b,m,y,B={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},v=r=>(l,a,n="")=>{for(l&&f("Unexpected string");(a=t.charCodeAt(e))-r;)92===a?(p(),a=p(),n+=B[a]||a):n+=p();return p()||f("Bad string"),()=>n};for((U=['"',v(34),,"'",v(39),,"/*",(r,l)=>(p((r=>42!==r&&47!==t.charCodeAt(e+1))),p(2),r||c(l)),,"//",(e,t)=>(p((e=>e>=32)),e||c(t)),,"null",e=>e?f("Unexpected literal"):()=>null,,"true",e=>e?f("Unexpected literal"):()=>!0,,"false",e=>e?f("Unexpected literal"):()=>!1,,"undefined",e=>e?f("Unexpected literal"):()=>{},,";",e=>c()||(()=>{}),,"===",9,(e,t)=>e===t,"!==",9,(e,t)=>e!==t,"~",15,e=>~e,"**",(e,t,r=c(13))=>t=>e(t)**r(t),14,":",3.1,(e,t)=>[e,t],"?",3,(e,t)=>e?t[0]:t[1],"??",6,(e,t)=>e??t,"?.",e=>e&&(t=>e(t)||(()=>{})),,"?.",(e,t)=>(s(),(t=p(i))&&(r=>e(r)?.[t])),,"in",10,(e,t)=>e in t,"[",e=>!e&&((e=c(0,93))?e.all?t=>e.all(t):t=>[e(t)]:e=>[]),,"{",(e,t)=>!e&&((e=c(0,125))?r=>(t=(e.all||e)(r),Object.fromEntries(e.all?t:[t])):e=>({})),,":",(e,t,l)=>(l=c(1.1)||f(),e.id&&r.pop(),t=>[(e.id||e)(t),l(t)]),1.1]);[b,m,y,...U]=U,b;)g(b,m,y);export{o as default};
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subscript",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"description": "Fast and tiny expression evaluator with common syntax microlanguage.",
|
|
5
5
|
"main": "subscript.js",
|
|
6
|
+
"module": "subscript.js",
|
|
7
|
+
"browser": "subscript.js",
|
|
6
8
|
"type": "module",
|
|
7
9
|
"files": [
|
|
8
|
-
"
|
|
10
|
+
"parser.js",
|
|
9
11
|
"subscript.js",
|
|
10
12
|
"subscript.min.js",
|
|
11
13
|
"justin.js",
|
|
@@ -17,11 +19,13 @@
|
|
|
17
19
|
"test": "test"
|
|
18
20
|
},
|
|
19
21
|
"scripts": {
|
|
20
|
-
"build": "
|
|
21
|
-
"minify": "
|
|
22
|
+
"build": "npm run build-subscript && npm run build-justin",
|
|
23
|
+
"minify": "npm run minify-subscript && npm run minify-justin",
|
|
24
|
+
"build-subscript": "rollup subscript.js --file subscript.min.js --format esm --name \"Subscript\"",
|
|
25
|
+
"minify-subscript": "terser subscript.min.js -o subscript.min.js --module -c passes=3 -m",
|
|
22
26
|
"build-justin": "rollup justin.js --file justin.min.js --format esm --name \"Justin\"",
|
|
23
27
|
"minify-justin": "terser justin.min.js -o justin.min.js --module -c passes=3 -m",
|
|
24
|
-
"test": "node test"
|
|
28
|
+
"test": "node test && node test/jsep && node test/perf"
|
|
25
29
|
},
|
|
26
30
|
"repository": {
|
|
27
31
|
"type": "git",
|
|
@@ -65,6 +69,7 @@
|
|
|
65
69
|
"homepage": "https://github.com/spectjs/subscript#readme",
|
|
66
70
|
"devDependencies": {
|
|
67
71
|
"rollup": "^2.60.2",
|
|
68
|
-
"terser": "^5.10.0"
|
|
72
|
+
"terser": "^5.10.0",
|
|
73
|
+
"tst": "^7.1.0"
|
|
69
74
|
}
|
|
70
75
|
}
|
package/{index.js → parser.js}
RENAMED
|
@@ -4,7 +4,11 @@ const SPACE=32, CPAREN=41
|
|
|
4
4
|
export let idx, cur, args,
|
|
5
5
|
|
|
6
6
|
// no handling tagged literals since easily done on user side with cache, if needed
|
|
7
|
-
parse = (s, fn
|
|
7
|
+
parse = (s, fn) => (
|
|
8
|
+
idx=0, args=[], cur=s.trim(),
|
|
9
|
+
!(s = cur ? expr() : ctx=>{}) || cur[idx] ? err() :
|
|
10
|
+
fn = ctx=>s(ctx||{}), fn.args = args, fn
|
|
11
|
+
),
|
|
8
12
|
|
|
9
13
|
isId = c =>
|
|
10
14
|
(c >= 48 && c <= 57) || // 0..9
|
|
@@ -63,7 +67,7 @@ set = parse.set = (
|
|
|
63
67
|
// binary
|
|
64
68
|
arity>1 ? (a,b) => a && (b=expr(opPrec)) && (
|
|
65
69
|
!a.length && !b.length ? (a=fn(a(),b()), ()=>a) : // static pre-eval like `"a"+"b"`
|
|
66
|
-
ctx => fn(a(ctx),b(ctx))
|
|
70
|
+
ctx => fn(a(ctx),b(ctx),a.id?.(ctx),b.id?.(ctx))
|
|
67
71
|
) :
|
|
68
72
|
// unary prefix (0 args)
|
|
69
73
|
arity ? a => !a && (a=expr(opPrec-1)) && (ctx => fn(a(ctx))) :
|
package/subscript.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {parse, set, lookup, skip, cur, idx, err, expr, isId, args, space} from './
|
|
1
|
+
import {parse, set, lookup, skip, cur, idx, err, expr, isId, args, space} from './parser.js'
|
|
2
2
|
|
|
3
3
|
const PERIOD=46, OPAREN=40, CPAREN=41, OBRACK=91, CBRACK=93, SPACE=32, DQUOTE=34, _0=48, _9=57,
|
|
4
4
|
PREC_SEQ=1, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
|
|
@@ -14,7 +14,7 @@ let u, list, op, prec, fn,
|
|
|
14
14
|
n=+n, n!=n ? err('Bad number') : () => n // 0 args means token is static
|
|
15
15
|
),
|
|
16
16
|
|
|
17
|
-
inc = (a,fn
|
|
17
|
+
inc = (a,fn) => ctx => fn(a.of?a.of(ctx):ctx, a.id(ctx))
|
|
18
18
|
|
|
19
19
|
// numbers
|
|
20
20
|
for (op=_0;op<=_9;) lookup[op++] = num
|
|
@@ -24,9 +24,12 @@ for (list=[
|
|
|
24
24
|
// "a"
|
|
25
25
|
'"', a => (a=a?err('Unexpected string'):skip(c => c-DQUOTE), skip()||err('Bad string'), ()=>a),,
|
|
26
26
|
|
|
27
|
-
// a.b
|
|
28
|
-
'.', (a,id
|
|
29
|
-
|
|
27
|
+
// a.b
|
|
28
|
+
'.', (a,id) => (space(), id=skip(isId)||err(), fn=ctx=>a(ctx)[id], fn.id=()=>id, fn.of=a, fn), PREC_CALL,
|
|
29
|
+
|
|
30
|
+
// .2
|
|
31
|
+
// FIXME: .123 is not operator, so we skip back, but mb reorganizing num would be better
|
|
32
|
+
'.', a => !a && num(skip(-1)),,
|
|
30
33
|
|
|
31
34
|
// a[b]
|
|
32
35
|
'[', (a,b,fn) => a && (b=expr(0,CBRACK)||err(), fn=ctx=>a(ctx)[b(ctx)], fn.id=b, fn.of=a, fn), PREC_CALL,
|
|
@@ -41,9 +44,9 @@ for (list=[
|
|
|
41
44
|
), PREC_CALL,
|
|
42
45
|
|
|
43
46
|
// [a,b,c] or (a,b,c)
|
|
44
|
-
',', (a,prec,b=expr(PREC_SEQ)) => (
|
|
45
|
-
b.all = a.all ? ctx => [...a.all(ctx),
|
|
46
|
-
|
|
47
|
+
',', (a,prec,b=expr(PREC_SEQ),fn=ctx => (a(ctx), b(ctx))) => (
|
|
48
|
+
b ? (fn.all = a.all ? ctx => [...a.all(ctx),b(ctx)] : ctx => [a(ctx),b(ctx)]) : err('Skipped argument',),
|
|
49
|
+
fn
|
|
47
50
|
), PREC_SEQ,
|
|
48
51
|
|
|
49
52
|
'|', PREC_OR, (a,b)=>a|b,
|
package/subscript.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e,r,t,a,o,l,
|
|
1
|
+
let e,r,t,a,o,d,l,n=(a,o)=>(e=0,t=[],r=a.trim(),!(a=r?s():e=>{})||r[e]?h():o=e=>a(e||{}),o.args=t,o),f=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,h=(t="Bad syntax",a=r[e])=>{throw SyntaxError(t+" `"+a+"` at "+e)},i=(t=1,a=e,o)=>{if("number"==typeof t)e+=t;else for(;t(r.charCodeAt(e));)e++;return r.slice(a,e)},s=(r=0,t,a,o,d,l)=>{for(;(a=p())&&(d=(l=c[a])&&l(o,r)||!o&&u());)o=d;return t&&(a==t?e++:h()),o},p=t=>{for(;(t=r.charCodeAt(e))<=32;)e++;return t},u=(e=i(f),r)=>e?(r=r=>r[e],t.push(e),r.id=()=>e,r):0,c=[],g=n.set=(t,a,o=32,d=t.charCodeAt(0),l=t.length,n=c[d],h=o.length||([o,a]=[a,o],0),i=t.toUpperCase()!==t,p=(h>1?(e,r)=>e&&(r=s(a))&&(e.length||r.length?t=>o(e(t),r(t),e.id?.(t),r.id?.(t)):(e=o(e(),r()),()=>e)):h?e=>!e&&(e=s(a-1))&&(r=>o(e(r))):o))=>c[d]=(o,d,h=e)=>d<a&&(l<2||r.substr(e,l)==t)&&(!i||!f(r.charCodeAt(e+l)))&&(e+=l,p(o,d))||(e=h,n&&n(o,d)),C=e=>e>=48&&e<=57,A=t=>(t&&h("Unexpected number"),t=i((e=>46==e||C(e))),(69==r.charCodeAt(e)||101==r.charCodeAt(e))&&(t+=i(2)+i(C)),(t=+t)!=t?h("Bad number"):()=>t),m=(e,r)=>t=>r(e.of?e.of(t):t,e.id(t));for(o=48;o<=57;)c[o++]=A;for(a=['"',e=>(e=e?h("Unexpected string"):i((e=>e-34)),i()||h("Bad string"),()=>e),,".",(e,r)=>(p(),r=i(f)||h(),l=t=>e(t)[r],l.id=()=>r,l.of=e,l),18,".",e=>!e&&A(i(-1)),,"[",(e,r,t)=>e&&(r=s(0,93)||h(),(t=t=>e(t)[r(t)]).id=r,t.of=e,t),18,"(",(e,r,t)=>(r=s(0,41),e?t=>e(t).apply(e.of?.(t),r?r.all?r.all(t):[r(t)]:[]):r||h()),18,",",(e,r,t=s(1),a=(r=>(e(r),t(r))))=>(t?a.all=e.all?r=>[...e.all(r),t(r)]:r=>[e(r),t(r)]:h("Skipped argument"),a),1,"|",6,(e,r)=>e|r,"||",4,(e,r)=>e||r,"&",8,(e,r)=>e&r,"&&",5,(e,r)=>e&&r,"^",7,(e,r)=>e^r,"==",9,(e,r)=>e==r,"!=",9,(e,r)=>e!=r,">",10,(e,r)=>e>r,">=",10,(e,r)=>e>=r,">>",11,(e,r)=>e>>r,">>>",11,(e,r)=>e>>>r,"<",10,(e,r)=>e<r,"<=",10,(e,r)=>e<=r,"<<",11,(e,r)=>e<<r,"+",12,(e,r)=>e+r,"+",15,e=>+e,"++",e=>m(e||s(14),e?(e,r)=>e[r]++:(e,r)=>++e[r]),15,"-",12,(e,r)=>e-r,"-",15,e=>-e,"--",e=>m(e||s(14),e?(e,r)=>e[r]--:(e,r)=>--e[r]),15,"!",15,e=>!e,"*",13,(e,r)=>e*r,"/",13,(e,r)=>e/r,"%",13,(e,r)=>e%r];[o,d,l,...a]=a,o;)g(o,d,l);export{n as default};
|