|
@@ -0,0 +1,124 @@
|
|
|
+import { IVProgParser } from "../ast/ivprogParser";
|
|
|
+import * as Expressions from "../ast/expressions";
|
|
|
+
|
|
|
+const TYPES = {
|
|
|
+ VARIABLE: "var",
|
|
|
+ CONST: "const",
|
|
|
+ FUNCTION: "function",
|
|
|
+ RELATIONAL: "relational",
|
|
|
+ LOGIC: "logic",
|
|
|
+ ARITHMETIC: "arithmetic",
|
|
|
+};
|
|
|
+
|
|
|
+function translateOp (type, op) {
|
|
|
+ switch (type) {
|
|
|
+ case TYPES.ARITHMETIC:
|
|
|
+ return op.value;
|
|
|
+ case TYPES.RELATIONAL:
|
|
|
+ return op.value;
|
|
|
+ case TYPES.LOGIC: {
|
|
|
+ if (op.ord === 11) {
|
|
|
+ return "and";
|
|
|
+ } else if (op.ord === 12) {
|
|
|
+ return "or";
|
|
|
+ } else {
|
|
|
+ return "not";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function getOpType (op) {
|
|
|
+ switch (op.ord) {
|
|
|
+ case 0:
|
|
|
+ case 1:
|
|
|
+ case 2:
|
|
|
+ case 3:
|
|
|
+ case 4:
|
|
|
+ return TYPES.ARITHMETIC;
|
|
|
+ case 5:
|
|
|
+ case 6:
|
|
|
+ case 7:
|
|
|
+ case 8:
|
|
|
+ case 9:
|
|
|
+ case 10:
|
|
|
+ return TYPES.RELATIONAL;
|
|
|
+ default:
|
|
|
+ return TYPES.LOGIC;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function expressionWalker (expression) {
|
|
|
+ let result;
|
|
|
+ if (expression instanceof Expressions.VariableLiteral) {
|
|
|
+ result = [
|
|
|
+ { instance: "expression", type: TYPES.VARIABLE, value: expression.id },
|
|
|
+ ];
|
|
|
+ } else if (expression instanceof Expressions.FunctionCall) {
|
|
|
+ const funcObj = {
|
|
|
+ instance: "expression",
|
|
|
+ type: TYPES.FUNCTION,
|
|
|
+ value: expression.id,
|
|
|
+ };
|
|
|
+ const paramsList = expression.actualParameters.map((e) =>
|
|
|
+ expressionWalker(e)
|
|
|
+ );
|
|
|
+
|
|
|
+ funcObj.params = paramsList;
|
|
|
+ result = [funcObj];
|
|
|
+ } else if (expression instanceof Expressions.InfixApp) {
|
|
|
+ const left = expressionWalker(expression.left);
|
|
|
+ const right = expressionWalker(expression.right);
|
|
|
+ const opType = getOpType(expression.op);
|
|
|
+ const opValue = translateOp(opType, expression.op);
|
|
|
+ result = [
|
|
|
+ ...left,
|
|
|
+ { instance: "operator", type: opType, value: opValue },
|
|
|
+ ...right,
|
|
|
+ ];
|
|
|
+ } else if (expression instanceof Expressions.UnaryApp) {
|
|
|
+ const left = expressionWalker(expression.left);
|
|
|
+ const opType = getOpType(expression.op);
|
|
|
+ const opValue = translateOp(opType, expression.op);
|
|
|
+ result = [{ instance: "operator", type: opType, value: opValue }, ...left];
|
|
|
+ } else if (expression instanceof Expressions.ArrayAccess) {
|
|
|
+ const line = expressionWalker(expression.line);
|
|
|
+ let arrayClass = "vector";
|
|
|
+ let column = null;
|
|
|
+ if (expression.column) {
|
|
|
+ arrayClass = "matrix";
|
|
|
+ column = expressionWalker(expression.column);
|
|
|
+ }
|
|
|
+ result = [
|
|
|
+ {
|
|
|
+ instance: "expression",
|
|
|
+ type: TYPES.VARIABLE,
|
|
|
+ class: arrayClass,
|
|
|
+ column: column,
|
|
|
+ line: line,
|
|
|
+ value: expression.id,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ } else {
|
|
|
+ let value = expression.value;
|
|
|
+ if (expression.value.toNumber) {
|
|
|
+ value = expression.value.toNumber();
|
|
|
+ }
|
|
|
+ result = [
|
|
|
+ {
|
|
|
+ instance: "expression",
|
|
|
+ class: "simple",
|
|
|
+ type: TYPES.CONST,
|
|
|
+ value: value,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ if (expression.parenthesis) return ["(", ...result, ")"];
|
|
|
+ else return result;
|
|
|
+}
|
|
|
+
|
|
|
+export function parseExpression (text) {
|
|
|
+ const parser = IVProgParser.createParser(text);
|
|
|
+ const expressionAST = parser.parseExpressionOR();
|
|
|
+ return expressionWalker(expressionAST);
|
|
|
+}
|