An expression evaluator written in typescript with the goal to support SQL like WHERE clauses.
npm install --save @abdullah2993/expression-parser
+-*/
=<>>>=<=
andor
IS NULLIS NOT NULLBETWEEN [NUMBER] AND [NUMBER]CASE WHEN expression THEN expression [WHEN expression] [ELSE expression] END
Currently only function that is evaluated is the LENGTH(variable) function but supports function calls at the parser level so it is fairly easy to add more SQL functions.
/** Basic Math **/evaluate('1+2'));// 3evaluate('10 + 2 * 6'));// 22evaluate('100 * 2 + 12'));// 212evaluate('100 * ( 2 + 12 )'));// 1400evaluate('100 * ( 2 + 12 ) / 14'));// 100/** Basic Math With Variable Substitution**/constcontext={a: 1,b: 2,c: 10,d: 6,e: 100,f: 12,g: 14,};evaluateObject('a+b',context));// 3evaluateObject('c + b * d',context));// 22evaluateObject('e * b + f',context));// 212evaluateObject('e * ( b + f )',context));// 1400evaluateObject('e * ( b + f ) / g',context));// 100/** Other Operations **/constval: any={a: null};evaluateObject('a is not null and length(a) between 4 and 10',val);// falseconstval={a: '123'};evaluateObject('a is not null and length(a) between 4 and 10',val);// falseconstval={a: '1234'};evaluateObject('a is not null and length(a) between 4 and 10',val);// trueconstval={a: '1234567890'};evaluateObject('a is not null and length(a) between 4 and 10',val);// trueconstval={a: '12345678901'};evaluateObject('a is not null and length(a) between 4 and 10',val);// falseconstval: any={a: 1,b: 1};evaluateObject('a is not null and b is not null',val);// trueevaluateObject('a is not null and b is null',val);// falseconstval={a: 1,b: null};evaluateObject('a is not null and b is null',val);// trueconstval={a: 1,b: 1};evaluateObject('a=b',val));// trueevaluateObject('a>b',val));// falseevaluateObject('a<b',val));// falseconstval={a: 1,b: 2};evaluateObject('a=b',val);// falseevaluateObject('a>b',val);// falseevaluateObject('a<b',val);// trueconstval={a: 1,b: 3};evaluateObject('case when a > 1 then true else false end',val);// falseconstval={a: 2,b: 3};evaluateObject('case when a > 1 then true else false end',val);// trueval={a: 2,b: 3};evaluateObject('case when a = 1 then 1 when a = 2 then 1 else false end',val);// 1evaluateObject('case when a = 1 then 1 when a = 2 then 2 else 3 end',val);// 2evaluateObject('case when a = 1 then 1 when a = 3 then 3 else 2 end',val);// 2construle=`case when light = 'Green' then 'Go' when light = 'Yellow' then 'Should Stop' when light = 'Red' then 'Stop' else 'Invalid State' end`;val={light: 'Yellow'};evaluateObject(rule,val))// 'Should Stop'val={light: 'Green'};evaluateObject(rule,val))// 'Go'val={light: 'Red'};evaluateObject(rule,val))// 'Stop'val={light: 'Blue'};evaluateObject(rule,val))// 'Invalid State'//Expression: a is not null and length(a) between 4 and 10
{
"operator": "and",
"left": {
"operator": "<>",
"left": {
"name": "a",
"type": "IdentifierExpression"
},
"right": {
"value": null,
"type": "ValueExpression"
},
"type": "BinaryExpression"
},
"right": {
"operator": "and",
"left": {
"operator": ">=",
"left": {
"name": "length",
"args": [
{
"name": "a",
"type": "IdentifierExpression"
}
],
"type": "FunctionCallExpression"
},
"right": {
"value": 4,
"type": "ValueExpression"
},
"type": "BinaryExpression"
},
"right": {
"operator": "<=",
"left": {
"name": "length",
"args": [
{
"name": "a",
"type": "IdentifierExpression"
}
],
"type": "FunctionCallExpression"
},
"right": {
"value": 10,
"type": "ValueExpression"
},
"type": "BinaryExpression"
},
"type": "BinaryExpression"
},
"type": "BinaryExpression"
}13 specs, 0 failures
Finished in 0.069 seconds
Randomized with seed 62175 (jasmine --random=true --seed=62175)
--------------|---------|----------|---------|---------|-----------------------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------|---------|----------|---------|---------|-----------------------------------
All files | 93.24 | 83.33 | 92.73 | 93.19 |
ast.ts | 89.66 | 100 | 90 | 90 | 16-18
evaluator.ts | 85 | 69.23 | 100 | 84.21 | 14,18,27,47-49,64
lexer.ts | 99.04 | 98 | 100 | 99.03 | 86
parser.ts | 89.89 | 70 | 89.47 | 89.41 | 83,91,103,121,133,137,144,181,184
token.ts | 97.06 | 100 | 75 | 96.97 | 44
--------------|---------|----------|---------|---------|-----------------------------------