subscript 7.6.2 → 8.0.1

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/justin.js CHANGED
@@ -1,41 +1,31 @@
1
1
  // justin lang https://github.com/endojs/Jessie/issues/66
2
- import { skip, cur, idx, err, expr, lookup, token, binary } from './parse.js'
3
- import compile, { operator } from './compile.js'
4
- import subscript, { set } from './subscript.js'
5
-
6
- const PERIOD = 46, OPAREN = 40, CPAREN = 41, OBRACK = 91, CBRACK = 93, SPACE = 32, DQUOTE = 34, QUOTE = 39, _0 = 48, _9 = 57, BSLASH = 92,
7
- PREC_SEQ = 1, PREC_COND = 3, PREC_SOME = 4, PREC_EVERY = 5, PREC_OR = 6, PREC_XOR = 7, PREC_AND = 8,
8
- PREC_EQ = 9, PREC_COMP = 10, PREC_SHIFT = 11, PREC_SUM = 12, PREC_MULT = 13, PREC_EXP = 14, PREC_UNARY = 15, PREC_POSTFIX = 16, PREC_CALL = 18, PREC_GROUP = 19
9
-
10
- let escape = { n: '\n', r: '\r', t: '\t', b: '\b', f: '\f', v: '\v' },
11
- string = q => (qc, c, str = '') => {
12
- qc && err('Unexpected string') // must not follow another token
13
- skip() // first quote
14
- while (c = cur.charCodeAt(idx), c - q) {
15
- if (c === BSLASH) skip(), c = skip(), str += escape[c] || c
16
- else str += skip()
17
- }
18
- skip() || err('Bad string')
19
- return ['', str]
20
- }
2
+ import { skip, cur, idx, err, expr, lookup, token, binary, unary } from './src/parse.js'
3
+ import compile, { operator } from './src/compile.js'
4
+ import { CPAREN, COLON, PREC_ASSIGN, PREC_PREFIX, PREC_OR, PREC_ACCESS, PREC_COMP, PREC_EXP, PREC_GROUP } from './src/const.js'
5
+
6
+ // register subscript operators set
7
+ import subscript from './subscript.js'
8
+ import './feature/comment.js'
9
+ import './feature/pow.js'
10
+ import './feature/in.js'
11
+ import './feature/ternary.js'
12
+ import './feature/bool.js'
13
+ import './feature/array.js'
14
+ import './feature/object.js'
21
15
 
22
16
  // operators
23
17
  // set('===', PREC_EQ, (a, b) => a === b)
24
18
  // set('!==', PREC_EQ, (a, b) => a !== b)
25
- set('~', PREC_UNARY, (a) => ~a)
26
-
27
- // ?:
28
- token('?', PREC_COND, (a, b, c) => a && (b = expr(2, 58)) && (c = expr(3), ['?', a, b, c]))
29
- operator('?', (a, b, c) => (a = compile(a), b = compile(b), c = compile(c), ctx => a(ctx) ? b(ctx) : c(ctx)))
30
-
31
- set('??', PREC_OR, (a, b) => a ?? b)
19
+ binary('??', PREC_OR), operator('??', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) ?? b(ctx)))
32
20
 
33
21
  // a?.[, a?.( - postfix operator
34
- token('?.', PREC_CALL, a => a && ['?.', a])
22
+ token('?.', PREC_ACCESS, a => a && ['?.', a])
23
+ // a ?.
35
24
  operator('?.', a => (a = compile(a), ctx => a(ctx) || (() => { })))
36
25
 
37
26
  // a?.b, a?.() - optional chain operator
38
- token('?.', PREC_CALL, (a, b) => a && (b = expr(PREC_CALL), !b?.map) && (b ? ['?.', a, b] : ['?.', a, b]))
27
+ token('?.', PREC_ACCESS, (a, b) => a && (b = expr(PREC_ACCESS), !b?.map) && ['?.', a, b])
28
+ // a ?. b
39
29
  operator('?.', (a, b) => b && (a = compile(a), ctx => a(ctx)?.[b]))
40
30
 
41
31
  // a?.x() - keep context, but watch out a?.()
@@ -43,59 +33,22 @@ operator('(', (a, b, container, args, path, optional) => (b != null) && (a[0] ==
43
33
  args = b == '' ? () => [] : // a()
44
34
  b[0] === ',' ? (b = b.slice(1).map(compile), ctx => b.map(a => a(ctx))) : // a(b,c)
45
35
  (b = compile(b), ctx => [b(ctx)]), // a(b)
36
+
46
37
  // a?.()
47
38
  !a[2] && (optional = true, a = a[1]),
39
+
48
40
  // a?.['x']?.()
49
- a[0] === '[' ? (path = compile(a[2])) : (path = ctx => a[2]),
41
+ a[0] === '[' ? (path = compile(a[2])) : (path = () => a[2]),
50
42
  (container = compile(a[1]), optional ?
51
43
  ctx => (container(ctx)?.[path(ctx)]?.(...args(ctx))) :
52
44
  ctx => (container(ctx)?.[path(ctx)](...args(ctx)))
53
45
  )
54
46
  ))
55
47
 
56
- // a in b
57
- set('in', PREC_COMP, (a, b) => a in b)
58
-
59
- // "' with /
60
- lookup[DQUOTE] = string(DQUOTE)
61
- lookup[QUOTE] = string(QUOTE)
62
-
63
- // /**/, //
64
- token('/*', 20, (a, prec) => (skip(c => c !== 42 && cur.charCodeAt(idx + 1) !== 47), skip(2), a || expr(prec) || ['']))
65
- token('//', 20, (a, prec) => (skip(c => c >= 32), a || expr(prec) || ['']))
66
-
67
48
  // literals
68
- token('null', 20, a => a ? err() : ['', null])
69
- token('true', 20, a => a ? err() : ['', true])
70
- token('false', 20, a => a ? err() : ['', false])
71
- // token('undefined', 20, a => a ? err() : ['', undefined])
72
- // token('NaN', 20, a => a ? err() : ['', NaN])
73
-
74
- set(';', -1, (...args) => args[args.length - 1])
75
-
76
- // right order
77
- // '**', (a,prec,b=expr(PREC_EXP-1)) => ctx=>a(ctx)**b(ctx), PREC_EXP,
78
- set('**', -PREC_EXP, (a, b) => a ** b)
79
-
80
- // [a,b,c]
81
- token('[', 20, (a) => !a && ['[', expr(0, 93) || ''])
82
- operator('[', (a, b) => !b && (
83
- !a ? () => [] : // []
84
- a[0] === ',' ? (a = a.slice(1).map(compile), ctx => a.map(a => a(ctx))) : // [a,b,c]
85
- (a = compile(a), ctx => [a(ctx)]) // [a]
86
- ))
87
-
88
- // {a:1, b:2, c:3}
89
- token('{', 20, a => !a && (['{', expr(0, 125) || '']))
90
- operator('{', (a, b) => (
91
- !a ? ctx => ({}) : // {}
92
- a[0] === ',' ? (a = a.slice(1).map(compile), ctx => Object.fromEntries(a.map(a => a(ctx)))) : // {a:1,b:2}
93
- a[0] === ':' ? (a = compile(a), ctx => Object.fromEntries([a(ctx)])) : // {a:1}
94
- (b = compile(a), ctx => ({ [a]: b(ctx) }))
95
- ))
96
-
97
- token(':', 1.1, (a, b) => (b = expr(1.1) || err(), [':', a, b]))
98
- operator(':', (a, b) => (b = compile(b), a = Array.isArray(a) ? compile(a) : (a => a).bind(0, a), ctx => [a(ctx), b(ctx)]))
49
+ token('null', 20, a => a ? err() : [, null])
50
+ // token('undefined', 20, a => a ? err() : [, undefined])
51
+ // token('NaN', 20, a => a ? err() : [, NaN])
99
52
 
100
53
  export default subscript
101
54
  export * from './subscript.js'
package/justin.min.js CHANGED
@@ -1 +1 @@
1
- let e,t,r=r=>(e=0,t=r,r=n(),t[e]?l():r||""),l=(r="Bad syntax",l=t[e],a=t.slice(0,e).split("\n"),n=a.pop())=>{let s=t.slice(e-108,e).split("\n").pop(),i=t.slice(e+1,e+108).split("\n").shift();throw EvalError(`${r} at ${a.length}:${n.length} \`${s+l+i}\``,"font-weight: bold")},a=(r=1,l=e,a)=>{if("number"==typeof r)e+=r;else for(;a=r(t.charCodeAt(e));)e+=a;return t.slice(l,e)},n=(t=0,a,n,s,i,p)=>{for(;(n=r.space())&&(i=((p=o[n])&&p(s,t))??(!s&&r.id()));)s=i;return a&&(n==a?e++:l()),s},s=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,i=r.space=r=>{for(;(r=t.charCodeAt(e))<=32;)e++;return r},p=r.id=e=>a(s),o=[],h=(r,l=32,a,n=r.charCodeAt(0),i=r.length,p=o[n],h=r.toUpperCase()!==r)=>o[n]=(n,o,c=e)=>o<l&&(i<2||t.substr(e,i)==r)&&(!h||!s(t.charCodeAt(e+i)))&&(e+=i,a(n,o))||(e=c,p?.(n,o)),c=(e,t,r=0)=>h(e,t,((l,a)=>l&&(a=n(t-r/2))&&[e,l,a])),f=(e,t,r)=>h(e,t,(l=>r?l&&[e,l]:!l&&(l=n(t-.5))&&[e,l])),g=(e,t,r)=>{h(e,t,((l,a)=>(l||r)&&((a=n(t))||r)&&((!l||l[0]!==e)&&(l=[e,l]),(a||r)&&l.push(a),l)))};const u=e=>Array.isArray(e)?d[e[0]](...e.slice(1)):t=>t?.[e],d={},m=(e,t,r=d[e])=>d[e]=(...e)=>t(...e)||r&&r(...e),A=e=>(e=r(e),t=>(e.call?e:e=u(e))(t)),b=(e,t,r)=>r.length?r.length>1?(c(e,Math.abs(t),t<0),m(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))))):(f(e,t),m(e,((e,t)=>!t&&((e=u(e)).length?t=>r(e(t)):(e=r(e()),()=>e))))):(g(e,Math.abs(t),t<0),m(e,((...e)=>(e=e.map(u),t=>r(...e.map((e=>e(t)))))))),y=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)=>(h(e,t,(r=>r?["++"===e?"-":"+",[e,r],["",1]]:[e,n(t-1)])),m(e,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)));m("",(e=>()=>e)),o[34]=e=>e?l():["",(a()+a((e=>e-34?1:0))+(a()||l("Bad string"))).slice(1,-1)],o[46]=e=>!e&&y();for(let e=0;e<=9;e++)o[48+e]=y;b(",",1,((...e)=>e[e.length-1])),b("||",4,((...e)=>{let t,r=0;for(;!t&&r<e.length;)t=e[r++];return t})),b("&&",5,((...e)=>{let t=0,r=!0;for(;r&&t<e.length;)r=e[t++];return r})),c("=",10,!0),m("=",((e,t)=>{let r,a,n=u(t),s="string"==typeof e?(t,r)=>t[e]=r:"."===e[0]?(r=u(e[1]),a=e[2],(e,t)=>r(e)[a]=t):"["===e[0]?(r=u(e[1]),a=u(e[2]),(e,t)=>r(e)[a(e)]=t):l("Bad left value");return e=>s(e,n(e))})),b("+",12,((e,t)=>e+t)),b("-",12,((e,t)=>e-t)),b("*",13,((e,t)=>e*t)),b("/",13,((e,t)=>e/t)),b("%",13,((e,t)=>e%t)),b("|",6,((e,t)=>e|t)),b("&",8,((e,t)=>e&t)),b("^",7,((e,t)=>e^t)),b("==",9,((e,t)=>e==t)),b("!=",9,((e,t)=>e!=t)),b(">",10,((e,t)=>e>t)),b(">=",10,((e,t)=>e>=t)),b("<",10,((e,t)=>e<t)),b("<=",10,((e,t)=>e<=t)),b(">>",11,((e,t)=>e>>t)),b(">>>",11,((e,t)=>e>>>t)),b("<<",11,((e,t)=>e<<t)),b("+",15,(e=>+e)),b("-",15,(e=>-e)),b("!",15,(e=>!e)),C("++",15,((e,t)=>++e[t])),C("--",15,((e,t)=>--e[t])),h("[",18,(e=>e&&["[",e,n(0,93)||l()])),m("[",((e,t)=>t&&(e=u(e),t=u(t),r=>e(r)[t(r)]))),h(".",18,((e,t)=>e&&(t=n(18))&&[".",e,t])),m(".",((e,t)=>(e=u(e),t=t[0]?t:t[1],r=>e(r)[t]))),h("(",18,(e=>!e&&["(",n(0,41)||l()])),h("(",18,((e,t)=>e&&((t=n(0,41))?["(",e,t]:["(",e,""]))),m("(",((e,t,r,l,a)=>null==t?u(e):(a=""==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](...a(t))):"["===e[0]?(r=u(e[2]),e=u(e[1]),t=>e(t)[r(t)](...a(t))):(e=u(e),t=>e(t)(...a(t))))));let v={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},B=r=>(n,s,i="")=>{for(n&&l("Unexpected string"),a();(s=t.charCodeAt(e))-r;)92===s?(a(),s=a(),i+=v[s]||s):i+=a();return a()||l("Bad string"),["",i]};b("~",15,(e=>~e)),h("?",3,((e,t,r)=>e&&(t=n(2,58))&&["?",e,t,n(3)])),m("?",((e,t,r)=>(e=u(e),t=u(t),r=u(r),l=>e(l)?t(l):r(l)))),b("??",6,((e,t)=>e??t)),h("?.",18,(e=>e&&["?.",e])),m("?.",(e=>(e=u(e),t=>e(t)||(()=>{})))),h("?.",18,((e,t)=>e&&!(t=n(18))?.map&&["?.",e,t])),m("?.",((e,t)=>t&&(e=u(e),r=>e(r)?.[t]))),m("(",((e,t,r,l,a,n)=>null!=t&&"?."===e[0]&&(e[2]||Array.isArray(e[1]))&&(l=""==t?()=>[]:","===t[0]?(t=t.slice(1).map(u),e=>t.map((t=>t(e)))):(t=u(t),e=>[t(e)]),!e[2]&&(e=e[1]),a="["===e[0]?u(e[2]):t=>e[2],r=u(e[1]),e=>r(e)?.[a(e)]?.(...l(e))))),b("in",10,((e,t)=>e in t)),o[34]=B(34),o[39]=B(39),h("/*",20,((r,l)=>(a((r=>42!==r&&47!==t.charCodeAt(e+1))),a(2),r||n(l)||[""]))),h("//",20,((e,t)=>(a((e=>e>=32)),e||n(t)||[""]))),h("null",20,(e=>e?l():["",null])),h("true",20,(e=>e?l():["",!0])),h("false",20,(e=>e?l():["",!1])),b(";",-1,((...e)=>e[e.length-1])),b("**",-14,((e,t)=>e**t)),h("[",20,(e=>!e&&["[",n(0,93)||""])),m("[",((e,t)=>!t&&(e?","===e[0]?(e=e.slice(1).map(u),t=>e.map((e=>e(t)))):(e=u(e),t=>[e(t)]):()=>[]))),h("{",20,(e=>!e&&["{",n(0,125)||""])),m("{",((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=>({}))),h(":",1.1,((e,t)=>[":",e,n(1.1)||l()])),m(":",((e,t)=>(t=u(t),e=Array.isArray(e)?u(e):(e=>e).bind(0,e),r=>[e(r),t(r)])));export{c as binary,u as compile,t as cur,A as default,l as err,n as expr,p as id,e as idx,s as isId,o as lookup,g as nary,m as operator,d as operators,r as parse,b as set,a as skip,i as space,h as token,f as unary};
1
+ let r,e,t=t=>(r=0,e=t,t=i(),e[r]?a():t||""),a=(t="Bad syntax",a=e.slice(0,r).split("\n"),n=a.pop())=>{let i=e.slice(r-108,r).split("\n").pop(),s=e.slice(r,r+108).split("\n").shift();throw EvalError(`${t} at ${a.length}:${n.length} \`${r>=108?"…":""}${i}▶${s}\``,"font-weight: bold")},n=(t=1,a=r,n)=>{if("number"==typeof t)r+=t;else for(;n=t(e.charCodeAt(r));)r+=n;return e.slice(a,r)},i=(e=0,n,i,s,l,p)=>{for(;(i=t.space())&&(l=((p=o[i])&&p(s,e))??(!s&&t.id()));)s=l;return n&&(i==n?r++:a()),s},s=r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192&&215!=r&&247!=r,l=t.id=r=>n(s),p=t.space=t=>{for(;(t=e.charCodeAt(r))<=32;)r++;return t},o=[],c=(t,a=32,n,i=t.charCodeAt(0),l=t.length,p=o[i],c=t.toUpperCase()!==t)=>o[i]=(i,o,f=r)=>o<a&&(l<2||e.substr(r,l)==t)&&(!c||!s(e.charCodeAt(r+l)))&&(r+=l,n(i,o))||(r=f,p?.(i,o)),f=(r,e,t=0)=>c(r,e,((a,n)=>a&&(n=i(e-t/2))&&[r,a,n])),d=(r,e,t)=>c(r,e,(a=>t?a&&[r,a]:!a&&(a=i(e-.5))&&[r,a])),u=(r,e,t)=>{c(r,e,((a,n)=>(a||t)&&((n=i(e))||t)&&((!a||a[0]!==r)&&(a=[r,a]),(n||t)&&a.push(n),a)))};const m=r=>Array.isArray(r)?r[0]?h[r[0]](...r.slice(1)):()=>r[1]:e=>e?.[r],h={},b=(r,e,t=h[r])=>h[r]=(...r)=>e(...r)||t&&t(...r),A=(r,e,t)=>"()"===r[0]?A(r[1],e,t):"string"==typeof r?e.bind(0,(r=>r),(()=>r)):"."===r[0]?e.bind(0,m(r[1]),(r=r[2],()=>r)):"["===r[0]?e.bind(0,m(r[1]),m(r[2])):t?(r=m(r),e.bind(0,(e=>[r(e)]),(()=>0))):()=>a("Bad left value"),y=r=>r?a():[,(r=+n((r=>46===r||r>=48&&r<=57||(69===r||101===r?2:0))))!=r?a():r];o[46]=r=>!r&&y();for(let r=48;r<=57;r++)o[r]=y;const g={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},C=t=>(i,s,l="")=>{for(i&&a("Unexpected string"),n();(s=e.charCodeAt(r))-t;)92===s?(n(),s=n(),l+=g[s]||s):l+=n();return n()||a("Bad string"),[,l]};o[34]=C(34),o[39]=C(39),c("(",17,((r,e)=>r&&((e=i(0,41))?["(",r,e]:["(",r,""]))),b("(",((r,e,t)=>(t=""==e?()=>[]:","===e[0]?(e=e.slice(1).map(m),r=>e.map((e=>e(r)))):(e=m(e),r=>[e(r)]),A(r,((r,e,a)=>r(a)[e(a)](...t(a))),!0)))),c("[",17,(r=>r&&["[",r,i(0,93)||a()])),b("[",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)[e(t)]))),c(".",17,((r,e)=>r&&(e=i(17))&&[".",r,e])),b(".",((r,e)=>(r=m(r),e=e[0]?e:e[1],t=>r(t)[e]))),c("(",17,(r=>!r&&["()",i(0,41)||a("Empty group")])),b("()",(r=>m(r)));const $=(...r)=>(r=r.map(m),e=>r.map((r=>r(e))).pop());u(",",1),b(",",$),u(";",1,!0),b(";",$),f("*",12),b("*",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)*e(t)))),f("/",12),b("/",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)/e(t)))),f("%",12),b("%",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)%e(t)))),f("*=",2,!0),b("*=",((r,e)=>(e=m(e),A(r,((r,t,a)=>r(a)[t(a)]*=e(a)))))),f("/=",2,!0),b("/=",((r,e)=>(e=m(e),A(r,((r,t,a)=>r(a)[t(a)]/=e(a)))))),f("%=",2,!0),b("%=",((r,e)=>(e=m(e),A(r,((r,t,a)=>r(a)[t(a)]%=e(a)))))),d("+",14),b("+",((r,e)=>!e&&(r=m(r),e=>+r(e)))),d("-",14),b("-",((r,e)=>!e&&(r=m(r),e=>-r(e)))),f("+",11),b("+",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)+e(t)))),f("-",11),b("-",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)-e(t)))),f("+=",2,!0),b("+=",((r,e)=>(e=m(e),A(r,((r,t,a)=>r(a)[t(a)]+=e(a)))))),f("-=",2,!0),b("-=",((r,e)=>(e=m(e),A(r,((r,t,a)=>r(a)[t(a)]-=e(a)))))),c("++",15,(r=>r?["-",["++",r],[,1]]:["++",i(14)])),b("++",(r=>A(r,((r,e,t)=>++r(t)[e(t)])))),c("--",15,(r=>r?["+",["--",r],[,1]]:["--",i(14)])),b("--",(r=>A(r,((r,e,t)=>--r(t)[e(t)])))),d("~",14),b("~",((r,e)=>!e&&(r=m(r),e=>~r(e)))),f("|",5),b("|",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)|e(t)))),f("&",7),b("&",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)&e(t)))),f("^",6),b("^",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)^e(t)))),f(">>",10),b(">>",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)>>e(t)))),f("<<",10),b("<<",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)<<e(t)))),f("==",8),b("==",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)==e(t)))),f("!=",8),b("!=",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)!=e(t)))),f(">",8),b(">",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)>e(t)))),f("<",8),b("<",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)<e(t)))),f(">=",8),b(">=",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)>=e(t)))),f("<=",8),b("<=",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)<=e(t)))),d("!",14),b("!",((r,e)=>!e&&(r=m(r),e=>!r(e)))),u("||",3),b("||",((...r)=>(r=r.map(m),e=>{let t,a;for(t of r)if(a=t(e))return a;return a}))),u("&&",4),b("&&",((...r)=>(r=r.map(m),e=>{let t,a;for(t of r)if(!(a=t(e)))return a;return a}))),f("=",2,!0),b("=",((r,e)=>(e=m(e),A(r,((r,t,a)=>r(a)[t(a)]=e(a))))));var v=r=>m(t(r));c("/*",20,((t,a)=>(n((t=>42!==t&&47!==e.charCodeAt(r+1))),n(2),t||i(a)||[""]))),c("//",20,((r,e)=>(n((r=>r>=32)),r||i(e)||[""]))),f("**",13,!0),b("**",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)**e(t)))),f("in",9),b("in",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)in e(t)))),c("?",2,((r,e,t)=>r&&(e=i(2,58))&&["?",r,e,i(3)])),b("?",((r,e,t)=>(r=m(r),e=m(e),t=m(t),a=>r(a)?e(a):t(a)))),c("true",20,(r=>r?err():[,!0])),c("false",20,(r=>r?err():[,!1])),c("[",20,(r=>!r&&["[",i(0,93)||""])),b("[",((r,e)=>!e&&(r?","===r[0]?(r=r.slice(1).map(m),e=>r.map((r=>r(e)))):(r=m(r),e=>[r(e)]):()=>[]))),c("{",20,(r=>!r&&["{",i(0,125)||""])),b("{",((r,e)=>r?","===r[0]?(r=r.slice(1).map(m),e=>Object.fromEntries(r.map((r=>r(e))))):":"===r[0]?(r=m(r),e=>Object.fromEntries([r(e)])):(e=m(r),t=>({[r]:e(t)})):r=>({}))),c(":",1.1,((r,e)=>[":",r,i(1.1)||err()])),b(":",((r,e)=>(e=m(e),r=Array.isArray(r)?m(r):(r=>r).bind(0,r),t=>[r(t),e(t)]))),f("??",5),b("??",((r,e)=>e&&(r=m(r),e=m(e),t=>r(t)??e(t)))),c("?.",17,(r=>r&&["?.",r])),b("?.",(r=>(r=m(r),e=>r(e)||(()=>{})))),c("?.",17,((r,e)=>r&&!(e=i(17))?.map&&["?.",r,e])),b("?.",((r,e)=>e&&(r=m(r),t=>r(t)?.[e]))),b("(",((r,e,t,a,n,i)=>null!=e&&"?."===r[0]&&(r[2]||Array.isArray(r[1]))&&(a=""==e?()=>[]:","===e[0]?(e=e.slice(1).map(m),r=>e.map((e=>e(r)))):(e=m(e),r=>[e(r)]),!r[2]&&(r=r[1]),n="["===r[0]?m(r[2]):()=>r[2],t=m(r[1]),r=>t(r)?.[n(r)]?.(...a(r))))),c("null",20,(r=>r?a():[,null]));export{A as access,f as binary,m as compile,e as cur,v as default,a as err,i as expr,l as id,r as idx,s as isId,o as lookup,u as nary,b as operator,h as operators,t as parse,n as skip,p as space,c as token,d as unary};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "subscript",
3
- "version": "7.6.2",
3
+ "version": "8.0.1",
4
4
  "description": "Fast and tiny expression evaluator with minimal syntax.",
5
5
  "main": "subscript.js",
6
6
  "module": "subscript.js",
@@ -8,15 +8,15 @@
8
8
  "types": "./subscript.d.ts",
9
9
  "exports": {
10
10
  ".": "./subscript.js",
11
- "./parse.js": "./parse.js",
12
- "./compile.js": "./compile.js",
11
+ "./parse.js": "./src/parse.js",
12
+ "./compile.js": "./src/compile.js",
13
13
  "./subscript.js": "./subscript.js",
14
14
  "./justin.js": "./justin.js"
15
15
  },
16
16
  "type": "module",
17
17
  "files": [
18
- "parse.js",
19
- "compile.js",
18
+ "src",
19
+ "feature",
20
20
  "subscript.js",
21
21
  "subscript.min.js",
22
22
  "justin.js",
@@ -0,0 +1,17 @@
1
+ export type OperatorFunction = (...args: any[]) => any;
2
+ export type OperatorMap = {
3
+ [key: string]: OperatorFunction;
4
+ };
5
+ export type Node = string | [string | undefined, ...Node[]];
6
+ export function compile(node: Node): ((ctx?: any) => any) | OperatorFunction;
7
+ export const operators: OperatorMap;
8
+ export function operator(op: string, fn: OperatorFunction): void;
9
+
10
+ type AccessorFunction = (ctx: any) => any;
11
+ export function access(
12
+ a: [string, ...any[]] | string,
13
+ fn: Function,
14
+ generic: boolean
15
+ ): AccessorFunction;
16
+
17
+ export default compile;
package/src/compile.js ADDED
@@ -0,0 +1,26 @@
1
+ import { err } from "./parse.js"
2
+
3
+ // build optimized evaluator for the tree
4
+ export const compile = (node) => !Array.isArray(node) ? ctx => ctx?.[node] : !node[0] ? () => node[1] : operators[node[0]](...node.slice(1)),
5
+
6
+ // registered operators
7
+ operators = {},
8
+
9
+ // register an operator
10
+ operator = (op, fn, prev = operators[op]) => (operators[op] = (...args) => fn(...args) || prev && prev(...args)),
11
+
12
+ // takes node and returns evaluator depending on the case with passed params (container, path, ctx) =>
13
+ access = (a, fn, generic) => (
14
+ // (((x))) => x
15
+ a[0] === '()' ? access(a[1], fn, generic) :
16
+ // (_, name, ctx) => ctx[path]
17
+ typeof a === 'string' ? fn.bind(0, ctx => ctx, () => a) :
18
+ // (container, path, ctx) => container(ctx)[path]
19
+ a[0] === '.' ? fn.bind(0, compile(a[1]), (a = a[2], () => a)) :
20
+ // (container, path, ctx) => container(ctx)[path(ctx)]
21
+ a[0] === '[' ? fn.bind(0, compile(a[1]), compile(a[2])) :
22
+ // (src, _, ctx) => src(ctx)
23
+ generic ? (a = compile(a), fn.bind(0, ctx => [a(ctx)], () => 0)) : () => err('Bad left value')
24
+ )
25
+
26
+ export default compile
package/src/const.js ADDED
@@ -0,0 +1,40 @@
1
+ export const
2
+ PERIOD = 46,
3
+ OPAREN = 40,
4
+ CPAREN = 41,
5
+ OBRACK = 91,
6
+ CBRACK = 93,
7
+ OBRACE = 123,
8
+ CBRACE = 125,
9
+ SPACE = 32,
10
+ COLON = 58,
11
+ DQUOTE = 34,
12
+ QUOTE = 39,
13
+ _0 = 48,
14
+ _9 = 57,
15
+ _E = 69,
16
+ _e = 101,
17
+ BSLASH = 92,
18
+ SLASH = 47,
19
+ STAR = 42
20
+
21
+ // ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence
22
+ export const
23
+ PREC_SEQ = 1,
24
+ PREC_ASSIGN = 2,
25
+ PREC_LOR = 3,
26
+ PREC_LAND = 4,
27
+ PREC_OR = 5,
28
+ PREC_XOR = 6,
29
+ PREC_AND = 7,
30
+ PREC_EQ = 8,
31
+ PREC_COMP = 9,
32
+ PREC_SHIFT = 10,
33
+ PREC_ADD = 11,
34
+ PREC_MULT = 12,
35
+ PREC_EXP = 13,
36
+ PREC_PREFIX = 14,
37
+ PREC_POSTFIX = 15,
38
+ PREC_ACCESS = 17,
39
+ PREC_GROUP = 18,
40
+ PREC_TOKEN = 20
package/src/parse.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export let idx: any;
2
+ export let cur: any;
3
+ export function parse(s: string): any;
4
+ export namespace parse {
5
+ function space(cc: any): any;
6
+ function id(n: any): any;
7
+ }
8
+ export function err(msg?: string, frag?: string): never;
9
+ export function skip(is: number | ((c: number) => number)): string;
10
+ export const lookup: ((a: any, b: any) => any)[];
11
+ export function token(op: string, prec: number, map: (a: any, curPrec: number, from: number) => any): (a: any, curPrec: number, from?: any) => any;
12
+ export function binary(op: string, prec: number, right?: boolean | undefined): (a: any, curPrec: number, from?: any) => any;
13
+ export function unary(op: string, prec: number, post?: boolean | undefined): (a: any, curPrec: number, from?: any) => any;
14
+ export function nary(op: string, prec: number, skips?: boolean | undefined): (a: any, curPrec: number, from?: any) => any;
15
+ export function expr(prec: number, end?: string | undefined): any;
16
+ export function isId(c: number): boolean;
17
+ export function space(): number;
18
+ export function id(): string;
19
+ export default parse;
@@ -1,4 +1,4 @@
1
- const SPACE = 32
1
+ import { SPACE } from "./const.js"
2
2
 
3
3
  // current string, index and collected ids
4
4
  export let idx, cur,
@@ -7,13 +7,12 @@ export let idx, cur,
7
7
  parse = s => (idx = 0, cur = s, s = expr(), cur[idx] ? err() : s || ''),
8
8
 
9
9
  err = (msg = 'Bad syntax',
10
- frag = cur[idx],
11
10
  lines = cur.slice(0, idx).split('\n'),
12
11
  last = lines.pop()
13
12
  ) => {
14
13
  let before = cur.slice(idx - 108, idx).split('\n').pop()
15
- let after = cur.slice(idx + 1, idx + 108).split('\n').shift()
16
- throw EvalError(`${msg} at ${lines.length}:${last.length} \`${before + frag + after}\``, 'font-weight: bold')
14
+ let after = cur.slice(idx, idx + 108).split('\n').shift()
15
+ throw EvalError(`${msg} at ${lines.length}:${last.length} \`${idx >= 108 ? '…' : ''}${before}▶${after}\``, 'font-weight: bold')
17
16
  },
18
17
 
19
18
  skip = (is = 1, from = idx, l) => {
@@ -49,11 +48,12 @@ export let idx, cur,
49
48
  c == 36 || c == 95 || // $, _,
50
49
  (c >= 192 && c != 215 && c != 247), // any non-ASCII
51
50
 
51
+ // parse identifier (configurable)
52
+ id = parse.id = n => skip(isId),
53
+
52
54
  // skip space chars, return first non-space character
53
55
  space = parse.space = cc => { while ((cc = cur.charCodeAt(idx)) <= SPACE) idx++; return cc },
54
56
 
55
- id = parse.id = n => skip(isId),
56
-
57
57
  // operator/token lookup table
58
58
  // lookup[0] is id parser to let configs redefine it
59
59
  lookup = [],
package/subscript.js CHANGED
@@ -1,127 +1,22 @@
1
- import parse, { lookup, nary, binary, unary, token, skip, err, expr } from './parse.js'
2
- import compile, { operator } from './compile.js'
3
-
4
- const OPAREN = 40, CPAREN = 41, OBRACK = 91, CBRACK = 93, SPACE = 32, DQUOTE = 34, PERIOD = 46, _0 = 48, _9 = 57,
5
- PREC_SEQ = 1, PREC_SOME = 4, PREC_EVERY = 5, PREC_OR = 6, PREC_XOR = 7, PREC_AND = 8,
6
- PREC_EQ = 9, PREC_COMP = 10, PREC_SHIFT = 11, PREC_SUM = 12, PREC_MULT = 13, PREC_UNARY = 15, PREC_POSTFIX = 16, PREC_CALL = 18
7
-
8
- const subscript = s => (s = parse(s), ctx => (s.call ? s : (s = compile(s)))(ctx)),
9
-
10
- // set any operator
11
- // right assoc is indicated by negative precedence (meaning go from right to left)
12
- set = (op, prec, fn) => (
13
- !fn.length ? (
14
- nary(op, Math.abs(prec), prec < 0),
15
- operator(op, (...args) => (args = args.map(compile), ctx => fn(...args.map(arg => arg(ctx)))))
16
- ) :
17
- fn.length > 1 ? (
18
- binary(op, Math.abs(prec), prec < 0),
19
- operator(op,
20
- (a, b) => b && (a = compile(a), b = compile(b), !a.length && !b.length ? (a = fn(a(), b()), () => a) : ctx => fn(a(ctx), b(ctx)))
21
- )
22
- ) :
23
- (
24
- unary(op, prec),
25
- operator(op, (a, b) => !b && (a = compile(a), !a.length ? (a = fn(a()), () => a) : ctx => fn(a(ctx))))
26
- )
27
- ),
28
-
29
- num = a => a ? err() : ['', (a = +skip(c => c === PERIOD || (c >= _0 && c <= _9) || (c === 69 || c === 101 ? 2 : 0))) != a ? err() : a],
30
-
31
- // create increment-assign pair from fn
32
- inc = (op, prec, fn, ev) => (
33
- token(op, prec, a => a ? [op === '++' ? '-' : '+', [op, a], ['', 1]] : [op, expr(prec - 1)]), // ++a → [++, a], a++ → [-,[++,a],1]
34
- operator(op, ev = (a, b) => (
35
- a[0] === '(' ? ev(a[1]) : // ++(((a)))
36
- a[0] === '.' ? (b = a[2], a = compile(a[1]), ctx => fn(a(ctx), b)) : // ++a.b
37
- a[0] === '[' ? ([, a, b] = a, a = compile(a), b = compile(b), ctx => fn(a(ctx), b(ctx))) : // ++a[b]
38
- (ctx => fn(ctx, a)) // ++a
39
- ))
40
- )
41
-
42
- // literals
43
- // null operator returns first value (needed for direct literals)
44
- operator('', v => () => v)
45
-
46
- // "a"
47
- lookup[DQUOTE] = (a) => (a ? err() : ['', (skip() + skip(c => c - DQUOTE ? 1 : 0) + (skip() || err('Bad string'))).slice(1, -1)])
48
-
49
- // .1
50
- lookup[PERIOD] = a => (!a && num())
51
-
52
- // 0-9
53
- for (let i = 0; i <= 9; i++) lookup[_0 + i] = num
54
-
55
- // sequences
56
- set(',', PREC_SEQ, (...args) => args[args.length - 1])
57
- set('||', PREC_SOME, (...args) => { let i = 0, v; for (; !v && i < args.length;) v = args[i++]; return v })
58
- set('&&', PREC_EVERY, (...args) => { let i = 0, v = true; for (; v && i < args.length;) v = args[i++]; return v })
59
-
60
- // assignment
61
- binary('=', 10, true)
62
- operator('=', (a, b) => {
63
- let calc = compile(b), container, path,
64
- set = typeof a === 'string' ? (ctx, v) => ctx[a] = v :
65
- a[0] === '.' ? (container = compile(a[1]), path = a[2], (ctx, v) => container(ctx)[path] = v) :
66
- a[0] === '[' ? (container = compile(a[1]), path = compile(a[2]), (ctx, v) => container(ctx)[path(ctx)] = v) :
67
- err('Bad left value');
68
- return ctx => set(ctx, calc(ctx))
69
- })
70
-
71
- // binaries
72
- set('+', PREC_SUM, (a, b) => a + b)
73
- set('-', PREC_SUM, (a, b) => a - b)
74
- set('*', PREC_MULT, (a, b) => a * b)
75
- set('/', PREC_MULT, (a, b) => a / b)
76
- set('%', PREC_MULT, (a, b) => a % b)
77
- set('|', PREC_OR, (a, b) => a | b)
78
- set('&', PREC_AND, (a, b) => a & b)
79
- set('^', PREC_XOR, (a, b) => a ^ b)
80
- set('==', PREC_EQ, (a, b) => a == b)
81
- set('!=', PREC_EQ, (a, b) => a != b)
82
- set('>', PREC_COMP, (a, b) => a > b)
83
- set('>=', PREC_COMP, (a, b) => a >= b)
84
- set('<', PREC_COMP, (a, b) => a < b)
85
- set('<=', PREC_COMP, (a, b) => a <= b)
86
- set('>>', PREC_SHIFT, (a, b) => a >> b)
87
- set('>>>', PREC_SHIFT, (a, b) => a >>> b)
88
- set('<<', PREC_SHIFT, (a, b) => a << b)
89
-
90
- // unaries
91
- set('+', PREC_UNARY, a => +a)
92
- set('-', PREC_UNARY, a => -a)
93
- set('!', PREC_UNARY, a => !a)
94
-
95
- // increments
96
- inc('++', PREC_UNARY, (a, b) => ++a[b])
97
- inc('--', PREC_UNARY, (a, b) => --a[b])
98
-
99
- // a[b]
100
- token('[', PREC_CALL, a => a && ['[', a, expr(0, CBRACK) || err()])
101
- operator('[', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx)[b(ctx)]))
102
-
103
- // a.b
104
- token('.', PREC_CALL, (a, b) => a && (b = expr(PREC_CALL)) && ['.', a, b])
105
- operator('.', (a, b) => (a = compile(a), b = !b[0] ? b[1] : b, ctx => a(ctx)[b])) // a.true, a.1 → needs to work fine
106
-
107
- // (a,b,c), (a)
108
- token('(', PREC_CALL, a => !a && ['(', expr(0, CPAREN) || err()])
109
-
110
- // a(b,c,d), a()
111
- token('(', PREC_CALL, (a, b) => a && (b = expr(0, CPAREN), b ? ['(', a, b] : ['(', a, '']))
112
- operator('(', (a, b, path, container, args) => b == null ? (compile(a, b)) : (
113
- args = b == '' ? () => [] : // a()
114
- b[0] === ',' ? (b = b.slice(1).map(compile), ctx => b.map(arg => arg(ctx))) : // a(b,c)
115
- (b = compile(b), ctx => [b(ctx)]), // a(b)
116
-
117
- a[0] === '.' ? (path = a[2], a = compile(a[1]), ctx => a(ctx)[path](...args(ctx))) : // a.b(...args)
118
- a[0] === '[' ? (path = compile(a[2]), a = compile(a[1]), ctx => a(ctx)[path(ctx)](...args(ctx))) : // a[b](...args)
119
- (a = compile(a), ctx => a(ctx)(...args(ctx))) // a(...args)
120
- )
121
- )
122
-
123
-
124
- export default subscript
125
- export { set }
126
- export * from './parse.js'
127
- export * from './compile.js'
1
+ /**
2
+ * Subscript dialect includes common operators / primitives for all languages
3
+ */
4
+ import './feature/number.js'
5
+ import './feature/string.js'
6
+ import './feature/call.js'
7
+ import './feature/access.js'
8
+ import './feature/group.js'
9
+ import './feature/mult.js'
10
+ import './feature/add.js'
11
+ import './feature/increment.js'
12
+ import './feature/bitwise.js'
13
+ import './feature/compare.js'
14
+ import './feature/logic.js'
15
+ import './feature/assign.js'
16
+ import compile from './src/compile.js'
17
+ import parse from './src/parse.js'
18
+
19
+ export * from './src/parse.js'
20
+ export * from './src/compile.js'
21
+
22
+ export default s => compile(parse(s))
package/subscript.min.js CHANGED
@@ -1 +1 @@
1
- let e,t,l=l=>(e=0,t=l,l=n(),t[e]?r():l||""),r=(l="Bad syntax",r=t[e],a=t.slice(0,e).split("\n"),n=a.pop())=>{let s=t.slice(e-108,e).split("\n").pop(),h=t.slice(e+1,e+108).split("\n").shift();throw EvalError(`${l} at ${a.length}:${n.length} \`${s+r+h}\``,"font-weight: bold")},a=(l=1,r=e,a)=>{if("number"==typeof l)e+=l;else for(;a=l(t.charCodeAt(e));)e+=a;return t.slice(r,e)},n=(t=0,a,n,s,h,o)=>{for(;(n=l.space())&&(h=((o=p[n])&&o(s,t))??(!s&&l.id()));)s=h;return a&&(n==a?e++:r()),s},s=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,h=l.space=l=>{for(;(l=t.charCodeAt(e))<=32;)e++;return l},o=l.id=e=>a(s),p=[],i=(l,r=32,a,n=l.charCodeAt(0),h=l.length,o=p[n],i=l.toUpperCase()!==l)=>p[n]=(n,p,c=e)=>p<r&&(h<2||t.substr(e,h)==l)&&(!i||!s(t.charCodeAt(e+h)))&&(e+=h,a(n,p))||(e=c,o?.(n,p)),c=(e,t,l=0)=>i(e,t,((r,a)=>r&&(a=n(t-l/2))&&[e,r,a])),g=(e,t,l)=>i(e,t,(r=>l?r&&[e,r]:!r&&(r=n(t-.5))&&[e,r])),f=(e,t,l)=>{i(e,t,((r,a)=>(r||l)&&((a=n(t))||l)&&((!r||r[0]!==e)&&(r=[e,r]),(a||l)&&r.push(a),r)))};const u=e=>Array.isArray(e)?d[e[0]](...e.slice(1)):t=>t?.[e],d={},A=(e,t,l=d[e])=>d[e]=(...e)=>t(...e)||l&&l(...e),b=e=>(e=l(e),t=>(e.call?e:e=u(e))(t)),m=(e,t,l)=>l.length?l.length>1?(c(e,Math.abs(t),t<0),A(e,((e,t)=>t&&(e=u(e),t=u(t),e.length||t.length?r=>l(e(r),t(r)):(e=l(e(),t()),()=>e))))):(g(e,t),A(e,((e,t)=>!t&&((e=u(e)).length?t=>l(e(t)):(e=l(e()),()=>e))))):(f(e,Math.abs(t),t<0),A(e,((...e)=>(e=e.map(u),t=>l(...e.map((e=>e(t)))))))),y=e=>e?r():["",(e=+a((e=>46===e||e>=48&&e<=57||(69===e||101===e?2:0))))!=e?r():e],C=(e,t,l,r)=>(i(e,t,(l=>l?["++"===e?"-":"+",[e,l],["",1]]:[e,n(t-1)])),A(e,r=(e,t)=>"("===e[0]?r(e[1]):"."===e[0]?(t=e[2],e=u(e[1]),r=>l(e(r),t)):"["===e[0]?([,e,t]=e,e=u(e),t=u(t),r=>l(e(r),t(r))):t=>l(t,e)));A("",(e=>()=>e)),p[34]=e=>e?r():["",(a()+a((e=>e-34?1:0))+(a()||r("Bad string"))).slice(1,-1)],p[46]=e=>!e&&y();for(let e=0;e<=9;e++)p[48+e]=y;m(",",1,((...e)=>e[e.length-1])),m("||",4,((...e)=>{let t,l=0;for(;!t&&l<e.length;)t=e[l++];return t})),m("&&",5,((...e)=>{let t=0,l=!0;for(;l&&t<e.length;)l=e[t++];return l})),c("=",10,!0),A("=",((e,t)=>{let l,a,n=u(t),s="string"==typeof e?(t,l)=>t[e]=l:"."===e[0]?(l=u(e[1]),a=e[2],(e,t)=>l(e)[a]=t):"["===e[0]?(l=u(e[1]),a=u(e[2]),(e,t)=>l(e)[a(e)]=t):r("Bad left value");return e=>s(e,n(e))})),m("+",12,((e,t)=>e+t)),m("-",12,((e,t)=>e-t)),m("*",13,((e,t)=>e*t)),m("/",13,((e,t)=>e/t)),m("%",13,((e,t)=>e%t)),m("|",6,((e,t)=>e|t)),m("&",8,((e,t)=>e&t)),m("^",7,((e,t)=>e^t)),m("==",9,((e,t)=>e==t)),m("!=",9,((e,t)=>e!=t)),m(">",10,((e,t)=>e>t)),m(">=",10,((e,t)=>e>=t)),m("<",10,((e,t)=>e<t)),m("<=",10,((e,t)=>e<=t)),m(">>",11,((e,t)=>e>>t)),m(">>>",11,((e,t)=>e>>>t)),m("<<",11,((e,t)=>e<<t)),m("+",15,(e=>+e)),m("-",15,(e=>-e)),m("!",15,(e=>!e)),C("++",15,((e,t)=>++e[t])),C("--",15,((e,t)=>--e[t])),i("[",18,(e=>e&&["[",e,n(0,93)||r()])),A("[",((e,t)=>t&&(e=u(e),t=u(t),l=>e(l)[t(l)]))),i(".",18,((e,t)=>e&&(t=n(18))&&[".",e,t])),A(".",((e,t)=>(e=u(e),t=t[0]?t:t[1],l=>e(l)[t]))),i("(",18,(e=>!e&&["(",n(0,41)||r()])),i("(",18,((e,t)=>e&&((t=n(0,41))?["(",e,t]:["(",e,""]))),A("(",((e,t,l,r,a)=>null==t?u(e):(a=""==t?()=>[]:","===t[0]?(t=t.slice(1).map(u),e=>t.map((t=>t(e)))):(t=u(t),e=>[t(e)]),"."===e[0]?(l=e[2],e=u(e[1]),t=>e(t)[l](...a(t))):"["===e[0]?(l=u(e[2]),e=u(e[1]),t=>e(t)[l(t)](...a(t))):(e=u(e),t=>e(t)(...a(t))))));export{c as binary,u as compile,t as cur,b as default,r as err,n as expr,o as id,e as idx,s as isId,p as lookup,f as nary,A as operator,d as operators,l as parse,m as set,a as skip,h as space,i as token,g as unary};
1
+ let t,r,e=e=>(t=0,r=e,e=s(),r[t]?n():e||""),n=(e="Bad syntax",n=r.slice(0,t).split("\n"),o=n.pop())=>{let s=r.slice(t-108,t).split("\n").pop(),a=r.slice(t,t+108).split("\n").shift();throw EvalError(`${e} at ${n.length}:${o.length} \`${t>=108?"…":""}${s}▶${a}\``,"font-weight: bold")},o=(e=1,n=t,o)=>{if("number"==typeof e)t+=e;else for(;o=e(r.charCodeAt(t));)t+=o;return r.slice(n,t)},s=(r=0,o,s,a,p,i)=>{for(;(s=e.space())&&(p=((i=l[s])&&i(a,r))??(!a&&e.id()));)a=p;return o&&(s==o?t++:n()),a},a=t=>t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122||36==t||95==t||t>=192&&215!=t&&247!=t,p=e.id=t=>o(a),i=e.space=e=>{for(;(e=r.charCodeAt(t))<=32;)t++;return e},l=[],f=(e,n=32,o,s=e.charCodeAt(0),p=e.length,i=l[s],f=e.toUpperCase()!==e)=>l[s]=(s,l,c=t)=>l<n&&(p<2||r.substr(t,p)==e)&&(!f||!a(r.charCodeAt(t+p)))&&(t+=p,o(s,l))||(t=c,i?.(s,l)),c=(t,r,e=0)=>f(t,r,((n,o)=>n&&(o=s(r-e/2))&&[t,n,o])),d=(t,r,e)=>f(t,r,(n=>e?n&&[t,n]:!n&&(n=s(r-.5))&&[t,n])),u=(t,r,e)=>{f(t,r,((n,o)=>(n||e)&&((o=s(r))||e)&&((!n||n[0]!==t)&&(n=[t,n]),(o||e)&&n.push(o),n)))};const h=t=>t?n():[,(t=+o((t=>46===t||t>=48&&t<=57||(69===t||101===t?2:0))))!=t?n():t];l[46]=t=>!t&&h();for(let t=48;t<=57;t++)l[t]=h;const b={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},g=e=>(s,a,p="")=>{for(s&&n("Unexpected string"),o();(a=r.charCodeAt(t))-e;)92===a?(o(),a=o(),p+=b[a]||a):p+=o();return o()||n("Bad string"),[,p]};l[34]=g(34),l[39]=g(39);const m=t=>Array.isArray(t)?t[0]?A[t[0]](...t.slice(1)):()=>t[1]:r=>r?.[t],A={},y=(t,r,e=A[t])=>A[t]=(...t)=>r(...t)||e&&e(...t),C=(t,r,e)=>"()"===t[0]?C(t[1],r,e):"string"==typeof t?r.bind(0,(t=>t),(()=>t)):"."===t[0]?r.bind(0,m(t[1]),(t=t[2],()=>t)):"["===t[0]?r.bind(0,m(t[1]),m(t[2])):e?(t=m(t),r.bind(0,(r=>[t(r)]),(()=>0))):()=>n("Bad left value");f("(",17,((t,r)=>t&&((r=s(0,41))?["(",t,r]:["(",t,""]))),y("(",((t,r,e)=>(e=""==r?()=>[]:","===r[0]?(r=r.slice(1).map(m),t=>r.map((r=>r(t)))):(r=m(r),t=>[r(t)]),C(t,((t,r,n)=>t(n)[r(n)](...e(n))),!0)))),f("[",17,(t=>t&&["[",t,s(0,93)||n()])),y("[",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)[r(e)]))),f(".",17,((t,r)=>t&&(r=s(17))&&[".",t,r])),y(".",((t,r)=>(t=m(t),r=r[0]?r:r[1],e=>t(e)[r]))),f("(",17,(t=>!t&&["()",s(0,41)||n("Empty group")])),y("()",(t=>m(t)));const $=(...t)=>(t=t.map(m),r=>t.map((t=>t(r))).pop());u(",",1),y(",",$),u(";",1,!0),y(";",$),c("*",12),y("*",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)*r(e)))),c("/",12),y("/",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)/r(e)))),c("%",12),y("%",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)%r(e)))),c("*=",2,!0),y("*=",((t,r)=>(r=m(r),C(t,((t,e,n)=>t(n)[e(n)]*=r(n)))))),c("/=",2,!0),y("/=",((t,r)=>(r=m(r),C(t,((t,e,n)=>t(n)[e(n)]/=r(n)))))),c("%=",2,!0),y("%=",((t,r)=>(r=m(r),C(t,((t,e,n)=>t(n)[e(n)]%=r(n)))))),d("+",14),y("+",((t,r)=>!r&&(t=m(t),r=>+t(r)))),d("-",14),y("-",((t,r)=>!r&&(t=m(t),r=>-t(r)))),c("+",11),y("+",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)+r(e)))),c("-",11),y("-",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)-r(e)))),c("+=",2,!0),y("+=",((t,r)=>(r=m(r),C(t,((t,e,n)=>t(n)[e(n)]+=r(n)))))),c("-=",2,!0),y("-=",((t,r)=>(r=m(r),C(t,((t,e,n)=>t(n)[e(n)]-=r(n)))))),f("++",15,(t=>t?["-",["++",t],[,1]]:["++",s(14)])),y("++",(t=>C(t,((t,r,e)=>++t(e)[r(e)])))),f("--",15,(t=>t?["+",["--",t],[,1]]:["--",s(14)])),y("--",(t=>C(t,((t,r,e)=>--t(e)[r(e)])))),d("~",14),y("~",((t,r)=>!r&&(t=m(t),r=>~t(r)))),c("|",5),y("|",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)|r(e)))),c("&",7),y("&",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)&r(e)))),c("^",6),y("^",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)^r(e)))),c(">>",10),y(">>",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)>>r(e)))),c("<<",10),y("<<",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)<<r(e)))),c("==",8),y("==",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)==r(e)))),c("!=",8),y("!=",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)!=r(e)))),c(">",8),y(">",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)>r(e)))),c("<",8),y("<",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)<r(e)))),c(">=",8),y(">=",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)>=r(e)))),c("<=",8),y("<=",((t,r)=>r&&(t=m(t),r=m(r),e=>t(e)<=r(e)))),d("!",14),y("!",((t,r)=>!r&&(t=m(t),r=>!t(r)))),u("||",3),y("||",((...t)=>(t=t.map(m),r=>{let e,n;for(e of t)if(n=e(r))return n;return n}))),u("&&",4),y("&&",((...t)=>(t=t.map(m),r=>{let e,n;for(e of t)if(!(n=e(r)))return n;return n}))),c("=",2,!0),y("=",((t,r)=>(r=m(r),C(t,((t,e,n)=>t(n)[e(n)]=r(n))))));var v=t=>m(e(t));export{C as access,c as binary,m as compile,r as cur,v as default,n as err,s as expr,p as id,t as idx,a as isId,l as lookup,u as nary,y as operator,A as operators,e as parse,o as skip,i as space,f as token,d as unary};
package/compile.js DELETED
@@ -1,8 +0,0 @@
1
- // build optimized evaluator for the tree
2
- export const compile = (node) => !Array.isArray(node) ? ctx => ctx?.[node] : operators[node[0]](...node.slice(1)),
3
-
4
- operators = {},
5
-
6
- operator = (op, fn, prev = operators[op]) => (operators[op] = (...args) => fn(...args) || prev && prev(...args))
7
-
8
- export default compile