Parse and evaluate expressions

feature/CapEx
Alinson S. Xavier 3 years ago
parent 40506c13eb
commit c89747e8d4
Signed by: isoron
GPG Key ID: 0DA8E4B9E1109DCA

@ -16,6 +16,7 @@
"d3-array": "^2.12.1", "d3-array": "^2.12.1",
"dagre": "^0.8.5", "dagre": "^0.8.5",
"idb": "^6.1.5", "idb": "^6.1.5",
"jsep": "^1.3.8",
"leaflet": "^1.8.0", "leaflet": "^1.8.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
@ -11201,6 +11202,14 @@
} }
} }
}, },
"node_modules/jsep": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz",
"integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==",
"engines": {
"node": ">= 10.16.0"
}
},
"node_modules/jsesc": { "node_modules/jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@ -25021,6 +25030,11 @@
"xml-name-validator": "^3.0.0" "xml-name-validator": "^3.0.0"
} }
}, },
"jsep": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz",
"integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ=="
},
"jsesc": { "jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",

@ -17,6 +17,7 @@
"d3-array": "^2.12.1", "d3-array": "^2.12.1",
"dagre": "^0.8.5", "dagre": "^0.8.5",
"idb": "^6.1.5", "idb": "^6.1.5",
"jsep": "^1.3.8",
"leaflet": "^1.8.0", "leaflet": "^1.8.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",

@ -0,0 +1,50 @@
import { Jsep } from "jsep";
import { exportValue } from "./export";
export const evaluateExpr = (expr, data) => {
const node = Jsep.parse(expr);
return evaluateNode(node, data);
};
const evaluateNode = (node, data) => {
if (node.type == "BinaryExpression") {
return evaluateBinaryExprNode(node, data);
} else if (node.type == "UnaryExpression") {
return evaluateUnaryExprNode(node, data);
} else if (node.type == "Literal") {
return node.value;
} else if (node.type == "Identifier") {
return data[node.name];
} else {
throw `Unknown type: ${node.type}`;
}
};
const evaluateBinaryExprNode = (node, data) => {
const leftVal = evaluateNode(node.left, data);
const rightVal = evaluateNode(node.right, data);
if (node.operator == "+") {
return leftVal + rightVal;
} else if (node.operator == "*") {
return leftVal * rightVal;
} else if (node.operator == "/") {
return leftVal / rightVal;
} else if (node.operator == "-") {
return leftVal - rightVal;
} else if (node.operator == "^") {
return Math.pow(leftVal, rightVal);
} else {
throw `Unknown operator: ${node.operator}`;
}
};
const evaluateUnaryExprNode = (node, data) => {
const arg = evaluateNode(node.argument, data);
if (node.operator == "+") {
return arg;
} else if (node.operator == "-") {
return -arg;
} else {
throw `Unknown operator: ${node.operator}`;
}
};

@ -0,0 +1,19 @@
import { evaluateExpr } from "./expr";
test("parse expression", () => {
// Basic expressions
expect(evaluateExpr("1 + 1")).toEqual(2);
expect(evaluateExpr("2 * 5")).toEqual(10);
expect(evaluateExpr("2 * (3 + 5)")).toEqual(16);
expect(evaluateExpr("14 / 2")).toEqual(7);
expect(evaluateExpr("10 - 3")).toEqual(7);
expect(evaluateExpr("-10")).toEqual(-10);
expect(evaluateExpr("+10")).toEqual(10);
expect(evaluateExpr("2^3")).toEqual(8);
expect(evaluateExpr("2^(3 + 1)")).toEqual(16);
// With data
expect(evaluateExpr("x + 1", { x: 10 })).toEqual(11);
expect(evaluateExpr("2 ^ (3 + x)", { x: 1 })).toEqual(16);
expect(evaluateExpr("x + y", { x: 1, y: 2 })).toEqual(3);
});
Loading…
Cancel
Save