| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 | 
							- import { IVProgParser } from "../ast/ivprogParser";
 
- import * as Expressions from "../ast/expressions";
 
- import { Types } from "../typeSystem/types";
 
- import { convertBoolToString } from "../typeSystem/parsers";
 
- import * as Commands from "../ast/commands";
 
- import { ArrayType } from "../typeSystem/array_type";
 
- import { Literal } from "../ast/expressions/literal";
 
- 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;
 
-   }
 
- }
 
- /**
 
-  * @param {Commands.Case} switchCase
 
-  * */
 
- function switchCaseWalker (switchCase) {
 
-   const commands = switchCase.commands.map(commandWalker);
 
-   const expression = switchCase.isDefault
 
-     ? null
 
-     : expressionWalker(switchCase.expression);
 
-   return {
 
-     type: "switchcase",
 
-     line: switchCase.sourceInfo.line,
 
-     expression,
 
-     commands,
 
-   };
 
- }
 
- /**
 
-  * @param {Commands.Switch} switchCommand
 
-  * */
 
- function switchWalker (switchCommand) {
 
-   const expression = expressionWalker(switchCommand.expression);
 
-   const cases = switchCommand.cases.map(switchCaseWalker);
 
-   return {
 
-     type: "switch",
 
-     expression,
 
-     cases,
 
-   };
 
- }
 
- /**
 
-  * @param {Commands.Return} returnCommand
 
-  * */
 
- function returnWalker (returnCommand) {
 
-   const expression = expressionWalker(returnCommand.expression);
 
-   return {
 
-     type: "return",
 
-     expression,
 
-   };
 
- }
 
- function breakWalker (_) {
 
-   return { type: "break" };
 
- }
 
- /**
 
-  * @param {Commands.For} forLoop
 
-  * */
 
- function forWalker (forLoop) {
 
-   const var_attribution = expressionWalker(forLoop.for_id);
 
-   const var_initial = expressionWalker(forLoop.for_from);
 
-   const condition = expressionWalker(forLoop.for_to);
 
-   const step_expression = forLoop.for_pass
 
-     ? expressionWalker(forLoop.for_pass)
 
-     : [];
 
-   const commands = forLoop.commands.map(commandWalker);
 
-   return {
 
-     type: "repeatNtimes",
 
-     var_attribution,
 
-     var_initial,
 
-     condition,
 
-     step_expression,
 
-     commands,
 
-   };
 
- }
 
- /**
 
-  * @param {Commands.While} whileLoop
 
-  * */
 
- function whileWalker (whileLoop) {
 
-   const expression = expressionWalker(whileLoop.expression);
 
-   const commands = whileLoop.commands.map(commandWalker);
 
-   let type = whileLoop.testFirst ? "whiletrue" : "dowhiletrue";
 
-   return {
 
-     type,
 
-     expression,
 
-     commands,
 
-   };
 
- }
 
- /**
 
-  * @param {Commands.IfThenElse} ifthenelse
 
-  * */
 
- function ifThenElseWalker (ifthenelse) {
 
-   //ifthenelse.
 
-   const expression = expressionWalker(ifthenelse.condition);
 
-   const ifTrue = ifthenelse.ifTrue.commands.map(commandWalker);
 
-   let ifFalse = [];
 
-   if (ifthenelse.ifFalse) {
 
-     if (ifthenelse.ifFalse instanceof Commands.CommandBlock) {
 
-       ifFalse = ifthenelse.ifFalse.commands.map(commandWalker);
 
-     } else {
 
-       ifFalse = [ifThenElseWalker(ifthenelse.ifFalse)];
 
-     }
 
-   }
 
-   return {
 
-     type: "iftrue",
 
-     expression,
 
-     ifTrue,
 
-     ifFalse,
 
-   };
 
- }
 
- /**
 
-  * @param {Commands.Assign} assingment
 
-  * */
 
- function assignmentWalker (assingment) {
 
-   let variable = null;
 
-   if (assingment instanceof Commands.ArrayIndexAssign) {
 
-     const line = expressionWalker(assingment.line);
 
-     let arrayClass = "vector";
 
-     let column = null;
 
-     if (assingment.column) {
 
-       arrayClass = "matrix";
 
-       column = expressionWalker(assingment.column);
 
-     }
 
-     variable = [
 
-       {
 
-         instance: "expression",
 
-         type: TYPES.VARIABLE,
 
-         class: arrayClass,
 
-         column: column,
 
-         line: line,
 
-         value: assingment.id,
 
-       },
 
-     ];
 
-   } else {
 
-     variable = [
 
-       { instance: "expression", type: TYPES.VARIABLE, value: assingment.id },
 
-     ];
 
-   }
 
-   const expression = expressionWalker(assingment.expression);
 
-   return {
 
-     type: "attribution",
 
-     variable,
 
-     expression,
 
-   };
 
- }
 
- /**
 
-  * @param {Command} command
 
-  * */
 
- function commandWalker (command) {
 
-   let parsedCommand = null;
 
-   if (command instanceof Commands.FunctionCall) {
 
-     parsedCommand = functionCallWalker(command);
 
-   } else if (command instanceof Commands.Assign) {
 
-     parsedCommand = assignmentWalker(command);
 
-   } else if (command instanceof Commands.IfThenElse) {
 
-     parsedCommand = ifThenElseWalker(command);
 
-   } else if (command instanceof Commands.While) {
 
-     parsedCommand = whileWalker(command);
 
-   } else if (command instanceof Commands.Break) {
 
-     parsedCommand = breakWalker(command);
 
-   } else if (command instanceof Commands.Return) {
 
-     parsedCommand = returnWalker(command);
 
-   } else if (command instanceof Commands.Switch) {
 
-     parsedCommand = switchWalker(command);
 
-   } else if (command instanceof Commands.For) {
 
-     parsedCommand = forWalker(command);
 
-   } else {
 
-     throw new Error("not implemented");
 
-   }
 
-   parsedCommand.line = command.sourceInfo.line;
 
-   return parsedCommand;
 
- }
 
- /**
 
-  * @param {Commands.FunctionCall} functionCall
 
-  * */
 
- function functionCallWalker (functionCall) {
 
-   let name = functionCall.id;
 
-   if (name.indexOf(".") !== -1) {
 
-     name = name.split(".")[1];
 
-   }
 
-   const parameters = functionCall.actualParameters.map(expressionWalker);
 
-   if (name === "$write") {
 
-     const lastInput = parameters[parameters.length - 1][0];
 
-     // if lastInput is an object with value === '\n', newLine is true
 
-     const newLine = lastInput.value && lastInput.value.match(/^\n$/) !== null;
 
-     const content = newLine
 
-       ? parameters.slice(0, parameters.length - 1)
 
-       : parameters;
 
-     return {
 
-       type: "writer",
 
-       newLine,
 
-       content,
 
-     };
 
-   }
 
-   if (name === "$read") {
 
-     return {
 
-       type: "reader",
 
-       variable: parameters[0],
 
-     };
 
-   }
 
-   return {
 
-     type: "functioncall",
 
-     parameters_list: parameters,
 
-     name: functionCall.id,
 
-   };
 
- }
 
- /**
 
-  * @param {Commands.Function} func
 
-  * */
 
- function functionWalker (func) {
 
-   const funcDeclaration = {
 
-     name: func.name,
 
-     line: func.sourceInfo.line,
 
-     return_type: "",
 
-     return_dimensions: 0,
 
-     parameters_list: [],
 
-     variables_list: [],
 
-     commands: [],
 
-   };
 
-   if (func.returnType instanceof ArrayType) {
 
-     funcDeclaration.return_type = func.returnType.innerType.value;
 
-     funcDeclaration.return_dimensions = func.returnType.dimensions;
 
-   } else {
 
-     funcDeclaration.return_type = func.returnType.value;
 
-   }
 
-   funcDeclaration.parameters_list = func.formalParameters.map(
 
-     functionParameterWalker
 
-   );
 
-   funcDeclaration.variables_list = func.variablesDeclarations.map(
 
-     variableDeclarationWalker
 
-   );
 
-   funcDeclaration.commands = func.commands.map(commandWalker);
 
-   return funcDeclaration;
 
- }
 
- /**
 
-  * @param {Commands.FormalParameter} formalParameter
 
-  * */
 
- function functionParameterWalker (formalParameter) {
 
-   const variable = {
 
-     name: formalParameter.id,
 
-     line: formalParameter.sourceInfo.line,
 
-     type: "",
 
-     rows: 0,
 
-     columns: 0,
 
-     dimension: 0,
 
-     value: 0,
 
-     is_const: false,
 
-     reference: formalParameter.byRef,
 
-   };
 
-   if (formalParameter.type instanceof ArrayType) {
 
-     variable.type = formalParameter.type.innerType.value;
 
-     variable.dimension = formalParameter.type.dimensions;
 
-   } else {
 
-     variable.type = formalParameter.type.value;
 
-   }
 
-   return variable;
 
- }
 
- /**
 
-  * @param {Commands.Declaration} command
 
-  * @param {boolean} global
 
-  * */
 
- function variableDeclarationWalker (command, global = false) {
 
-   const variable = {
 
-     name: command.id,
 
-     line: command.sourceInfo.line,
 
-     type: "",
 
-     rows: 0,
 
-     columns: 0,
 
-     dimension: 0,
 
-     value: 0,
 
-     is_const: false,
 
-   };
 
-   variable.is_const = global && command.isConst;
 
-   if (command instanceof Commands.ArrayDeclaration) {
 
-     // array
 
-     const lines = expressionWalker(command.lines).pop();
 
-     variable.type = command.type.innerType.value;
 
-     if (command.isVector) {
 
-       variable.columns = lines.value;
 
-       variable.dimension = 1;
 
-       const values = command.initial.value.map((exp) =>
 
-         variableInitialWalker(exp)
 
-       );
 
-       variable.value = values;
 
-     } else {
 
-       const columns = expressionWalker(command.columns).pop();
 
-       variable.dimension = 2;
 
-       variable.rows = lines.value;
 
-       variable.columns = columns.value;
 
-       const values = command.initial.value.map((rows) =>
 
-         rows.value.map((exp) => variableInitialWalker(exp))
 
-       );
 
-       variable.value = values;
 
-     }
 
-   } else {
 
-     // atomic
 
-     variable.type = command.type.value;
 
-     variable.value = variableInitialWalker(command.initial);
 
-   }
 
-   return variable;
 
- }
 
- /**
 
-  * @param {any} expression
 
-  * */
 
- function variableInitialWalker (expression) {
 
-   if (expression instanceof Expressions.UnaryApp) {
 
-     const left = variableInitialWalker(expression.left);
 
-     const opType = getOpType(expression.op);
 
-     if (opType !== TYPES.ARITHMETIC) {
 
-       throw new Error(
 
-         "invalid variable initial value: " + expression.toString()
 
-       );
 
-     }
 
-     return `${expression.op.value}${left}`;
 
-   } else if (expression instanceof Expressions.BoolLiteral) {
 
-     const value = expression.value;
 
-     return convertBoolToString(value);
 
-   } else if (expression instanceof Literal) {
 
-     let value = expression.value;
 
-     if (expression.value.toNumber) {
 
-       if (
 
-         Types.REAL.isCompatible(expression.type) &&
 
-         expression.value.decimalPlaces() == 0
 
-       ) {
 
-         value = Number(expression.value.toFixed(2));
 
-       } else {
 
-         value = expression.value.toNumber();
 
-       }
 
-     }
 
-     return value;
 
-   }
 
-   throw new Error("invalid variable initial value: " + expression.toString());
 
- }
 
- /**
 
-  *
 
-  * @return {[]}
 
-  **/
 
- 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.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.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.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 if (expression instanceof Expressions.BoolLiteral) {
 
-     const value = expression.value;
 
-     result = [
 
-       {
 
-         instance: "expression",
 
-         class: "simple",
 
-         type: TYPES.CONST,
 
-         value: convertBoolToString(value),
 
-       },
 
-     ];
 
-   } else {
 
-     let value = expression.value;
 
-     if (expression.value.toNumber) {
 
-       if (
 
-         Types.REAL.isCompatible(expression.type) &&
 
-         expression.value.decimalPlaces() == 0
 
-       ) {
 
-         value = Number(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);
 
- }
 
- /**
 
-  * @param {string} text
 
-  * */
 
- export function parseCode (text) {
 
-   const parser = IVProgParser.createParser(text, false);
 
-   const codeLinesMap = new Map();
 
-   const tokens = Array.from(parser.lexer.reset(text));
 
-   const tokenStream = [];
 
-   for (const token of tokens) {
 
-     if (token.type === parser.ruleNames.ERROR) {
 
-       return null;
 
-     }
 
-     if (token.type === parser.ruleNames.COMMENTS) {
 
-       for (let i = 0; i <= token.lineBreaks; i++) {
 
-         if (codeLinesMap.has(i + token.line))
 
-           codeLinesMap.get(i + token.line).push(token);
 
-         else codeLinesMap.set(i + token.line, [token]);
 
-       }
 
-       continue;
 
-     }
 
-     if (token.type !== parser.ruleNames.WHITESPACE) {
 
-       tokenStream.push(token);
 
-     }
 
-   }
 
-   parser.fill(tokenStream);
 
-   try {
 
-     const program = parser.parseTree();
 
-     const globals = program.global.map((decl) =>
 
-       variableDeclarationWalker(decl, true)
 
-     );
 
-     const functions = program.functions.map(functionWalker);
 
-     return { globals, functions };
 
-   } catch (e) {
 
-     console.error(e);
 
-     return null;
 
-   }
 
- }
 
 
  |