Ceval
中文文档 零依赖,适合表达式运算;
No dependence, suitable for calculating expressions;
┌───────────────────────────────┐│ ││ Destination: lib/index.js ││ Bundle Size: 2192 KB ││ Minified Size: 2189 KB ││ Gzipped Size: 676 KB ││ │└───────────────────────────────┘
usage
npm i ceval -S
introduce
Options
API
Parser Instance API
api | desc | type |
---|---|---|
operatorMap | Operators mapping table, which can be used in preset values overlay operation | Record<string, Function> |
getSupportOperationMap | The name of the operator method supported by the query can be overridden | (ops: string) => null |
parseString | Parsing strings, exposing methods to the outside world | (expression: string, values?: Record<string, any>) => any; |
getCurrentValues | Get current datapool preset + external + internal declaration | () => Record<string, any> |
updatePresetValues | Update PresetValues | (values: Record<string, any>) => void |
updateOptions | Update Option | (Options: Partial) => void |
getOptions | get Options | () => Readonly |
about Options example test case;
use test262 test case;
rule
There are two rules:
Semicolon at the end
e.g.
parse'0b01 + 0b01;' // 2
Although it is not necessary in a simple expression operation, but it's a good habit.The parser can know exactly where the end is, Although it doesn't have too many restrictions.
e.g.
parse` function abs(a,b,c) { let b = 1 /* ⚠️ error, must has semicolon */ c = 2; return(a+b+c); }; abs(3,4,8);`
statement
"var" statement does not affect "scope", it's inserted into values "let" and "const" assigned to the current scope, warn if the current scope exists
;;;parse`var obj = { foo:'foo', bar: 'bar'};function abs(a,b,c) {var d = 'global';return (a+b+c);}abs(1,2,3)`console.loginstance.getCurrentValues.obj; // { foo:'foo', bar: 'bar'}console.loginstance.getCurrentValues.d; // 'global'parse`let foo = 'foo';const bar = 'bar';function abs(a,b,c) {let d = 'scope';const e = 'scope';return (a+b+c);}abs(1,2,3)`console.loginstance.getCurrentValues.foo; // undefinedconsole.loginstance.getCurrentValues.bar; // undefinedconsole.loginstance.getCurrentValues.d; // undefinedconsole.loginstance.getCurrentValues.e; // undefined
basic
Number
parse'0b01' // 1parse'0b11' // 3parse'0b010101' // 21parse'01' // 1parse'077' // 63parse'01111' // 585parse'.1' // 1parse'33' // 33parse'100.00' // 100parse'0x01' // 1parse'0xaf' // 175parse'0x9fac' // 40876parse`1e+308*2 === Infinity` // trueparse`var x = NaN;var y = NaN;return (x !== y);` // trueparse`var x = NaN;return(typeof(x) === 'number');` // trueparse`var x = NaN;var x_geq_0=(x >= 0.0);return(x_geq_0)` // falseparse`var x=+Infinity;return(typeof(x) === 'number')` // true
More testcase here
calculation
parse`1+1`; // 2parse`-1-2-3`; // -6parse`1*2*3`; // 6parse`1/2/4`; // 0.125parse`undefined || 2`; // 2parse`~-1 || -2 || 3`; // -2parse`-0 == +0`; // trueparse`~1 > 1`; // falseparse`false > false > 1`; // falseparse`5 >= 0`; // trueparse`1 in [1, 2, 3]`; // trueparse`undefined in [1, 2, true]`; // falseparse`'a' in `; // trueparse`\'\'a\'\' in `; // true ('"a"' === 'a') is Palindromeparse`1 === true`; // falseparse`3%2`; // 1
Function
parse`function abs(a,b,c) {var a = 5; /* => inject to presetValues */let b = 1; /* => inject to current scope */c = 2;const d = 4; /* If the current scope contains the variable D, It will trigger warning, but the operation will still be completed, is overlay */return(a+b+c);};abs(3,4,8);`
Object & Array
parse`[1*2, false, true, undefined, null]`; // Array[]parse`var a = { b: { c: ['a','b','c','d']} };'e' in a.b.c`; // falseparse`{ a: 1, b: 2, c: { d: undefined, e: { f: false, g: { h: null }}}}`; // objectparse`var a = { b: 2 };a.b` //2;parse`var a = { b: 2 };a["b"]` //2;parse`var a = { b: 2, c:3 };var b='c';a[b]` //3;// data referenceparse`var a = { b: 2, c:[1,2,3]};var b='c';a[b][0] = '0';return a[b];` // ['0',2,3]parse`var arr = [1,2,3];arr[0] = 0;return arr;` // [0,2,3]
Variable
parse`var a = { foo: 1 };var b = { bar: 2 };let a = { state: 1 } // ⚠️, Raise warning, current scope exists keyconst b = { state: 1 } // ⚠️, Raise warning, current scope exists keylet c = { coo: 1} // success;const d = { coo: 1} // success;`parse`var a = { a: [false, true, undefined, null, ''] };var b = { b: true, c: undefined, d:{ e: a, f: '1', g: {}}};` // Can be obtained from the instance. api: getCurrentValues
this
Operator
Through instance.operatorMap
Get all operators;
return
return
interrupt this operation cycle; but it doesn't affect the outside world.
parse`return 1;return 2;` // 1parse`var foo = 'foo'function abs(a,b,c) {return a;return b;}var bar = abs(1,2,3)return (bar + foo);` // foo1
Other
Please move to test case for more examples。
Test39 Some test cases,
TODO:speed of progress
2020-06-24 done: number, null, boolean
In more function extension, welcome to participate or propose feature.
development
develop
npm start
build
# webapck build umd module, No compressionnpm run build:umd# rollup build umd module, Compressed versionnpm run build:rollup# webpack build docsnpm run build:docs
publish
npm publish