1- # sub<sub ><sup > β¦ </sup ></sub >script [ ![ build] ( https://github.com/dy/subscript/actions/workflows/node.js.yml/badge.svg )] ( https://github.com/dy/subscript/actions/workflows/node.js.yml ) [ ![ npm] ( https://img.shields.io/npm/v/subscript )] ( http://npmjs.org/subscript ) [ ![ size] ( https://img.shields.io/bundlephobia/minzip/subscript?label=size )] ( https://bundlephobia.com/package/subscript )
1+ # sub<sub ><sup > β¦ </sup ></sub >script [ ![ build] ( https://github.com/dy/subscript/actions/workflows/node.js.yml/badge.svg )] ( https://github.com/dy/subscript/actions/workflows/node.js.yml ) [ ![ npm] ( https://img.shields.io/npm/v/subscript )] ( http://npmjs.org/subscript ) [ ![ size] ( https://img.shields.io/bundlephobia/minzip/subscript?label=size )] ( https://bundlephobia.com/package/subscript ) [ ![ demo ] ( https://img.shields.io/badge/play-%F0%9F%9A%80-white )] ( https://dy.github.io/subscript/ )
22
33> Tiny expression compiler.
44
@@ -14,41 +14,32 @@ fn({ a: 1, b: 3 }) // 7
1414* ** Safe** β sandboxed, blocks ` __proto__ ` , ` constructor ` , no global access
1515* ** Fast** β Pratt parser engine, see [ benchmarks] ( #performance )
1616* ** Portable** β universal expression format, any compile target
17- * ** Metacircular** β [ jessie ] ( #jessie ) can parse and compile itself
17+ * ** Metacircular** β can parse and compile itself
1818* ** Extensible** β pluggable syntax for building custom DSL
1919
2020
21- [ ** Playground β** ] ( https://dy.github.io/subscript/ )
22-
23-
24- ## Install
25-
26- ```
27- npm install subscript
28- ```
29-
3021
3122## Presets
3223
33- ** subscript** β common expressions (~ 4kb gzip)
24+ ** subscript** β common expressions (~ 4kb gzip):
25+ ` a.b ` ` a[b] ` ` a(b) ` ` + ` ` - ` ` * ` ` / ` ` % ` ` < ` ` > ` ` <= ` ` >= ` ` == ` ` != ` ` ! ` ` && ` ` || ` ` ~ ` ` & ` ` | ` ` ^ ` ` << ` ` >> ` ` ++ ` ` -- ` ` = ` ` += ` ` -= ` ` *= ` ` /= `
3426``` js
3527import subscript from ' subscript'
3628
3729subscript (' a.b + c * 2' )({ a: { b: 1 }, c: 3 }) // 7
38- subscript (' x > 0 && y != z' )({ x: 1 , y: 2 , z: 3 }) // true
3930```
4031
41- ** justin** β JSON + expressions (~ 6kb gzip)
32+ ** justin** β + JSON, arrows, templates (~ 6kb gzip):
33+ ` 'str' ` ` 0x ` ` 0b ` ` === ` ` !== ` ` ** ` ` ?? ` ` >>> ` ` ?. ` ` ? : ` ` => ` ` ... ` ` [] ` ` {} ` `` ` ` `` ` // ` ` /**/ ` ` true ` ` false ` ` null `
4234``` js
4335import justin from ' subscript/justin.js'
4436
4537justin (' { x: a?.b ?? 0, y: [1, ...rest] }' )({ a: null , rest: [2 , 3 ] })
4638// { x: 0, y: [1, 2, 3] }
47-
48- justin (' items.filter(x => x > 1)' )({ items: [1 , 2 , 3 ] }) // [2, 3]
4939```
5040
51- ** jessie** β JS subset (~ 8kb gzip)
41+ ** jessie** β + statements, functions (~ 8kb gzip):
42+ ` if ` ` else ` ` for ` ` while ` ` do ` ` let ` ` const ` ` var ` ` function ` ` class ` ` return ` ` throw ` ` try ` ` catch ` ` switch ` ` import ` ` export ` ` /regex/ `
5243``` js
5344import jessie from ' subscript/jessie.js'
5445
@@ -62,7 +53,7 @@ let fn = jessie(`
6253fn ({}) // 120
6354```
6455
65- Jessie can parse and compile its own source code .
56+ Jessie can parse and compile its own source.
6657
6758## Extension
6859
@@ -86,7 +77,7 @@ justin('[1,2,3] β© [2,3,4]')({}) // [2, 3]
8677See [ docs.md] ( ./docs.md ) for full API: ` binary ` , ` unary ` , ` nary ` , ` group ` , ` access ` , ` literal ` , ` token ` .
8778
8879
89- ## Tree Format
80+ ## Syntax Tree
9081
9182Expressions parse to a minimal JSON-compatible AST:
9283
@@ -122,51 +113,11 @@ subscript('constructor.constructor("alert(1)")()')({})
122113
123114## Performance
124115
125- Parse 30k expressions:
126-
127- | Parser | Time |
128- | --------| ------|
129- | subscript | ~ 150ms |
130- | justin | ~ 183ms |
131- | jsep | ~ 270ms |
132- | expr-eval | ~ 480ms |
133- | jexl | ~ 1056ms |
134-
135- Evaluate 30k times:
136-
137- | Evaluator | Time |
138- | -----------| ------|
139- | new Function | ~ 7ms |
140- | subscript | ~ 15ms |
141- | jsep+eval | ~ 30ms |
142- | expr-eval | ~ 72ms |
143-
144-
145- ## Template Tag
146-
147- For repeated evaluation, use template syntax for automatic caching:
148-
149- ``` js
150- subscript` a + b` ({ a: 1 , b: 2 }) // cached compilation
151-
152- // interpolate values
153- const limit = 100
154- subscript` x < ${ limit} ` ({ x: 50 }) // true
155116```
156-
157- ## Bundle
158-
159- Create custom dialect as single file:
160-
161- ``` js
162- import { bundle } from ' subscript/util/bundle.js'
163-
164- const code = await bundle (' subscript/jessie.js' )
165- // β self-contained ES module
117+ Parse 30k: subscript 150ms Β· justin 183ms Β· jsep 270ms Β· expr-eval 480ms Β· jexl 1056ms
118+ Eval 30k: new Function 7ms Β· subscript 15ms Β· jsep+eval 30ms Β· expr-eval 72ms
166119```
167120
168- [ ** Playground β** ] ( https://dy.github.io/subscript/ ) β interactive dialect builder
169-
170121
171122## Used by
172123
@@ -176,10 +127,10 @@ const code = await bundle('subscript/jessie.js')
176127<!-- * [piezo](https://github.com/dy/piezo) -->
177128
178129
179- ## See Also
130+ ## Refs
180131
181132[ jsep] ( https://github.com/EricSmekens/jsep ) , [ jexl] ( https://github.com/TomFrost/Jexl ) , [ expr-eval] ( https://github.com/silentmatt/expr-eval ) , [ math.js] ( https://mathjs.org/ ) .
182133
183134<!-- [mozjexl](https://github.com/mozilla/mozjexl), [jexpr](https://github.com/justinfagnani/jexpr), [expression-eval](https://github.com/donmccurdy/expression-eval), [string-math](https://github.com/devrafalko/string-math), [nerdamer](https://github.com/jiggzson/nerdamer), [math-codegen](https://github.com/mauriciopoppe/math-codegen), [math-parser](https://www.npmjs.com/package/math-parser), [nx-compile](https://github.com/nx-js/compiler-util), [built-in-math-eval](https://github.com/mauriciopoppe/built-in-math-eval) -->
184135
185- <p align =center ><a href =" https://github.com/krsnzd/license/ " >π </a ></p >
136+ <p align =center ><a href =" https://github.com/krsnzd/license/ " >ΰ₯ </a ></p >
0 commit comments