import { IVProgParser } from "../ast/ivprogParser"; import * as Expressions from "../ast/expressions"; import { Types } from "../typeSystem/types"; 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) ); //const params = Array.prototype.concat.apply([], paramsList); 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) { if ( Types.REAL.isCompatible(expression.type) && expression.value.decimalPlaces() == 0 ) { value = expression.value.toFixed(2); } else { 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); }