subscript 6.0.2 → 6.2.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 CHANGED
@@ -1,21 +1,18 @@
1
- # <img alt="subscript" src="/subscript2.svg" height=42/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
2
- <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>
3
- <a href="http://npmjs.org/subscript"><img src="https://img.shields.io/npm/v/subscript?color=indianred"/></a>
4
- <a href="http://microjs.com/#subscript"><img src="https://img.shields.io/badge/microjs-subscript-blue?color=darkslateblue"/></a>
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>
5
2
 
6
- _Subscript_ is micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust etc.<br/>
3
+ _Subscript_ is expression evaluator / microlanguage with standard syntax<br/>
7
4
 
8
- * Standard conventional syntax
9
- * Any fragment can be copy-pasted to any target language
5
+ * Any fragment can be copy-pasted to any language: C++, JS, Java, Python, Go, Rust etc.
10
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>
11
7
  * :rocket: Fast [performance](#performance)
12
8
  * Configurable & extensible
13
9
  * Trivial to use
14
10
 
15
11
  ```js
16
- import script from 'subscript.js'
12
+ import script from './subscript.js'
17
13
  let fn = script`a.b + c(d - 1)`
18
14
  fn({ a: { b:1 }, c: x => x * 2, d: 3 }) // 5
15
+ fn.args // ['a', 'c', 'd']
19
16
  ```
20
17
 
21
18
  ## Motivation
@@ -37,19 +34,20 @@ _Subscript_ has [2kb](https://npmfs.com/package/subscript/6.0.0/subscript.min.js
37
34
  Default operators are (same as JS precedence order):
38
35
 
39
36
  * `( a, b, c )`
40
- * `a . b`, `a [ b ]`, `a ( b, c )`
37
+ * `a.b`, `a[b]`, `a(b, c)`
41
38
  * `a++`, `a--` unary postfix
42
39
  * `!a`, `+a`, `-a`, `++a`, `--a` unary prefix
43
40
  * `a * b`, `a / b`, `a % b`
44
41
  * `a + b`, `a - b`
45
- * `a << b`, `a >>b`, `a >>>b`
46
- * `a < b`, `a <= b`, `a >b`, `a >=b`
42
+ * `a << b`, `a >> b`, `a >>> b`
43
+ * `a < b`, `a <= b`, `a > b`, `a >= b`
47
44
  * `a == b`, `a != b`
48
45
  * `a & b`
49
46
  * `a ^ b`
50
47
  * `a | b`
51
48
  * `a && b`
52
49
  * `a || b`
50
+ * `a , b`
53
51
 
54
52
  Default literals:
55
53
 
@@ -58,8 +56,8 @@ Default literals:
58
56
 
59
57
  Everything else can be extended via `parse.set(token, precedence, operator)` for unary or binary operators (detected by number of arguments in `operator`), or via `parse.set(token, parse, precedence)` for custom tokens.
60
58
 
61
- ```
62
- import script from 'subscript.js'
59
+ ```js
60
+ import script from './subscript.js'
63
61
 
64
62
  // add ~ unary operator with precedence 15
65
63
  script.set('~', 15, a => ~a)
@@ -123,6 +121,7 @@ It extends _subscript_ with:
123
121
  + `'` strings
124
122
  + `?:` ternary operator
125
123
  + `?.` optional chain operator
124
+ + `??` nullish coalesce operator
126
125
  + `[...]` Array literal
127
126
  + `{...}` Object literal
128
127
  + `in` binary
@@ -287,12 +286,14 @@ Subscript shows relatively good performance within other evaluators:
287
286
  Parse 30k times:
288
287
 
289
288
  ```
290
- subscript: ~170 ms
291
- justin: ~183 ms
292
- jsep: ~270 ms
289
+ subscript: ~170 ms 🥇
290
+ justin: ~183 ms 🥈
291
+ jsep: ~270 ms 🥉
292
+ jexpr: ~297 ms
293
293
  mr-parser: ~420 ms
294
294
  expr-eval: ~480 ms
295
295
  math-parser: ~570 ms
296
+ math-expression-evaluator: ~900ms
296
297
  jexl: ~1056 ms
297
298
  mathjs: ~1200 ms
298
299
  new Function: ~1154 ms
@@ -300,19 +301,22 @@ new Function: ~1154 ms
300
301
 
301
302
  Eval 30k times:
302
303
  ```
303
- subscript: ~17 ms
304
- justin: ~17 ms
304
+ new Function: ~7 ms 🥇
305
+ subscript: ~17 ms 🥈
306
+ justin: ~17 ms 🥈
307
+ jexpr: ~23 ms 🥉
305
308
  jsep (expression-eval): ~30 ms
306
- mr-parser: -
309
+ math-expression-evaluator: ~50ms
307
310
  expr-eval: ~72 ms
308
- math-parser: -
309
311
  jexl: ~110 ms
310
312
  mathjs: ~119 ms
311
- new Function: ~7 ms
313
+ mr-parser: -
314
+ math-parser: -
312
315
  ```
313
316
 
314
317
  ## Alternatives
315
318
 
319
+ * [jexpr](https://github.com/justinfagnani/jexpr)
316
320
  * [jexl](https://github.com/TomFrost/Jexl)
317
321
  * [mozjexl](https://github.com/mozilla/mozjexl)
318
322
  * [expr-eval](https://github.com/silentmatt/expr-eval)
package/index.js CHANGED
@@ -1,9 +1,10 @@
1
- const SPACE=32
1
+ const SPACE=32, CPAREN=41
2
2
 
3
- // current string & index
4
- export let idx, cur,
3
+ // current string, index and collected ids
4
+ export let idx, cur, args,
5
5
 
6
- parse = (s, ...fields) => !(cur=s.raw ? String.raw(s,...fields) : s, idx=0, s=expr()) || cur[idx] ? err('Unexpected end') : ctx=>s(ctx||{}),
6
+ // no handling tagged literals since easily done on user side with cache, if needed
7
+ parse = (s, fn= !(cur=s, idx=0, args=[], s=expr()) || cur[idx] ? err() : ctx=>s(ctx||{})) => (fn.args = args, fn),
7
8
 
8
9
  isId = c =>
9
10
  (c >= 48 && c <= 57) || // 0..9
@@ -12,7 +13,7 @@ isId = c =>
12
13
  c == 36 || c == 95 || // $, _,
13
14
  (c >= 192 && c != 215 && c != 247), // any non-ASCII
14
15
 
15
- err = (msg='Unexpected token',c=cur[idx]) => { throw SyntaxError(msg + ' `' + c + '` at ' + idx) },
16
+ err = (msg='Bad syntax',c=cur[idx]) => { throw SyntaxError(msg + ' `' + c + '` at ' + idx) },
16
17
 
17
18
  skip = (is=1, from=idx, l) => {
18
19
  if (typeof is == 'number') idx += is
@@ -34,7 +35,8 @@ expr = (prec=0, end, cc, token, newNode, fn) => {
34
35
  ) token = newNode;
35
36
 
36
37
  // check end character
37
- if (end) cc==end?idx++:err('Missing', String.fromCharCode(end))
38
+ // FIXME: can't show "Unclose paren", because can be unknown operator within group as well
39
+ if (end) cc==end?idx++:err()
38
40
 
39
41
  return token
40
42
  },
@@ -43,7 +45,7 @@ expr = (prec=0, end, cc, token, newNode, fn) => {
43
45
  space = cc => { while ((cc = cur.charCodeAt(idx)) <= SPACE) idx++; return cc },
44
46
 
45
47
  // variable identifier
46
- id = (name=skip(isId), fn) => name ? (fn=ctx => ctx[name], fn.id=()=>name, fn) : 0,
48
+ id = (name=skip(isId), fn) => name ? (fn=ctx => ctx[name], args.push(name), fn.id=()=>name, fn) : 0,
47
49
 
48
50
  // operator/token lookup table
49
51
  lookup = [],
@@ -61,11 +63,10 @@ set = parse.set = (
61
63
  // binary
62
64
  arity>1 ? (a,b) => a && (b=expr(opPrec)) && (
63
65
  !a.length && !b.length ? (a=fn(a(),b()), ()=>a) : // static pre-eval like `"a"+"b"`
64
- ctx => fn(a(ctx),b(ctx))
66
+ ctx => fn(a(ctx),b(ctx),a.id?.(ctx),b.id?.(ctx))
65
67
  ) :
66
68
  // unary prefix (0 args)
67
69
  arity ? a => !a && (a=expr(opPrec-1)) && (ctx => fn(a(ctx))) :
68
70
  fn // custom parser
69
71
  ) =>
70
- // FIXME: find out if that's possible to globalize precision and instead of passing it to map, just provide global
71
72
  lookup[c] = (a, curPrec, from=idx) => curPrec<opPrec && (l<2||cur.substr(idx,l)==op) && (!word||!isId(cur.charCodeAt(idx+l))) && (idx+=l, map(a, curPrec)) || (idx=from, prev&&prev(a, curPrec))
package/justin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // justin lang https://github.com/endojs/Jessie/issues/66
2
- import {parse, set, lookup, skip, cur, idx, err, expr, isId, space} from './index.js'
3
- import './subscript.js'
2
+ import {set, lookup, skip, cur, idx, err, expr, isId, space, args} from './index.js'
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,
6
6
  PREC_SEQ=1, PREC_COND=3, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
@@ -46,7 +46,9 @@ for (list=[
46
46
 
47
47
  // ?:
48
48
  ':', 3.1, (a,b) => [a,b],
49
- '?', 3, (a,b) => a ? b[2] : b[1],
49
+ '?', 3, (a,b) => a ? b[0] : b[1],
50
+
51
+ '??', PREC_OR, (a,b) => a??b,
50
52
 
51
53
  // a?.[, a?.( - postfix operator
52
54
  '?.', a => a && (ctx => a(ctx)||(()=>{})),,//(a) => a||(()=>{}),
@@ -56,18 +58,17 @@ for (list=[
56
58
  'in', PREC_COMP, (a,b) => a in b,
57
59
 
58
60
  // [a,b,c]
59
- '[', (a, args) => !a && (
61
+ '[', (a) => !a && (
60
62
  a=expr(0,CBRACK),
61
63
  !a ? ctx => [] : a.all ? ctx => a.all(ctx) : ctx => [a(ctx)]
62
64
  ),,
63
65
 
64
66
  // {a:1, b:2, c:3}
65
- '{', (a, args) => !a && (
67
+ '{', (a, entries) => !a && (
66
68
  a=expr(0,125),
67
- !a ? ctx => ({}) : ctx => (args=(a.all||a)(ctx), Object.fromEntries(a.all?args:[args]))
69
+ !a ? ctx => ({}) : ctx => (entries=(a.all||a)(ctx), Object.fromEntries(a.all?entries:[entries]))
68
70
  ),,
69
- ':', (a, prec, b) => (b=expr(3.1)||err(), ctx => [(a.id||a)(ctx), b(ctx), a(ctx)]), 3.1
71
+ // for JSON case we should not collect arg (different evaluator than ternary)
72
+ ':', (a, prec, b) => (b=expr(1.1)||err(), a.id&&args.pop(), ctx => [(a.id||a)(ctx), b(ctx)]), 1.1
70
73
 
71
74
  ]; [op,prec,fn,...list]=list, op;) set(op,prec,fn)
72
-
73
- export default parse
package/justin.min.js CHANGED
@@ -1 +1 @@
1
- let e,r,t,l,n,a,d=(t,...l)=>(r=t.raw?String.raw(t,...l):t,e=0,!(t=p())||r[e]?i("Unexpected end"):e=>t(e||{})),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=(t="Unexpected token",l=r[e])=>{throw SyntaxError(t+" `"+l+"` at "+e)},f=(t=1,l=e,n)=>{if("number"==typeof t)e+=t;else for(;t(r.charCodeAt(e));)e++;return r.slice(l,e)},p=(r=0,t,l,n,a,d)=>{for(;(l=c())&&(a=(d=u[l])&&d(n,r)||!n&&s());)n=a;return t&&(l==t?e++:i("Missing",String.fromCharCode(t))),n},c=t=>{for(;(t=r.charCodeAt(e))<=32;)e++;return t},s=(e=f(o),r)=>e?((r=r=>r[e]).id=()=>e,r):0,u=[],h=d.set=(t,l,n=32,a=t.charCodeAt(0),d=t.length,i=u[a],f=n.length||([n,l]=[l,n],0),c=t.toUpperCase()!==t,s=(f>1?(e,r)=>e&&(r=p(l))&&(e.length||r.length?t=>n(e(t),r(t)):(e=n(e(),r()),()=>e)):f?e=>!e&&(e=p(l-1))&&(r=>n(e(r))):n))=>u[a]=(n,a,f=e)=>a<l&&(d<2||r.substr(e,d)==t)&&(!c||!o(r.charCodeAt(e+d)))&&(e+=d,s(n,a))||(e=f,i&&i(n,a)),g=e=>e>=48&&e<=57,x=t=>(t&&i("Unexpected number"),t=f((e=>46==e||g(e))),(69==r.charCodeAt(e)||101==r.charCodeAt(e))&&(t+=f(2)+f(g)),(t=+t)!=t?i("Bad number"):()=>t),C=(e,r,t=e.of)=>l=>r(t?t(l):l,e.id());for(l=48;l<=57;)u[l++]=x;for(t=['"',e=>(e=e?i("Unexpected string"):f((e=>e-34)),f()||i("Bad string"),()=>e),,".",(e,r,t)=>e?(c(),r=f(o)||i(),(t=t=>e(t)[r]).id=()=>r,t.of=e,t):x(f(-1)),18,"[",(e,r,t)=>e&&(r=p(0,93)||i("Empty group"),(t=t=>e(t)[r(t)]).id=r,t.of=e,t),18,"(",(e,r,t)=>(r=p(0,41),e?t=>e(t).apply(e.of?.(t),r?r.all?r.all(t):[r(t)]:[]):r||i("Empty group")),18,",",(e,r,t=p(1))=>(t.all=e.all?(r,l,n=e.all(r))=>n.push(t(r))&&n:r=>[e(r),t(r)],t),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=>C(e||p(14),e?(e,r)=>e[r]++:(e,r)=>++e[r]),15,"-",12,(e,r)=>e-r,"-",15,e=>-e,"--",e=>C(e||p(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];[l,n,a,...t]=t,l;)h(l,n,a);let U,A,b,m,y={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},E=t=>(l,n,a="")=>{for(l&&i("Unexpected string");(n=r.charCodeAt(e))-t;)92===n?(f(),n=f(),a+=y[n]||n):a+=f();return f()||i("Bad string"),()=>a};for((U=['"',E(34),,"'",E(39),,"/*",(t,l)=>(f((t=>42!==t&&47!==r.charCodeAt(e+1))),f(2),t||p(l)),,"//",(e,r)=>(f((e=>e>=32)),e||p(r)),,"null",e=>e?i("Unexpected literal"):()=>null,,"true",e=>e?i("Unexpected literal"):()=>!0,,"false",e=>e?i("Unexpected literal"):()=>!1,,"undefined",e=>e?i("Unexpected literal"):()=>{},,";",e=>p()||(()=>{}),,"===",9,(e,r)=>e===r,"!==",9,(e,r)=>e!==r,"~",15,e=>~e,"**",(e,r,t=p(13))=>r=>e(r)**t(r),14,":",3.1,(e,r)=>[e,r],"?",3,(e,r)=>e?r[2]:r[1],"?.",e=>e&&(r=>e(r)||(()=>{})),,"?.",(e,r)=>(c(),(r=f(o))&&(t=>e(t)?.[r])),,"in",10,(e,r)=>e in r,"[",(e,r)=>!e&&((e=p(0,93))?e.all?r=>e.all(r):r=>[e(r)]:e=>[]),,"{",(e,r)=>!e&&((e=p(0,125))?t=>(r=(e.all||e)(t),Object.fromEntries(e.all?r:[r])):e=>({})),,":",(e,r,t)=>(t=p(3.1)||i(),r=>[(e.id||e)(r),t(r),e(r)]),3.1]);[A,b,m,...U]=U,A;)h(A,b,m);export{d as default};
1
+ let e,t,r,l,a,n,d,o=(l,a=(t=l,e=0,r=[],!(l=p())||t[e]?f():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)},c=(r=1,l=e,a)=>{if("number"==typeof r)e+=r;else for(;r(t.charCodeAt(e));)e++;return t.slice(l,e)},p=(t=0,r,l,a,n,d)=>{for(;(l=s())&&(n=(d=u[l])&&d(a,t)||!a&&h());)a=n;return r&&(l==r?e++:f()),a},s=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},h=(e=c(i),t)=>e?(t=t=>t[e],r.push(e),t.id=()=>e,t):0,u=[],x=o.set=(r,l,a=32,n=r.charCodeAt(0),d=r.length,o=u[n],f=a.length||([a,l]=[l,a],0),c=r.toUpperCase()!==r,s=(f>1?(e,t)=>e&&(t=p(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=p(l-1))&&(t=>a(e(t))):a))=>u[n]=(a,n,f=e)=>n<l&&(d<2||t.substr(e,d)==r)&&(!c||!i(t.charCodeAt(e+d)))&&(e+=d,s(a,n))||(e=f,o&&o(a,n)),g=e=>e>=48&&e<=57,C=r=>(r&&f("Unexpected number"),r=c((e=>46==e||g(e))),(69==t.charCodeAt(e)||101==t.charCodeAt(e))&&(r+=c(2)+c(g)),(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;)u[a++]=C;for(l=['"',e=>(e=e?f("Unexpected string"):c((e=>e-34)),c()||f("Bad string"),()=>e),,".",(e,t)=>(s(),t=c(i)||f(),d=r=>e(r)[t],d.id=()=>t,d.of=e,d),18,".",e=>!e&&C(c(-1)),,"[",(e,t,r)=>e&&(t=p(0,93)||f(),(r=r=>e(r)[t(r)]).id=t,r.of=e,r),18,"(",(e,t,r)=>(t=p(0,41),e?r=>e(r).apply(e.of?.(r),t?t.all?t.all(r):[t(r)]:[]):t||f()),18,",",(e,t,r=p(1))=>(r.all=e.all?t=>[...e.all(t),r(t)]:t=>[e(t),r(t)],r),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||p(14),e?(e,t)=>e[t]++:(e,t)=>++e[t]),15,"-",12,(e,t)=>e-t,"-",15,e=>-e,"--",e=>A(e||p(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;)x(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?(c(),a=c(),n+=B[a]||a):n+=c();return c()||f("Bad string"),()=>n};for((U=['"',v(34),,"'",v(39),,"/*",(r,l)=>(c((r=>42!==r&&47!==t.charCodeAt(e+1))),c(2),r||p(l)),,"//",(e,t)=>(c((e=>e>=32)),e||p(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=>p()||(()=>{}),,"===",9,(e,t)=>e===t,"!==",9,(e,t)=>e!==t,"~",15,e=>~e,"**",(e,t,r=p(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=c(i))&&(r=>e(r)?.[t])),,"in",10,(e,t)=>e in t,"[",e=>!e&&((e=p(0,93))?e.all?t=>e.all(t):t=>[e(t)]:e=>[]),,"{",(e,t)=>!e&&((e=p(0,125))?r=>(t=(e.all||e)(r),Object.fromEntries(e.all?t:[t])):e=>({})),,":",(e,t,l)=>(l=p(1.1)||f(),e.id&&r.pop(),t=>[(e.id||e)(t),l(t)]),1.1]);[b,m,y,...U]=U,b;)x(b,m,y);export{o as default};
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "subscript",
3
- "version": "6.0.2",
4
- "description": "Microlanguage with common syntax for JS/C++/Python/Rust",
3
+ "version": "6.2.0",
4
+ "description": "Fast and tiny expression evaluator with common syntax microlanguage.",
5
5
  "main": "subscript.js",
6
+ "module": "subscript.js",
6
7
  "type": "module",
7
8
  "files": [
8
9
  "index.js",
@@ -31,11 +32,17 @@
31
32
  "jexl",
32
33
  "jsep",
33
34
  "expression",
35
+ "evaluator",
36
+ "parser",
34
37
  "evaluation",
35
38
  "math",
36
39
  "arithmetic",
37
- "evaluator",
38
40
  "justin",
41
+ "eval",
42
+ "math-eval",
43
+ "math-evaluator",
44
+ "math-expression-evaluator",
45
+ "calculation",
39
46
  "jessie",
40
47
  "jessica",
41
48
  "eval",
@@ -43,11 +50,13 @@
43
50
  "json",
44
51
  "calculator",
45
52
  "calc",
46
- "lisp",
47
- "frisk",
48
53
  "math.js",
54
+ "mathjs",
49
55
  "math-codegen",
50
- "math-parser"
56
+ "math-parser",
57
+ "formula",
58
+ "operator",
59
+ "overload"
51
60
  ],
52
61
  "author": "Dmitry Iv.",
53
62
  "license": "ISC",
package/subscript.js CHANGED
@@ -1,4 +1,4 @@
1
- import {parse, set, lookup, skip, cur, idx, err, expr, isId, space} from './index.js'
1
+ import {parse, set, lookup, skip, cur, idx, err, expr, isId, args, space} from './index.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,
@@ -9,12 +9,12 @@ let u, list, op, prec, fn,
9
9
  // 1.2e+3, .5
10
10
  num = n => (
11
11
  n&&err('Unexpected number'),
12
- n = skip(c=>c==PERIOD || isNum(c)),
12
+ n = skip(c=>c == PERIOD || isNum(c)),
13
13
  (cur.charCodeAt(idx) == 69 || cur.charCodeAt(idx) == 101) && (n += skip(2) + skip(isNum)),
14
14
  n=+n, n!=n ? err('Bad number') : () => n // 0 args means token is static
15
15
  ),
16
16
 
17
- inc = (a,fn,c=a.of) => ctx => fn(c?c(ctx):ctx, a.id())
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, .2, 1.2 parser in one
28
- '.', (a,id,fn) => !a ? num(skip(-1)) : // FIXME: .123 is not operator, so we skip back, but mb reorganizing num would be better
29
- (space(), id=skip(isId)||err(), fn=ctx=>a(ctx)[id], fn.id=()=>id, fn.of=a, fn), PREC_CALL,
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,
package/subscript.min.js CHANGED
@@ -1 +1 @@
1
- let e,r,t,o,a,n,d=(t,...o)=>(r=t.raw?String.raw(t,...o):t,e=0,!(t=i())||r[e]?f("Unexpected end"):e=>t(e||{})),l=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,f=(t="Unexpected token",o=r[e])=>{throw SyntaxError(t+" `"+o+"` at "+e)},h=(t=1,o=e,a)=>{if("number"==typeof t)e+=t;else for(;t(r.charCodeAt(e));)e++;return r.slice(o,e)},i=(r=0,t,o,a,n,d)=>{for(;(o=c())&&(n=(d=p[o])&&d(a,r)||!a&&s());)a=n;return t&&(o==t?e++:f("Missing",String.fromCharCode(t))),a},c=t=>{for(;(t=r.charCodeAt(e))<=32;)e++;return t},s=(e=h(l),r)=>e?((r=r=>r[e]).id=()=>e,r):0,p=[],g=d.set=(t,o,a=32,n=t.charCodeAt(0),d=t.length,f=p[n],h=a.length||([a,o]=[o,a],0),c=t.toUpperCase()!==t,s=(h>1?(e,r)=>e&&(r=i(o))&&(e.length||r.length?t=>a(e(t),r(t)):(e=a(e(),r()),()=>e)):h?e=>!e&&(e=i(o-1))&&(r=>a(e(r))):a))=>p[n]=(a,n,h=e)=>n<o&&(d<2||r.substr(e,d)==t)&&(!c||!l(r.charCodeAt(e+d)))&&(e+=d,s(a,n))||(e=h,f&&f(a,n)),C=e=>e>=48&&e<=57,u=t=>(t&&f("Unexpected number"),t=h((e=>46==e||C(e))),(69==r.charCodeAt(e)||101==r.charCodeAt(e))&&(t+=h(2)+h(C)),(t=+t)!=t?f("Bad number"):()=>t),x=(e,r,t=e.of)=>o=>r(t?t(o):o,e.id());for(o=48;o<=57;)p[o++]=u;for(t=['"',e=>(e=e?f("Unexpected string"):h((e=>e-34)),h()||f("Bad string"),()=>e),,".",(e,r,t)=>e?(c(),r=h(l)||f(),(t=t=>e(t)[r]).id=()=>r,t.of=e,t):u(h(-1)),18,"[",(e,r,t)=>e&&(r=i(0,93)||f(),(t=t=>e(t)[r(t)]).id=r,t.of=e,t),18,"(",(e,r,t)=>(r=i(0,41),e?t=>e(t).apply(e.of?.(t),r?r.all?r.all(t):[r(t)]:[]):r||f()),18,",",(e,r,t=i(1))=>(t.all=e.all?r=>[...e.all(r),t(r)]:r=>[e(r),t(r)],t),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=>x(e||i(14),e?(e,r)=>e[r]++:(e,r)=>++e[r]),15,"-",12,(e,r)=>e-r,"-",15,e=>-e,"--",e=>x(e||i(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,a,n,...t]=t,o;)g(o,a,n);export{d as default};
1
+ let e,r,t,a,o,l,d,n=(a,o=(r=a,e=0,t=[],!(a=i())||r[e]?h():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)},s=(t=1,a=e,o)=>{if("number"==typeof t)e+=t;else for(;t(r.charCodeAt(e));)e++;return r.slice(a,e)},i=(r=0,t,a,o,l,d)=>{for(;(a=c())&&(l=(d=u[a])&&d(o,r)||!o&&p());)o=l;return t&&(a==t?e++:h()),o},c=t=>{for(;(t=r.charCodeAt(e))<=32;)e++;return t},p=(e=s(f),r)=>e?(r=r=>r[e],t.push(e),r.id=()=>e,r):0,u=[],g=n.set=(t,a,o=32,l=t.charCodeAt(0),d=t.length,n=u[l],h=o.length||([o,a]=[a,o],0),s=t.toUpperCase()!==t,c=(h>1?(e,r)=>e&&(r=i(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=i(a-1))&&(r=>o(e(r))):o))=>u[l]=(o,l,h=e)=>l<a&&(d<2||r.substr(e,d)==t)&&(!s||!f(r.charCodeAt(e+d)))&&(e+=d,c(o,l))||(e=h,n&&n(o,l)),C=e=>e>=48&&e<=57,A=t=>(t&&h("Unexpected number"),t=s((e=>46==e||C(e))),(69==r.charCodeAt(e)||101==r.charCodeAt(e))&&(t+=s(2)+s(C)),(t=+t)!=t?h("Bad number"):()=>t),x=(e,r)=>t=>r(e.of?e.of(t):t,e.id(t));for(o=48;o<=57;)u[o++]=A;for(a=['"',e=>(e=e?h("Unexpected string"):s((e=>e-34)),s()||h("Bad string"),()=>e),,".",(e,r)=>(c(),r=s(f)||h(),d=t=>e(t)[r],d.id=()=>r,d.of=e,d),18,".",e=>!e&&A(s(-1)),,"[",(e,r,t)=>e&&(r=i(0,93)||h(),(t=t=>e(t)[r(t)]).id=r,t.of=e,t),18,"(",(e,r,t)=>(r=i(0,41),e?t=>e(t).apply(e.of?.(t),r?r.all?r.all(t):[r(t)]:[]):r||h()),18,",",(e,r,t=i(1))=>(t.all=e.all?r=>[...e.all(r),t(r)]:r=>[e(r),t(r)],t),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=>x(e||i(14),e?(e,r)=>e[r]++:(e,r)=>++e[r]),15,"-",12,(e,r)=>e-r,"-",15,e=>-e,"--",e=>x(e||i(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,l,d,...a]=a,o;)g(o,l,d);export{n as default};