subscript 8.0.0 → 8.1.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,8 +1,8 @@
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="https://bundlephobia.com/package/subscript"><img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/subscript/latest?color=brightgreen&label=gzip"/></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>
1
+ # sub<em>script</em> <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="https://bundlephobia.com/package/subscript"><img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/subscript/latest?color=brightgreen&label=gzip"/></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
3
  > _Subscript_ is fast, tiny & extensible expression evaluator / microlanguage.
4
4
 
5
- Used for:
5
+ #### Used for:
6
6
 
7
7
  * templates (eg. [sprae](https://github.com/dy/sprae), [templize](https://github.com/dy/templize))
8
8
  * expressions evaluators, calculators
@@ -82,7 +82,7 @@ fn = compile(tree)
82
82
  fn({ a: {b: 1}, c: 2 }) // 3
83
83
  ```
84
84
 
85
- ## Syntax Tree
85
+ ### Syntax Tree
86
86
 
87
87
  AST has simplified lispy tree structure (inspired by [frisk](https://ghub.io/frisk) / [nisp](https://github.com/ysmood/nisp)), opposed to [ESTree](https://github.com/estree/estree):
88
88
 
@@ -90,34 +90,52 @@ AST has simplified lispy tree structure (inspired by [frisk](https://ghub.io/fri
90
90
  * reflects execution sequence, rather than code layout;
91
91
  * has minimal overhead, directly maps to operators;
92
92
  * simplifies manual evaluation and debugging;
93
- * has conventional form and one-line docs:
93
+ * has conventional form and one-liner docs:
94
94
 
95
95
  ```js
96
96
  import { compile } from 'subscript.js'
97
97
 
98
98
  const fn = compile(['+', ['*', 'min', [,60]], [,'sec']])
99
-
100
99
  fn({min: 5}) // min*60 + "sec" == "300sec"
100
+
101
+ // node kinds
102
+ ['+', a]; // unary prefix or postfix operator `+a`
103
+ ['+', a, b]; // binary operator `a + b`
104
+ ['+', a, b, c]; // n-ary operator `a + b + c`
105
+ ['()', a]; // group operator `(a)`
106
+ ['(', a, b]; // access operator `a(b)`
107
+ [, a]; // literal value `'a'`
108
+ a; // variable (from scope)
101
109
  ```
102
110
 
103
111
  ## Extending
104
112
 
105
- _Subscript_ provides API to customize or extend syntax:
113
+ _Subscript_ provides pluggable language [features](./features) and API to customize syntax:
106
114
 
107
- * `unary(str, precedence, postfix=false)` − register unary operator, either prefix or postfix.
108
- * `binary(str, precedence, rightAssoc=false)` − register binary operator, optionally right-associative.
109
- * `nary(str, precedence, allowSkip=false)` − register n-ary (sequence) operator, optionally allowing skipping args.
110
- * `token(str, precedence, prevNode => curNode)` register custom token or literal. Function takes last token and returns tree node.
111
- * `operator(str, (a, b) => ctx => result)` register evaluator for an operator. Function takes node arguments and returns evaluator function.
115
+ * `unary(str, precedence, postfix=false)` − register unary operator, either prefix `⚬a` or postfix `a⚬`.
116
+ * `binary(str, precedence, rassoc=false)` − register binary operator `a ⚬ b`, optionally right-associative.
117
+ * `nary(str, precedence)` − register n-ary (sequence) operator like `a; b;` or `a, b`, allows missing args.
118
+ * `group(str, precedence)` - register group, like `[a]`, `{a}`, `(a)` etc.
119
+ * `access(str, precedence)` - register access operator, like `a[b]`, `a(b)` etc.
120
+ * `token(str, precedence, lnode => node)` − register custom token or literal. Callback takes left-side node and returns complete expression node.
121
+ * `operator(str, (a, b) => ctx => value)` − register evaluator for an operator. Callback takes node arguments and returns evaluator function.
112
122
 
113
123
  ```js
114
124
  import script, { compile, operator, unary, binary, token } from './subscript.js'
115
125
 
116
- // add identity operators with precedence 9
126
+ // enable objects/arrays syntax
127
+ import 'subscript/feature/array.js';
128
+ import 'subscript/feature/object.js';
129
+
130
+ // add identity operators (precedence of comparison)
117
131
  binary('===', 9), binary('!==', 9)
118
132
  operator('===', (a, b) => (a = compile(a), b = compile(b), ctx => a(ctx)===b(ctx)))
119
133
  operator('===', (a, b) => (a = compile(a), b = compile(b), ctx => a(ctx)!==b(ctx)))
120
134
 
135
+ // add nullish coalescing (precedence of logical or)
136
+ binary('??', 3)
137
+ operator('??', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) ?? b(ctx)))
138
+
121
139
  // add JS literals
122
140
  token('undefined', 20, a => a ? err() : [, undefined])
123
141
  token('NaN', 20, a => a ? err() : [, NaN])
@@ -0,0 +1,11 @@
1
+ import { access, binary, group } from '../src/parse.js'
2
+ import { operator, compile } from '../src/compile.js'
3
+ import { CBRACK, PREC_ACCESS } from '../src/const.js'
4
+
5
+ // a[b]
6
+ access('[]', PREC_ACCESS)
7
+ operator('[', (a, b) => !b ? err() : (a = compile(a), b = compile(b), ctx => a(ctx)[b(ctx)]))
8
+
9
+ // a.b
10
+ binary('.', PREC_ACCESS)
11
+ operator('.', (a, b) => (a = compile(a), b = !b[0] ? b[1] : b, ctx => a(ctx)[b])) // a.true, a.1 → needs to work fine
package/feature/add.js ADDED
@@ -0,0 +1,22 @@
1
+
2
+ import { binary, unary } from '../src/parse.js'
3
+ import { PREC_ADD, PREC_PREFIX, PREC_ASSIGN } from '../src/const.js'
4
+ import { compile, prop, operator } from '../src/compile.js'
5
+
6
+ unary('+', PREC_PREFIX), operator('+', (a, b) => !b && (a = compile(a), ctx => +a(ctx)))
7
+ unary('-', PREC_PREFIX), operator('-', (a, b) => !b && (a = compile(a), ctx => -a(ctx)))
8
+
9
+ binary('+', PREC_ADD), operator('+', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) + b(ctx)))
10
+ binary('-', PREC_ADD), operator('-', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) - b(ctx)))
11
+
12
+ binary('+=', PREC_ASSIGN, true)
13
+ operator('+=', (a, b) => (
14
+ b = compile(b),
15
+ prop(a, (container, path, ctx) => container(ctx)[path(ctx)] += b(ctx))
16
+ ))
17
+
18
+ binary('-=', PREC_ASSIGN, true)
19
+ operator('-=', (a, b) => (
20
+ b = compile(b),
21
+ prop(a, (container, path, ctx) => (container(ctx)[path(ctx)] -= b(ctx)))
22
+ ))
@@ -0,0 +1,11 @@
1
+ import { token, expr, group } from '../src/parse.js'
2
+ import { operator, compile } from '../src/compile.js'
3
+ import { PREC_TOKEN } from '../src/const.js'
4
+
5
+ // [a,b,c]
6
+ group('[]', PREC_TOKEN)
7
+ operator('[]', (a, b) => (
8
+ !a ? () => [] : // []
9
+ a[0] === ',' ? (a = a.slice(1).map(compile), ctx => a.map(a => a(ctx))) : // [a,b,c]
10
+ (a = compile(a), ctx => [a(ctx)]) // [a]
11
+ ))
@@ -0,0 +1,23 @@
1
+ import { binary, group } from "../src/parse.js"
2
+ import { compile, operator } from "../src/compile.js"
3
+ import { PREC_ASSIGN, PREC_TOKEN } from "../src/const.js"
4
+
5
+ // arrow functions (useful for array methods)
6
+ binary('=>', PREC_ASSIGN)
7
+ operator('=>',
8
+ (a, b) => (
9
+ a = a[0] === '()' ? a[1] : a,
10
+ a = !a ? [] : // () =>
11
+ a[0] === ',' ? (a = a.slice(1)) : // (a,c) =>
12
+ (a = [a]), // a =>
13
+
14
+ b = compile(b[0] === '{}' ? b[1] : b), // `=> {x}` -> `=> x`
15
+
16
+ (ctx = null) => (
17
+ ctx = Object.create(ctx),
18
+ (...args) => (a.map((a, i) => ctx[a] = args[i]), b(ctx))
19
+ )
20
+ )
21
+ )
22
+
23
+ binary('')
@@ -0,0 +1,11 @@
1
+ import { binary, err } from "../src/parse.js";
2
+ import { compile, operator, operators, prop } from "../src/compile.js";
3
+ import { PREC_ASSIGN } from "../src/const.js";
4
+
5
+ // assignments
6
+ binary('=', PREC_ASSIGN, true)
7
+ operator('=', (a, b) => (
8
+ b = compile(b),
9
+ // a = x, ((a)) = x, a.b = x, a['b'] = x
10
+ prop(a, (container, path, ctx) => container(ctx)[path(ctx)] = b(ctx))
11
+ ))
@@ -0,0 +1,15 @@
1
+ import { PREC_OR, PREC_AND, PREC_SHIFT, PREC_XOR, PREC_PREFIX } from "../src/const.js"
2
+ import { unary, binary } from "../src/parse.js"
3
+ import { operator, compile } from "../src/compile.js"
4
+
5
+ unary('~', PREC_PREFIX), operator('~', (a, b) => !b && (a = compile(a), ctx => ~a(ctx)))
6
+
7
+ binary('|', PREC_OR), operator('|', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) | b(ctx)))
8
+
9
+ binary('&', PREC_AND), operator('&', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) & b(ctx)))
10
+
11
+ binary('^', PREC_XOR), operator('^', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) ^ b(ctx)))
12
+
13
+ binary('>>', PREC_SHIFT), operator('>>', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) >> b(ctx)))
14
+
15
+ binary('<<', PREC_SHIFT), operator('<<', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) << b(ctx)))
@@ -0,0 +1,5 @@
1
+ import { token } from "../src/parse.js"
2
+ import { PREC_TOKEN } from "../src/const.js"
3
+
4
+ token('true', PREC_TOKEN, a => a ? err() : [, true])
5
+ token('false', PREC_TOKEN, a => a ? err() : [, false])
@@ -0,0 +1,15 @@
1
+ import { access } from '../src/parse.js'
2
+ import { operator, compile, prop } from '../src/compile.js'
3
+ import { PREC_ACCESS } from '../src/const.js'
4
+
5
+ // a(b,c,d), a()
6
+ access('()', PREC_ACCESS)
7
+ operator('(', (a, b, args) => (
8
+ args = !b ? () => [] : // a()
9
+ b[0] === ',' ? (b = b.slice(1).map(b => !b ? err() : compile(b)), ctx => b.map(arg => arg(ctx))) : // a(b,c)
10
+ (b = compile(b), ctx => [b(ctx)]), // a(b)
11
+
12
+ // a(...args), a.b(...args), a[b](...args)
13
+ prop(a, (obj, path, ctx) => obj(ctx)[path(ctx)](...args(ctx)), true)
14
+ )
15
+ )
@@ -0,0 +1,7 @@
1
+ import { SPACE, STAR, PREC_TOKEN } from "../src/const.js"
2
+ import { token, skip, cur, idx, expr } from "../src/parse.js"
3
+
4
+ // /**/, //
5
+ // FIXME: try replacing with group
6
+ token('/*', PREC_TOKEN, (a, prec) => (skip(c => c !== STAR && cur.charCodeAt(idx + 1) !== 47), skip(2), a || expr(prec) || []))
7
+ token('//', PREC_TOKEN, (a, prec) => (skip(c => c >= SPACE), a || expr(prec) || ['']))
@@ -0,0 +1,11 @@
1
+ import { PREC_EQ } from '../src/const.js'
2
+ import { unary, binary } from "../src/parse.js"
3
+ import { operator, compile } from "../src/compile.js"
4
+
5
+
6
+ binary('==', PREC_EQ), operator('==', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) == b(ctx)))
7
+ binary('!=', PREC_EQ), operator('!=', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) != b(ctx)))
8
+ binary('>', PREC_EQ), operator('>', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) > b(ctx)))
9
+ binary('<', PREC_EQ), operator('<', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) < b(ctx)))
10
+ binary('>=', PREC_EQ), operator('>=', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) >= b(ctx)))
11
+ binary('<=', PREC_EQ), operator('<=', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) <= b(ctx)))
@@ -0,0 +1,12 @@
1
+ import { err, nary, group } from '../src/parse.js'
2
+ import { compile, operator } from '../src/compile.js'
3
+ import { PREC_ACCESS, PREC_GROUP, PREC_SEQ } from '../src/const.js'
4
+
5
+ // (a,b,c), (a)
6
+ // FIXME: try raising group precedence (it causes conflict in ?. though)
7
+ group('()', PREC_ACCESS)
8
+ operator('()', (a) => (!a && err('Empty ()'), compile(a)))
9
+
10
+ const last = (...args) => (args = args.map(compile), ctx => args.map(arg => arg(ctx)).pop())
11
+ nary(',', PREC_SEQ), operator(',', last)
12
+ nary(';', PREC_SEQ, true), operator(';', last)
package/feature/in.js ADDED
@@ -0,0 +1,6 @@
1
+ import { binary } from "../src/parse.js";
2
+ import { compile, operator } from "../src/compile.js";
3
+ import { PREC_COMP } from "../src/const.js";
4
+
5
+ // a in b
6
+ binary('in', PREC_COMP), operator('in', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) in b(ctx)))
@@ -0,0 +1,16 @@
1
+ import { token, expr } from "../src/parse.js"
2
+ import { operator, compile, prop } from "../src/compile.js"
3
+ import { PREC_POSTFIX } from "../src/const.js"
4
+
5
+ let inc, dec
6
+ token('++', PREC_POSTFIX, a => a ? ['-', ['++', a], [, 1]] : ['++', expr(PREC_POSTFIX - 1)])
7
+ operator('++', inc = (a) =>
8
+ // ++a, ++((a)), ++a.b, ++a[b]
9
+ prop(a, (obj, path, ctx) => ++obj(ctx)[path(ctx)])
10
+ )
11
+
12
+ token('--', PREC_POSTFIX, a => a ? ['+', ['--', a], [, 1]] : ['--', expr(PREC_POSTFIX - 1)])
13
+ operator('--', dec = (a) => (
14
+ // --a, --a.b, --a[b]
15
+ prop(a, (obj, path, ctx) => --obj(ctx)[path(ctx)])
16
+ ))
@@ -0,0 +1,11 @@
1
+ import { PREC_LOR, PREC_LAND, PREC_PREFIX } from '../src/const.js';
2
+ import { unary, binary } from "../src/parse.js"
3
+ import { operator, compile } from "../src/compile.js"
4
+
5
+ unary('!', PREC_PREFIX), operator('!', (a, b) => !b && (a = compile(a), ctx => !a(ctx)))
6
+
7
+ binary('||', PREC_LOR)
8
+ operator('||', (a, b) => (a = compile(a), b = compile(b), ctx => a(ctx) || b(ctx)))
9
+
10
+ binary('&&', PREC_LAND)
11
+ operator('&&', (a, b) => (a = compile(a), b = compile(b), ctx => a(ctx) && b(ctx)))
@@ -0,0 +1,25 @@
1
+ import { binary } from '../src/parse.js'
2
+ import { operator, compile, prop } from '../src/compile.js'
3
+ import { PREC_MULT, PREC_ASSIGN } from '../src/const.js'
4
+
5
+ binary('*', PREC_MULT), operator('*', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) * b(ctx)))
6
+ binary('/', PREC_MULT), operator('/', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) / b(ctx)))
7
+ binary('%', PREC_MULT), operator('%', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) % b(ctx)))
8
+
9
+ binary('*=', PREC_ASSIGN, true)
10
+ operator('*=', (a, b) => (
11
+ b = compile(b),
12
+ prop(a, (container, path, ctx) => container(ctx)[path(ctx)] *= b(ctx))
13
+ ))
14
+
15
+ binary('/=', PREC_ASSIGN, true)
16
+ operator('/=', (a, b) => (
17
+ b = compile(b),
18
+ prop(a, (container, path, ctx) => container(ctx)[path(ctx)] /= b(ctx))
19
+ ))
20
+
21
+ binary('%=', PREC_ASSIGN, true)
22
+ operator('%=', (a, b) => (
23
+ b = compile(b),
24
+ prop(a, (container, path, ctx) => container(ctx)[path(ctx)] %= b(ctx))
25
+ ))
@@ -0,0 +1,11 @@
1
+ import { lookup, skip, err } from "../src/parse.js"
2
+ import { PERIOD, _0, _E, _e, _9 } from "../src/const.js"
3
+
4
+ // parse number
5
+ const num = a => a ? err() : [, (a = +skip(c => c === PERIOD || (c >= _0 && c <= _9) || (c === _E || c === _e ? 2 : 0))) != a ? err() : a]
6
+
7
+ // .1
8
+ lookup[PERIOD] = a => (!a && num())
9
+
10
+ // 0-9
11
+ for (let i = _0; i <= _9; i++) lookup[i] = num
@@ -0,0 +1,16 @@
1
+ import { token, expr, group, binary } from '../src/parse.js'
2
+ import { operator, compile } from '../src/compile.js'
3
+ import { PREC_ASSIGN, PREC_SEQ, PREC_TOKEN } from '../src/const.js'
4
+
5
+
6
+ // {a:1, b:2, c:3}
7
+ group('{}', PREC_TOKEN)
8
+ operator('{}', (a, b) => (
9
+ !a ? () => ({}) : // {}
10
+ a[0] === ',' ? (a = a.slice(1).map(compile), ctx => Object.fromEntries(a.map(a => a(ctx)))) : // {a:1,b:2}
11
+ a[0] === ':' ? (a = compile(a), ctx => Object.fromEntries([a(ctx)])) : // {a:1}
12
+ (b = compile(a), ctx => ({ [a]: b(ctx) }))
13
+ ))
14
+
15
+ binary(':', PREC_ASSIGN, true)
16
+ operator(':', (a, b) => (b = compile(b), a = Array.isArray(a) ? compile(a) : (a => a).bind(0, a), ctx => [a(ctx), b(ctx)]))
@@ -0,0 +1,30 @@
1
+ import { token, expr } from '../src/parse.js'
2
+ import { operator, compile } from '../src/compile.js'
3
+ import { PREC_ACCESS } from '../src/const.js'
4
+
5
+ // a?.[, a?.( - postfix operator
6
+ token('?.', PREC_ACCESS, a => a && ['?.', a])
7
+ // a ?.
8
+ operator('?.', a => (a = compile(a), ctx => a(ctx) || (() => { })))
9
+
10
+ // a?.b, a?.() - optional chain operator
11
+ token('?.', PREC_ACCESS, (a, b) => a && (b = expr(PREC_ACCESS), !b?.map) && ['?.', a, b])
12
+ // a ?. b
13
+ operator('?.', (a, b) => b && (a = compile(a), ctx => a(ctx)?.[b]))
14
+
15
+ // a?.x() - keep context, but watch out a?.()
16
+ operator('(', (a, b, container, args, path, optional) => (a[0] === '?.') && (a[2] || Array.isArray(a[1])) && (
17
+ args = !b ? () => [] : // a()
18
+ b[0] === ',' ? (b = b.slice(1).map(compile), ctx => b.map(a => a(ctx))) : // a(b,c)
19
+ (b = compile(b), ctx => [b(ctx)]), // a(b)
20
+
21
+ // a?.()
22
+ !a[2] && (optional = true, a = a[1]),
23
+
24
+ // a?.['x']?.()
25
+ a[0] === '[' ? (path = compile(a[2])) : (path = () => a[2]),
26
+ (container = compile(a[1]), optional ?
27
+ ctx => (container(ctx)?.[path(ctx)]?.(...args(ctx))) :
28
+ ctx => (container(ctx)?.[path(ctx)](...args(ctx)))
29
+ )
30
+ ))
package/feature/pow.js ADDED
@@ -0,0 +1,5 @@
1
+ import { binary } from "../src/parse.js";
2
+ import { compile, operator } from "../src/compile.js";
3
+ import { PREC_EXP } from "../src/const.js";
4
+
5
+ binary('**', PREC_EXP, true), operator('**', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) ** b(ctx)))
@@ -0,0 +1,19 @@
1
+ import { skip, err, cur, idx, lookup } from '../src/parse.js'
2
+ import { DQUOTE, QUOTE, BSLASH } from '../src/const.js'
3
+
4
+ const escape = { n: '\n', r: '\r', t: '\t', b: '\b', f: '\f', v: '\v' },
5
+ string = q => (qc, c, str = '') => {
6
+ qc && err('Unexpected string') // must not follow another token
7
+ skip() // first quote
8
+ while (c = cur.charCodeAt(idx), c - q) {
9
+ if (c === BSLASH) skip(), c = skip(), str += escape[c] || c
10
+ else str += skip()
11
+ }
12
+ skip() || err('Bad string')
13
+ return [, str]
14
+ }
15
+
16
+
17
+ // "' with /
18
+ lookup[DQUOTE] = string(DQUOTE)
19
+ lookup[QUOTE] = string(QUOTE)
@@ -0,0 +1,7 @@
1
+ import { token, expr } from '../src/parse.js'
2
+ import { operator, compile } from '../src/compile.js'
3
+ import { PREC_ASSIGN, COLON } from '../src/const.js'
4
+
5
+ // ?:
6
+ token('?', PREC_ASSIGN, (a, b, c) => a && (b = expr(PREC_ASSIGN, COLON)) && (c = expr(PREC_ASSIGN + 1), ['?', a, b, c]))
7
+ operator('?', (a, b, c) => (a = compile(a), b = compile(b), c = compile(c), ctx => a(ctx) ? b(ctx) : c(ctx)))
package/justin.js CHANGED
@@ -12,43 +12,9 @@ import './feature/ternary.js'
12
12
  import './feature/bool.js'
13
13
  import './feature/array.js'
14
14
  import './feature/object.js'
15
+ import './feature/optional.js'
15
16
 
16
- // operators
17
- // set('===', PREC_EQ, (a, b) => a === b)
18
- // set('!==', PREC_EQ, (a, b) => a !== b)
19
- binary('??', PREC_OR), operator('??', (a, b) => b && (a = compile(a), b = compile(b), ctx => a(ctx) ?? b(ctx)))
20
-
21
- // a?.[, a?.( - postfix operator
22
- token('?.', PREC_ACCESS, a => a && ['?.', a])
23
- // a ?.
24
- operator('?.', a => (a = compile(a), ctx => a(ctx) || (() => { })))
25
-
26
- // a?.b, a?.() - optional chain operator
27
- token('?.', PREC_ACCESS, (a, b) => a && (b = expr(PREC_ACCESS), !b?.map) && ['?.', a, b])
28
- // a ?. b
29
- operator('?.', (a, b) => b && (a = compile(a), ctx => a(ctx)?.[b]))
30
-
31
- // a?.x() - keep context, but watch out a?.()
32
- operator('(', (a, b, container, args, path, optional) => (b != null) && (a[0] === '?.') && (a[2] || Array.isArray(a[1])) && (
33
- args = b == '' ? () => [] : // a()
34
- b[0] === ',' ? (b = b.slice(1).map(compile), ctx => b.map(a => a(ctx))) : // a(b,c)
35
- (b = compile(b), ctx => [b(ctx)]), // a(b)
36
-
37
- // a?.()
38
- !a[2] && (optional = true, a = a[1]),
39
-
40
- // a?.['x']?.()
41
- a[0] === '[' ? (path = compile(a[2])) : (path = () => a[2]),
42
- (container = compile(a[1]), optional ?
43
- ctx => (container(ctx)?.[path(ctx)]?.(...args(ctx))) :
44
- ctx => (container(ctx)?.[path(ctx)](...args(ctx)))
45
- )
46
- ))
47
-
48
- // literals
49
17
  token('null', 20, a => a ? err() : [, null])
50
- // token('undefined', 20, a => a ? err() : [, undefined])
51
- // token('NaN', 20, a => a ? err() : [, NaN])
52
18
 
53
19
  export default subscript
54
20
  export * from './subscript.js'
package/justin.min.js CHANGED
@@ -1 +1 @@
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};
1
+ let r,e,t=t=>(r=0,e=t,t=n(),e[r]?a():t||""),a=(t="Bad syntax",a=e.slice(0,r).split("\n"),s=a.pop())=>{let n=e.slice(r-108,r).split("\n").pop(),i=e.slice(r,r+108).split("\n").shift();throw EvalError(`${t} at ${a.length}:${s.length} \`${r>=108?"…":""}${n}▶${i}\``,"font-weight: bold")},s=(t=1,a=r,s)=>{if("number"==typeof t)r+=t;else for(;s=t(e.charCodeAt(r));)r+=s;return e.slice(a,r)},n=(e=0,s,n,i,p,l)=>{for(;(n=t.space())&&(p=((l=o[n])&&l(i,e))??(!i&&t.id()));)i=p;return s&&(n==s?r++:a()),i},i=r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192&&215!=r&&247!=r,p=t.id=()=>s(i),l=t.space=t=>{for(;(t=e.charCodeAt(r))<=32;)r++;return t},o=[],c=(t,a=32,s,n=t.charCodeAt(0),p=t.length,l=o[n],c=t.toUpperCase()!==t)=>o[n]=(n,o,d=r)=>o<a&&(p<2||e.substr(r,p)==t)&&(!c||!i(e.charCodeAt(r+p)))&&(r+=p,s(n,o))||(r=d,l?.(n,o)),d=(r,e,t=!1)=>c(r,e,((a,s)=>a&&(s=n(e-(t?.5:0)))&&[r,a,s])),f=(r,e,t)=>c(r,e,(a=>t?a&&[r,a]:!a&&(a=n(e-.5))&&[r,a])),h=(r,e)=>{c(r,e,((t,a)=>(a=n(e),(!t||t[0]!==r)&&(t=[r,t]),t.push(a),t)))},m=(r,e)=>c(r[0],e,(e=>!e&&[r,n(0,r.charCodeAt(1))])),A=(r,e)=>c(r[0],e,(e=>e&&[r[0],e,n(0,r.charCodeAt(1))]));const b=r=>Array.isArray(r)?r[0]?u[r[0]](...r.slice(1)):()=>r[1]:e=>e?.[r],u={},y=(r,e,t=u[r])=>u[r]=(...r)=>e(...r)||t&&t(...r),C=(r,e,t)=>"()"===r[0]?C(r[1],e,t):"string"==typeof r?e.bind(0,(r=>r),(()=>r)):"."===r[0]?e.bind(0,b(r[1]),(r=r[2],()=>r)):"["===r[0]?e.bind(0,b(r[1]),b(r[2])):t?(r=b(r),e.bind(0,(e=>[r(e)]),(()=>0))):()=>a("Bad left value"),g=r=>r?a():[,(r=+s((r=>46===r||r>=48&&r<=57||(69===r||101===r?2:0))))!=r?a():r];o[46]=r=>!r&&g();for(let r=48;r<=57;r++)o[r]=g;const $={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},v=t=>(n,i,p="")=>{for(n&&a("Unexpected string"),s();(i=e.charCodeAt(r))-t;)92===i?(s(),i=s(),p+=$[i]||i):p+=s();return s()||a("Bad string"),[,p]};o[34]=v(34),o[39]=v(39),A("()",17),y("(",((r,e,t)=>(t=e?","===e[0]?(e=e.slice(1).map((r=>r?b(r):err())),r=>e.map((e=>e(r)))):(e=b(e),r=>[e(r)]):()=>[],C(r,((r,e,a)=>r(a)[e(a)](...t(a))),!0)))),A("[]",17),y("[",((r,e)=>e?(r=b(r),e=b(e),t=>r(t)[e(t)]):err())),d(".",17),y(".",((r,e)=>(r=b(r),e=e[0]?e:e[1],t=>r(t)[e]))),m("()",17),y("()",(r=>(!r&&a("Empty ()"),b(r))));const E=(...r)=>(r=r.map(b),e=>r.map((r=>r(e))).pop());h(",",1),y(",",E),h(";",1),y(";",E),d("*",12),y("*",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)*e(t)))),d("/",12),y("/",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)/e(t)))),d("%",12),y("%",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)%e(t)))),d("*=",2,!0),y("*=",((r,e)=>(e=b(e),C(r,((r,t,a)=>r(a)[t(a)]*=e(a)))))),d("/=",2,!0),y("/=",((r,e)=>(e=b(e),C(r,((r,t,a)=>r(a)[t(a)]/=e(a)))))),d("%=",2,!0),y("%=",((r,e)=>(e=b(e),C(r,((r,t,a)=>r(a)[t(a)]%=e(a)))))),f("+",14),y("+",((r,e)=>!e&&(r=b(r),e=>+r(e)))),f("-",14),y("-",((r,e)=>!e&&(r=b(r),e=>-r(e)))),d("+",11),y("+",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)+e(t)))),d("-",11),y("-",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)-e(t)))),d("+=",2,!0),y("+=",((r,e)=>(e=b(e),C(r,((r,t,a)=>r(a)[t(a)]+=e(a)))))),d("-=",2,!0),y("-=",((r,e)=>(e=b(e),C(r,((r,t,a)=>r(a)[t(a)]-=e(a)))))),c("++",15,(r=>r?["-",["++",r],[,1]]:["++",n(14)])),y("++",(r=>C(r,((r,e,t)=>++r(t)[e(t)])))),c("--",15,(r=>r?["+",["--",r],[,1]]:["--",n(14)])),y("--",(r=>C(r,((r,e,t)=>--r(t)[e(t)])))),f("~",14),y("~",((r,e)=>!e&&(r=b(r),e=>~r(e)))),d("|",5),y("|",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)|e(t)))),d("&",7),y("&",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)&e(t)))),d("^",6),y("^",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)^e(t)))),d(">>",10),y(">>",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)>>e(t)))),d("<<",10),y("<<",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)<<e(t)))),d("==",8),y("==",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)==e(t)))),d("!=",8),y("!=",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)!=e(t)))),d(">",8),y(">",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)>e(t)))),d("<",8),y("<",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)<e(t)))),d(">=",8),y(">=",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)>=e(t)))),d("<=",8),y("<=",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)<=e(t)))),f("!",14),y("!",((r,e)=>!e&&(r=b(r),e=>!r(e)))),d("||",3),y("||",((r,e)=>(r=b(r),e=b(e),t=>r(t)||e(t)))),d("&&",4),y("&&",((r,e)=>(r=b(r),e=b(e),t=>r(t)&&e(t)))),d("=",2,!0),y("=",((r,e)=>(e=b(e),C(r,((r,t,a)=>r(a)[t(a)]=e(a))))));var x=r=>b(t(r));c("/*",20,((t,a)=>(s((t=>42!==t&&47!==e.charCodeAt(r+1))),s(2),t||n(a)||[]))),c("//",20,((r,e)=>(s((r=>r>=32)),r||n(e)||[""]))),d("**",13,!0),y("**",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)**e(t)))),d("in",9),y("in",((r,e)=>e&&(r=b(r),e=b(e),t=>r(t)in e(t)))),c("?",2,((r,e,t)=>r&&(e=n(2,58))&&["?",r,e,n(3)])),y("?",((r,e,t)=>(r=b(r),e=b(e),t=b(t),a=>r(a)?e(a):t(a)))),c("true",20,(r=>r?err():[,!0])),c("false",20,(r=>r?err():[,!1])),m("[]",20),y("[]",((r,e)=>r?","===r[0]?(r=r.slice(1).map(b),e=>r.map((r=>r(e)))):(r=b(r),e=>[r(e)]):()=>[])),m("{}",20),y("{}",((r,e)=>r?","===r[0]?(r=r.slice(1).map(b),e=>Object.fromEntries(r.map((r=>r(e))))):":"===r[0]?(r=b(r),e=>Object.fromEntries([r(e)])):(e=b(r),t=>({[r]:e(t)})):()=>({}))),d(":",2,!0),y(":",((r,e)=>(e=b(e),r=Array.isArray(r)?b(r):(r=>r).bind(0,r),t=>[r(t),e(t)]))),c("?.",17,(r=>r&&["?.",r])),y("?.",(r=>(r=b(r),e=>r(e)||(()=>{})))),c("?.",17,((r,e)=>r&&!(e=n(17))?.map&&["?.",r,e])),y("?.",((r,e)=>e&&(r=b(r),t=>r(t)?.[e]))),y("(",((r,e,t,a,s,n)=>"?."===r[0]&&(r[2]||Array.isArray(r[1]))&&(a=e?","===e[0]?(e=e.slice(1).map(b),r=>e.map((e=>e(r)))):(e=b(e),r=>[e(r)]):()=>[],!r[2]&&(r=r[1]),s="["===r[0]?b(r[2]):()=>r[2],t=b(r[1]),r=>t(r)?.[s(r)]?.(...a(r))))),c("null",20,(r=>r?a():[,null]));export{A as access,d as binary,b as compile,e as cur,x as default,a as err,n as expr,m as group,p as id,r as idx,i as isId,o as lookup,h as nary,y as operator,u as operators,t as parse,C as prop,s as skip,l as space,c as token,f as unary};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "subscript",
3
- "version": "8.0.0",
3
+ "version": "8.1.0",
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
+ prop = (a, fn, generic) => (
14
+ // (((x))) => x
15
+ a[0] === '()' ? prop(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;
package/src/parse.js ADDED
@@ -0,0 +1,100 @@
1
+ import { SPACE } from "./const.js"
2
+
3
+ // current string, index and collected ids
4
+ export let idx, cur,
5
+
6
+ // no handling tagged literals since easily done on user side with cache, if needed
7
+ parse = s => (idx = 0, cur = s, s = expr(), cur[idx] ? err() : s || ''),
8
+
9
+ err = (msg = 'Bad syntax',
10
+ lines = cur.slice(0, idx).split('\n'),
11
+ last = lines.pop()
12
+ ) => {
13
+ let before = cur.slice(idx - 108, idx).split('\n').pop()
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')
16
+ },
17
+
18
+ skip = (is = 1, from = idx, l) => {
19
+ if (typeof is == 'number') idx += is
20
+ else while (l = is(cur.charCodeAt(idx))) idx += l
21
+ return cur.slice(from, idx)
22
+ },
23
+
24
+ // a + b - c
25
+ expr = (prec = 0, end, cc, token, newNode, fn) => {
26
+ // chunk/token parser
27
+ while (
28
+ (cc = parse.space()) && // till not end
29
+ // FIXME: extra work is happening here, when lookup bails out due to lower precedence -
30
+ // it makes extra `space` call for parent exprs on the same character to check precedence again
31
+ (newNode =
32
+ ((fn = lookup[cc]) && fn(token, prec)) ?? // if operator with higher precedence isn't found
33
+ (!token && parse.id()) // parse literal or quit. token seqs are forbidden: `a b`, `a "b"`, `1.32 a`
34
+ )
35
+ ) token = newNode;
36
+
37
+ // check end character
38
+ if (end) cc == end ? idx++ : err()
39
+
40
+ return token
41
+ },
42
+
43
+ isId = c =>
44
+ (c >= 48 && c <= 57) || // 0..9
45
+ (c >= 65 && c <= 90) || // A...Z
46
+ (c >= 97 && c <= 122) || // a...z
47
+ c == 36 || c == 95 || // $, _,
48
+ (c >= 192 && c != 215 && c != 247), // any non-ASCII
49
+
50
+ // parse identifier (configurable)
51
+ id = parse.id = () => skip(isId),
52
+
53
+ // skip space chars, return first non-space character
54
+ space = parse.space = cc => { while ((cc = cur.charCodeAt(idx)) <= SPACE) idx++; return cc },
55
+
56
+ // operator/token lookup table
57
+ // lookup[0] is id parser to let configs redefine it
58
+ lookup = [],
59
+
60
+
61
+ // create operator checker/mapper (see examples)
62
+ token = (
63
+ op,
64
+ prec = SPACE,
65
+ map,
66
+ c = op.charCodeAt(0),
67
+ l = op.length,
68
+ prev = lookup[c],
69
+ word = op.toUpperCase() !== op // make sure word boundary comes after word operator
70
+ ) => lookup[c] = (a, curPrec, from = idx) =>
71
+ (curPrec < prec && (l < 2 || cur.substr(idx, l) == op) && (!word || !isId(cur.charCodeAt(idx + l))) && (idx += l, map(a, curPrec))) ||
72
+ (idx = from, prev?.(a, curPrec)),
73
+
74
+ // right assoc is indicated by negative precedence (meaning go from right to left)
75
+ binary = (op, prec, right = false) => token(op, prec, (a, b) => a && (b = expr(prec - (right ? .5 : 0))) && [op, a, b]),
76
+
77
+ // post indicates postfix rather than prefix operator
78
+ unary = (op, prec, post) => token(op, prec, a => post ? (a && [op, a]) : (!a && (a = expr(prec - .5)) && [op, a])),
79
+
80
+ // skips means ,,, ;;; are allowed
81
+ nary = (op, prec) => {
82
+ token(op, prec, (a, b) => (
83
+ (b = expr(prec)),
84
+ (
85
+ (!a || a[0] !== op) && (a = [op, a]), // if beginning of sequence - init node
86
+ a.push(b),
87
+ a
88
+ ))
89
+ )
90
+ },
91
+
92
+ // register (a), [b], {c} etc groups
93
+ // FIXME: add "Unclosed paren" error
94
+ group = (op, prec) => token(op[0], prec, a => (!a && ([op, expr(0, op.charCodeAt(1))]))),
95
+
96
+ // register a(b), a[b], a<b> etc,
97
+ access = (op, prec) => token(op[0], prec, a => (a && [op[0], a, expr(0, op.charCodeAt(1))]))
98
+
99
+
100
+ export default parse
package/subscript.min.js CHANGED
@@ -1 +1 @@
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};
1
+ let r,t,e=e=>(r=0,t=e,e=n(),t[r]?s():e||""),s=(e="Bad syntax",s=t.slice(0,r).split("\n"),a=s.pop())=>{let n=t.slice(r-108,r).split("\n").pop(),o=t.slice(r,r+108).split("\n").shift();throw EvalError(`${e} at ${s.length}:${a.length} \`${r>=108?"…":""}${n}▶${o}\``,"font-weight: bold")},a=(e=1,s=r,a)=>{if("number"==typeof e)r+=e;else for(;a=e(t.charCodeAt(r));)r+=a;return t.slice(s,r)},n=(t=0,a,n,o,p,i)=>{for(;(n=e.space())&&(p=((i=l[n])&&i(o,t))??(!o&&e.id()));)o=p;return a&&(n==a?r++:s()),o},o=r=>r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||36==r||95==r||r>=192&&215!=r&&247!=r,p=e.id=()=>a(o),i=e.space=e=>{for(;(e=t.charCodeAt(r))<=32;)r++;return e},l=[],c=(e,s=32,a,n=e.charCodeAt(0),p=e.length,i=l[n],c=e.toUpperCase()!==e)=>l[n]=(n,l,d=r)=>l<s&&(p<2||t.substr(r,p)==e)&&(!c||!o(t.charCodeAt(r+p)))&&(r+=p,a(n,l))||(r=d,i?.(n,l)),d=(r,t,e=!1)=>c(r,t,((s,a)=>s&&(a=n(t-(e?.5:0)))&&[r,s,a])),f=(r,t,e)=>c(r,t,(s=>e?s&&[r,s]:!s&&(s=n(t-.5))&&[r,s])),h=(r,t)=>{c(r,t,((e,s)=>(s=n(t),(!e||e[0]!==r)&&(e=[r,e]),e.push(s),e)))},b=(r,t)=>c(r[0],t,(t=>!t&&[r,n(0,r.charCodeAt(1))])),u=(r,t)=>c(r[0],t,(t=>t&&[r[0],t,n(0,r.charCodeAt(1))]));const A=r=>r?s():[,(r=+a((r=>46===r||r>=48&&r<=57||(69===r||101===r?2:0))))!=r?s():r];l[46]=r=>!r&&A();for(let r=48;r<=57;r++)l[r]=A;const C={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},g=e=>(n,o,p="")=>{for(n&&s("Unexpected string"),a();(o=t.charCodeAt(r))-e;)92===o?(a(),o=a(),p+=C[o]||o):p+=a();return a()||s("Bad string"),[,p]};l[34]=g(34),l[39]=g(39);const m=r=>Array.isArray(r)?r[0]?y[r[0]](...r.slice(1)):()=>r[1]:t=>t?.[r],y={},$=(r,t,e=y[r])=>y[r]=(...r)=>t(...r)||e&&e(...r),v=(r,t,e)=>"()"===r[0]?v(r[1],t,e):"string"==typeof r?t.bind(0,(r=>r),(()=>r)):"."===r[0]?t.bind(0,m(r[1]),(r=r[2],()=>r)):"["===r[0]?t.bind(0,m(r[1]),m(r[2])):e?(r=m(r),t.bind(0,(t=>[r(t)]),(()=>0))):()=>s("Bad left value");u("()",17),$("(",((r,t,e)=>(e=t?","===t[0]?(t=t.slice(1).map((r=>r?m(r):err())),r=>t.map((t=>t(r)))):(t=m(t),r=>[t(r)]):()=>[],v(r,((r,t,s)=>r(s)[t(s)](...e(s))),!0)))),u("[]",17),$("[",((r,t)=>t?(r=m(r),t=m(t),e=>r(e)[t(e)]):err())),d(".",17),$(".",((r,t)=>(r=m(r),t=t[0]?t:t[1],e=>r(e)[t]))),b("()",17),$("()",(r=>(!r&&s("Empty ()"),m(r))));const x=(...r)=>(r=r.map(m),t=>r.map((r=>r(t))).pop());h(",",1),$(",",x),h(";",1),$(";",x),d("*",12),$("*",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)*t(e)))),d("/",12),$("/",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)/t(e)))),d("%",12),$("%",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)%t(e)))),d("*=",2,!0),$("*=",((r,t)=>(t=m(t),v(r,((r,e,s)=>r(s)[e(s)]*=t(s)))))),d("/=",2,!0),$("/=",((r,t)=>(t=m(t),v(r,((r,e,s)=>r(s)[e(s)]/=t(s)))))),d("%=",2,!0),$("%=",((r,t)=>(t=m(t),v(r,((r,e,s)=>r(s)[e(s)]%=t(s)))))),f("+",14),$("+",((r,t)=>!t&&(r=m(r),t=>+r(t)))),f("-",14),$("-",((r,t)=>!t&&(r=m(r),t=>-r(t)))),d("+",11),$("+",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)+t(e)))),d("-",11),$("-",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)-t(e)))),d("+=",2,!0),$("+=",((r,t)=>(t=m(t),v(r,((r,e,s)=>r(s)[e(s)]+=t(s)))))),d("-=",2,!0),$("-=",((r,t)=>(t=m(t),v(r,((r,e,s)=>r(s)[e(s)]-=t(s)))))),c("++",15,(r=>r?["-",["++",r],[,1]]:["++",n(14)])),$("++",(r=>v(r,((r,t,e)=>++r(e)[t(e)])))),c("--",15,(r=>r?["+",["--",r],[,1]]:["--",n(14)])),$("--",(r=>v(r,((r,t,e)=>--r(e)[t(e)])))),f("~",14),$("~",((r,t)=>!t&&(r=m(r),t=>~r(t)))),d("|",5),$("|",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)|t(e)))),d("&",7),$("&",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)&t(e)))),d("^",6),$("^",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)^t(e)))),d(">>",10),$(">>",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)>>t(e)))),d("<<",10),$("<<",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)<<t(e)))),d("==",8),$("==",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)==t(e)))),d("!=",8),$("!=",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)!=t(e)))),d(">",8),$(">",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)>t(e)))),d("<",8),$("<",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)<t(e)))),d(">=",8),$(">=",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)>=t(e)))),d("<=",8),$("<=",((r,t)=>t&&(r=m(r),t=m(t),e=>r(e)<=t(e)))),f("!",14),$("!",((r,t)=>!t&&(r=m(r),t=>!r(t)))),d("||",3),$("||",((r,t)=>(r=m(r),t=m(t),e=>r(e)||t(e)))),d("&&",4),$("&&",((r,t)=>(r=m(r),t=m(t),e=>r(e)&&t(e)))),d("=",2,!0),$("=",((r,t)=>(t=m(t),v(r,((r,e,s)=>r(s)[e(s)]=t(s))))));var B=r=>m(e(r));export{u as access,d as binary,m as compile,t as cur,B as default,s as err,n as expr,b as group,p as id,r as idx,o as isId,l as lookup,h as nary,$ as operator,y as operators,e as parse,v as prop,a as skip,i as space,c as token,f as unary};