subscript 6.0.0 → 6.0.4

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,14 +1,11 @@
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 micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust etc.<br/>
7
4
 
8
5
  * Standard conventional syntax
9
6
  * Any fragment can be copy-pasted to any target language
10
7
  * 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
- * :rocket: fast ([performance](#performance))
8
+ * :rocket: Fast [performance](#performance)
12
9
  * Configurable & extensible
13
10
  * Trivial to use
14
11
 
@@ -34,27 +31,45 @@ _Subscript_ has [2kb](https://npmfs.com/package/subscript/6.0.0/subscript.min.js
34
31
 
35
32
  ## Design
36
33
 
37
- Default operators (precedence order):
38
-
39
- * `++ --` unary postfix
40
- * `! + - ++ --` unary prefix
41
- * `* / %`
42
- * `+ -`
43
- * `<< >> >>>`
44
- * `< <= > >=`
45
- * `== !=`
46
- * `&`
47
- * `^`
48
- * `|`
49
- * `&&`
50
- * `||`
34
+ Default operators are (same as JS precedence order):
35
+
36
+ * `( a, b, c )`
37
+ * `a.b`, `a[b]`, `a(b, c)`
38
+ * `a++`, `a--` unary postfix
39
+ * `!a`, `+a`, `-a`, `++a`, `--a` unary prefix
40
+ * `a * b`, `a / b`, `a % b`
41
+ * `a + b`, `a - b`
42
+ * `a << b`, `a >> b`, `a >>> b`
43
+ * `a < b`, `a <= b`, `a > b`, `a >= b`
44
+ * `a == b`, `a != b`
45
+ * `a & b`
46
+ * `a ^ b`
47
+ * `a | b`
48
+ * `a && b`
49
+ * `a || b`
51
50
 
52
51
  Default literals:
53
52
 
54
53
  * `"abc"` strings
55
54
  * `1.2e+3` numbers
56
55
 
57
- Everything else can be extended via `parse.set(operator, precedence, fn)` for unary or binary operators (detected by number of arguments in `fn`), or via `parse.set(operator, parser, precedence)` for custom tokens.
56
+ 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.
57
+
58
+ ```js
59
+ import script from 'subscript.js'
60
+
61
+ // add ~ unary operator with precedence 15
62
+ script.set('~', 15, a => ~a)
63
+
64
+ // add === binary operator
65
+ script.set('===', 9, (a, b) => a===b)
66
+
67
+ // add literals
68
+ script.set('true', a => ()=>true)
69
+ script.set('false', a => ()=>false)
70
+
71
+ script`true === false`() // false
72
+ ```
58
73
 
59
74
  See [subscript.js](subscript.js) or [justin.js](./justin.js) for examples.
60
75
 
@@ -115,10 +130,10 @@ It extends _subscript_ with:
115
130
  <!-- + strings interpolation -->
116
131
 
117
132
  ```js
118
- import { parse, evaluate } from 'subscript/justin.js'
133
+ import jstin from 'subscript/justin.js'
119
134
 
120
- let xy = parse('{ x: 1, "y": 2+2 }["x"]') // ['[', {x:1, y: ['+', 2, 2]}, '@x']
121
- evaluate(xy) // 1
135
+ let xy = jstin('{ x: 1, "y": 2+2 }["x"]')
136
+ xy() // 1
122
137
  ```
123
138
 
124
139
  <!--
@@ -269,12 +284,13 @@ Subscript shows relatively good performance within other evaluators:
269
284
  Parse 30k times:
270
285
 
271
286
  ```
272
- subscript: ~170 ms
273
- justin: ~183 ms
274
- jsep: ~250 ms
287
+ subscript: ~170 ms 🥇
288
+ justin: ~183 ms 🥈
289
+ jsep: ~270 ms 🥉
275
290
  mr-parser: ~420 ms
276
291
  expr-eval: ~480 ms
277
292
  math-parser: ~570 ms
293
+ math-expression-evaluator: ~900ms
278
294
  jexl: ~1056 ms
279
295
  mathjs: ~1200 ms
280
296
  new Function: ~1154 ms
@@ -282,15 +298,16 @@ new Function: ~1154 ms
282
298
 
283
299
  Eval 30k times:
284
300
  ```
285
- subscript: ~15 ms
286
- justin: ~15 ms
287
- jsep (expression-eval): ~30 ms
288
- mr-parser: -
301
+ new Function: ~7 ms 🥇
302
+ subscript: ~17 ms 🥈
303
+ justin: ~17 ms 🥈
304
+ jsep (expression-eval): ~30 ms 🥉
305
+ math-expression-evaluator: ~50ms
289
306
  expr-eval: ~72 ms
290
- math-parser: -
291
307
  jexl: ~110 ms
292
308
  mathjs: ~119 ms
293
- new Function: ~5 ms
309
+ mr-parser: -
310
+ math-parser: -
294
311
  ```
295
312
 
296
313
  ## Alternatives
package/index.js ADDED
@@ -0,0 +1,71 @@
1
+ const SPACE=32
2
+
3
+ // current string & index
4
+ export let idx, cur,
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||{}),
7
+
8
+ isId = c =>
9
+ (c >= 48 && c <= 57) || // 0..9
10
+ (c >= 65 && c <= 90) || // A...Z
11
+ (c >= 97 && c <= 122) || // a...z
12
+ c == 36 || c == 95 || // $, _,
13
+ (c >= 192 && c != 215 && c != 247), // any non-ASCII
14
+
15
+ err = (msg='Unexpected token',c=cur[idx]) => { throw SyntaxError(msg + ' `' + c + '` at ' + idx) },
16
+
17
+ skip = (is=1, from=idx, l) => {
18
+ if (typeof is == 'number') idx += is
19
+ else while (is(cur.charCodeAt(idx))) idx++
20
+ return cur.slice(from, idx)
21
+ },
22
+
23
+ // a + b - c
24
+ expr = (prec=0, end, cc, token, newNode, fn) => {
25
+ // chunk/token parser
26
+ while (
27
+ ( cc=space() ) && // till not end
28
+ // FIXME: extra work is happening here, when lookup bails out due to lower precedence -
29
+ // it makes extra `space` call for parent exprs on the same character to check precedence again
30
+ ( newNode =
31
+ (fn=lookup[cc]) && fn(token, prec) || // if operator with higher precedence isn't found
32
+ (!token && id()) // parse literal or quit. token seqs are forbidden: `a b`, `a "b"`, `1.32 a`
33
+ )
34
+ ) token = newNode;
35
+
36
+ // check end character
37
+ if (end) cc==end?idx++:err('Missing', String.fromCharCode(end))
38
+
39
+ return token
40
+ },
41
+
42
+ // skip space chars, return first non-space character
43
+ space = cc => { while ((cc = cur.charCodeAt(idx)) <= SPACE) idx++; return cc },
44
+
45
+ // variable identifier
46
+ id = (name=skip(isId), fn) => name ? (fn=ctx => ctx[name], fn.id=()=>name, fn) : 0,
47
+
48
+ // operator/token lookup table
49
+ lookup = [],
50
+
51
+ // create operator checker/mapper (see examples)
52
+ set = parse.set = (
53
+ op,
54
+ opPrec, fn=SPACE, // if opPrec & fn come in reverse order - consider them raw parse fn case, still precedence possible
55
+ c=op.charCodeAt(0),
56
+ l=op.length,
57
+ prev=lookup[c],
58
+ arity=fn.length || ([fn,opPrec]=[opPrec,fn], 0),
59
+ word=op.toUpperCase()!==op, // make sure word boundary comes after word operator
60
+ map=
61
+ // binary
62
+ arity>1 ? (a,b) => a && (b=expr(opPrec)) && (
63
+ !a.length && !b.length ? (a=fn(a(),b()), ()=>a) : // static pre-eval like `"a"+"b"`
64
+ ctx => fn(a(ctx),b(ctx))
65
+ ) :
66
+ // unary prefix (0 args)
67
+ arity ? a => !a && (a=expr(opPrec-1)) && (ctx => fn(a(ctx))) :
68
+ fn // custom parser
69
+ ) =>
70
+ // FIXME: find out if that's possible to globalize precision and instead of passing it to map, just provide global
71
+ 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
@@ -10,7 +10,7 @@ PREC_EQ=9, PREC_COMP=10, PREC_SHIFT=11, PREC_SUM=12, PREC_MULT=13, PREC_EXP=14,
10
10
  let u, list, op, prec, fn,
11
11
  escape = {n:'\n', r:'\r', t:'\t', b:'\b', f:'\f', v:'\v'},
12
12
  string = q => (qc, c, str='') => {
13
- qc&&err() // must not follow another token
13
+ qc&&err('Unexpected string') // must not follow another token
14
14
  while (c=cur.charCodeAt(idx), c-q) {
15
15
  if (c === BSLASH) skip(), c=skip(), str += escape[c] || c
16
16
  else str += skip()
@@ -29,10 +29,10 @@ for (list=[
29
29
  '//', (a, prec) => (skip(c => c >= 32), a||expr(prec)),,
30
30
 
31
31
  // literals
32
- 'null', a => a ? err() : ()=>null,,
33
- 'true', a => a ? err() : ()=>true,,
34
- 'false', a => a ? err() : ()=>false,,
35
- 'undefined', a => a ? err() : ()=>undefined,,
32
+ 'null', a => a ? err('Unexpected literal') : ()=>null,,
33
+ 'true', a => a ? err('Unexpected literal') : ()=>true,,
34
+ 'false', a => a ? err('Unexpected literal') : ()=>false,,
35
+ 'undefined', a => a ? err('Unexpected literal') : ()=>undefined,,
36
36
 
37
37
  ';', a => expr()||(()=>{}),,
38
38
 
package/justin.min.js CHANGED
@@ -1 +1 @@
1
- let r,e,t,l,a,o,n=(t,...l)=>(e=t.raw?String.raw(t,...l):t,r=0,!(t=i())||e[r]?f():r=>t(r||{})),d=r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192&&215!=r&&247!=r,f=(t="Bad syntax",l=e[r])=>{throw Error(t+" `"+l+"` at "+r)},h=(t=1,l=r,a)=>{if("number"==typeof t)r+=t;else for(;t(e.charCodeAt(r));)r++;return e.slice(l,r)},i=(e=0,t,l,a,o,n)=>{for(;(l=s())&&(o=(n=c[l])&&n(a,e)||!a&&u());)a=o;return t&&(l==t?r++:f("Unclosed")),a},s=t=>{for(;(t=e.charCodeAt(r))<=32;)r++;return t},u=(r=h(d),e)=>r?((e=e=>e[r]).id=()=>r,e):0,c=[],C=n.set=(t,l,a=32,o=t.charCodeAt(0),n=t.length,f=c[o],h=a.length||([a,l]=[l,a],0),s=t.toUpperCase()!==t,u=(h>1?(r,e)=>r&&(e=i(l))&&(r.length||e.length?t=>a(r(t),e(t)):(r=a(r(),e()),()=>r)):h?r=>!r&&(r=i(l-1))&&(e=>a(r(e))):a))=>c[o]=(a,o,h=r)=>o<l&&(n<2||e.substr(r,n)==t)&&(!s||!d(e.charCodeAt(r+n)))&&(r+=n,u(a,o))||(r=h,f&&f(a,o)),A=r=>r>=48&&r<=57,g=t=>(t&&f(),t=h((r=>46==r||A(r))),(69==e.charCodeAt(r)||101==e.charCodeAt(r))&&(t+=h(2)+h(A)),(t=+t)!=t?f("Bad number"):()=>t),p=(r,e,t=r.of)=>l=>e(t?t(l):l,r.id());for(l=48;l<=57;)c[l++]=g;for(t=['"',r=>(r=r?f():h((r=>r-34)),h()||f("Bad string"),()=>r),,".",(r,e,t)=>r?(s(),e=h(d)||f(),(t=t=>r(t)[e]).id=()=>e,t.of=r,t):g(h(-1)),18,"[",(r,e,t)=>r&&(e=i(0,93)||f(),(t=t=>r(t)[e(t)]).id=e,t.of=r,t),18,"(",(r,e,t)=>(e=i(0,41),r?t=>r(t).apply(r.of?.(t),e?e.all?e.all(t):[e(t)]:[]):e||f()),18,",",(r,e,t=i(1))=>(t.all=r.all?(e,l,a=r.all(e))=>a.push(t(e))&&a:e=>[r(e),t(e)],t),1,"|",6,(r,e)=>r|e,"||",4,(r,e)=>r||e,"&",8,(r,e)=>r&e,"&&",5,(r,e)=>r&&e,"^",7,(r,e)=>r^e,"==",9,(r,e)=>r==e,"!=",9,(r,e)=>r!=e,">",10,(r,e)=>r>e,">=",10,(r,e)=>r>=e,">>",11,(r,e)=>r>>e,">>>",11,(r,e)=>r>>>e,"<",10,(r,e)=>r<e,"<=",10,(r,e)=>r<=e,"<<",11,(r,e)=>r<<e,"+",12,(r,e)=>r+e,"+",15,r=>+r,"++",r=>p(r||i(14),r?(r,e)=>r[e]++:(r,e)=>++r[e]),15,"-",12,(r,e)=>r-e,"-",15,r=>-r,"--",r=>p(r||i(14),r?(r,e)=>r[e]--:(r,e)=>--r[e]),15,"!",15,r=>!r,"*",13,(r,e)=>r*e,"/",13,(r,e)=>r/e,"%",13,(r,e)=>r%e];[l,a,o,...t]=t,l;)C(l,a,o);let b,B,m,w,y={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},v=t=>(l,a,o="")=>{for(l&&f();(a=e.charCodeAt(r))-t;)92===a?(h(),a=h(),o+=y[a]||a):o+=h();return h()||f("Bad string"),()=>o};for((b=['"',v(34),,"'",v(39),,"/*",(t,l)=>(h((t=>42!==t&&47!==e.charCodeAt(r+1))),h(2),t||i(l)),,"//",(r,e)=>(h((r=>r>=32)),r||i(e)),,"null",r=>r?f():()=>null,,"true",r=>r?f():()=>!0,,"false",r=>r?f():()=>!1,,"undefined",r=>r?f():()=>{},,";",r=>i()||(()=>{}),,"===",9,(r,e)=>r===e,"!==",9,(r,e)=>r!==e,"~",15,r=>~r,"**",(r,e,t=i(13))=>e=>r(e)**t(e),14,":",3.1,(r,e)=>[r,e],"?",3,(r,e)=>r?e[2]:e[1],"?.",r=>r&&(e=>r(e)||(()=>{})),,"?.",(r,e)=>(s(),(e=h(d))&&(t=>r(t)?.[e])),,"in",10,(r,e)=>r in e,"[",(r,e)=>!r&&((r=i(0,93))?r.all?e=>r.all(e):e=>[r(e)]:r=>[]),,"{",(r,e)=>!r&&((r=i(0,125))?t=>(e=(r.all||r)(t),Object.fromEntries(r.all?e:[e])):r=>({})),,":",(r,e,t)=>(t=i(3.1)||f(),e=>[(r.id||r)(e),t(e),r(e)]),3.1]);[B,m,w,...b]=b,B;)C(B,m,w);export{n as default};
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};
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "subscript",
3
- "version": "6.0.0",
4
- "description": "Microlanguage with common syntax for JS/C++/Python/Rust",
3
+ "version": "6.0.4",
4
+ "description": "Fast and tiny expression evaluator with common syntax microlanguage.",
5
5
  "main": "subscript.js",
6
6
  "type": "module",
7
7
  "files": [
8
- "parse.js",
9
- "evaluate.js",
8
+ "index.js",
10
9
  "subscript.js",
11
10
  "subscript.min.js",
12
11
  "justin.js",
@@ -32,11 +31,17 @@
32
31
  "jexl",
33
32
  "jsep",
34
33
  "expression",
34
+ "evaluator",
35
+ "parser",
35
36
  "evaluation",
36
37
  "math",
37
38
  "arithmetic",
38
- "evaluator",
39
39
  "justin",
40
+ "eval",
41
+ "math-eval",
42
+ "math-evaluator",
43
+ "math-expression-evaluator",
44
+ "calculation",
40
45
  "jessie",
41
46
  "jessica",
42
47
  "eval",
@@ -44,11 +49,13 @@
44
49
  "json",
45
50
  "calculator",
46
51
  "calc",
47
- "lisp",
48
- "frisk",
49
52
  "math.js",
53
+ "mathjs",
50
54
  "math-codegen",
51
- "math-parser"
55
+ "math-parser",
56
+ "formula",
57
+ "operator",
58
+ "overload"
52
59
  ],
53
60
  "author": "Dmitry Iv.",
54
61
  "license": "ISC",
package/subscript.js CHANGED
@@ -8,7 +8,7 @@ let u, list, op, prec, fn,
8
8
  isNum = c => c>=_0 && c<=_9,
9
9
  // 1.2e+3, .5
10
10
  num = n => (
11
- n&&err(),
11
+ n&&err('Unexpected number'),
12
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
@@ -22,7 +22,7 @@ for (op=_0;op<=_9;) lookup[op++] = num
22
22
  // operators
23
23
  for (list=[
24
24
  // "a"
25
- '"', a => (a=a?err():skip(c => c-DQUOTE), skip()||err('Bad string'), ()=>a),,
25
+ '"', a => (a=a?err('Unexpected string'):skip(c => c-DQUOTE), skip()||err('Bad string'), ()=>a),,
26
26
 
27
27
  // a.b, .2, 1.2 parser in one
28
28
  '.', (a,id,fn) => !a ? num(skip(-1)) : // FIXME: .123 is not operator, so we skip back, but mb reorganizing num would be better
@@ -42,7 +42,7 @@ for (list=[
42
42
 
43
43
  // [a,b,c] or (a,b,c)
44
44
  ',', (a,prec,b=expr(PREC_SEQ)) => (
45
- b.all = a.all ? (ctx,prec,arr=a.all(ctx)) => arr.push(b(ctx)) && arr : ctx => [a(ctx),b(ctx)],
45
+ b.all = a.all ? ctx => [...a.all(ctx), b(ctx)] : ctx => [a(ctx),b(ctx)],
46
46
  b
47
47
  ), PREC_SEQ,
48
48
 
package/subscript.min.js CHANGED
@@ -1 +1 @@
1
- let r,e,t,a,o,l,d=(t,...a)=>(e=t.raw?String.raw(t,...a):t,r=0,!(t=s())||e[r]?f():r=>t(r||{})),n=r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192&&215!=r&&247!=r,f=(t="Bad syntax",a=e[r])=>{throw Error(t+" `"+a+"` at "+r)},h=(t=1,a=r,o)=>{if("number"==typeof t)r+=t;else for(;t(e.charCodeAt(r));)r++;return e.slice(a,r)},s=(e=0,t,a,o,l,d)=>{for(;(a=c())&&(l=(d=u[a])&&d(o,e)||!o&&i());)o=l;return t&&(a==t?r++:f("Unclosed")),o},c=t=>{for(;(t=e.charCodeAt(r))<=32;)r++;return t},i=(r=h(n),e)=>r?((e=e=>e[r]).id=()=>r,e):0,u=[],p=d.set=(t,a,o=32,l=t.charCodeAt(0),d=t.length,f=u[l],h=o.length||([o,a]=[a,o],0),c=t.toUpperCase()!==t,i=(h>1?(r,e)=>r&&(e=s(a))&&(r.length||e.length?t=>o(r(t),e(t)):(r=o(r(),e()),()=>r)):h?r=>!r&&(r=s(a-1))&&(e=>o(r(e))):o))=>u[l]=(o,l,h=r)=>l<a&&(d<2||e.substr(r,d)==t)&&(!c||!n(e.charCodeAt(r+d)))&&(r+=d,i(o,l))||(r=h,f&&f(o,l)),C=r=>r>=48&&r<=57,g=t=>(t&&f(),t=h((r=>46==r||C(r))),(69==e.charCodeAt(r)||101==e.charCodeAt(r))&&(t+=h(2)+h(C)),(t=+t)!=t?f("Bad number"):()=>t),A=(r,e,t=r.of)=>a=>e(t?t(a):a,r.id());for(a=48;a<=57;)u[a++]=g;for(t=['"',r=>(r=r?f():h((r=>r-34)),h()||f("Bad string"),()=>r),,".",(r,e,t)=>r?(c(),e=h(n)||f(),(t=t=>r(t)[e]).id=()=>e,t.of=r,t):g(h(-1)),18,"[",(r,e,t)=>r&&(e=s(0,93)||f(),(t=t=>r(t)[e(t)]).id=e,t.of=r,t),18,"(",(r,e,t)=>(e=s(0,41),r?t=>r(t).apply(r.of?.(t),e?e.all?e.all(t):[e(t)]:[]):e||f()),18,",",(r,e,t=s(1))=>(t.all=r.all?(e,a,o=r.all(e))=>o.push(t(e))&&o:e=>[r(e),t(e)],t),1,"|",6,(r,e)=>r|e,"||",4,(r,e)=>r||e,"&",8,(r,e)=>r&e,"&&",5,(r,e)=>r&&e,"^",7,(r,e)=>r^e,"==",9,(r,e)=>r==e,"!=",9,(r,e)=>r!=e,">",10,(r,e)=>r>e,">=",10,(r,e)=>r>=e,">>",11,(r,e)=>r>>e,">>>",11,(r,e)=>r>>>e,"<",10,(r,e)=>r<e,"<=",10,(r,e)=>r<=e,"<<",11,(r,e)=>r<<e,"+",12,(r,e)=>r+e,"+",15,r=>+r,"++",r=>A(r||s(14),r?(r,e)=>r[e]++:(r,e)=>++r[e]),15,"-",12,(r,e)=>r-e,"-",15,r=>-r,"--",r=>A(r||s(14),r?(r,e)=>r[e]--:(r,e)=>--r[e]),15,"!",15,r=>!r,"*",13,(r,e)=>r*e,"/",13,(r,e)=>r/e,"%",13,(r,e)=>r%e];[a,o,l,...t]=t,a;)p(a,o,l);export{d as default};
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};