Explorar el Código

Update 'js/util/parseFromVisual.js'

Work-in-progress to to allow comment inside code (but is not in the right context).
New function: export function parserCodeVisual (text) by Gleyce
Need to keep "old" function "parseCode(text)".
leo hace 2 meses
padre
commit
f08efbaff1
Se han modificado 1 ficheros con 146 adiciones y 118 borrados
  1. 146 118
      js/util/parseFromVisual.js

+ 146 - 118
js/util/parseFromVisual.js

@@ -1,3 +1,8 @@
+// iVProg - www.usp.br/line/ivprog
+// LInE - Free Education, Private Data
+
+// This is used when is loaded "ivph" file (under the button "upload" or GET)
+
 import { IVProgParser } from "../ast/ivprogParser";
 import * as Expressions from "../ast/expressions";
 import { Types } from "../typeSystem/types";
@@ -13,7 +18,7 @@ const TYPES = {
   RELATIONAL: "relational",
   LOGIC: "logic",
   ARITHMETIC: "arithmetic",
-};
+  };
 
 function translateOp (type, op) {
   switch (type) {
@@ -28,10 +33,10 @@ function translateOp (type, op) {
         return "or";
       } else {
         return "not";
+        }
       }
     }
   }
-}
 
 function getOpType (op) {
   switch (op.ord) {
@@ -50,24 +55,24 @@ function getOpType (op) {
       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);
+  const expression = switchCase.isDefault ? null : expressionWalker(switchCase.expression);
   return {
     type: "switchcase",
     line: switchCase.sourceInfo.line,
     expression,
     commands,
-  };
-}
+    };
+  }
+
 
 /**
  * @param {Commands.Switch} switchCommand
@@ -79,8 +84,9 @@ function switchWalker (switchCommand) {
     type: "switch",
     expression,
     cases,
-  };
-}
+    };
+  }
+
 
 /**
  * @param {Commands.Return} returnCommand
@@ -89,16 +95,18 @@ function returnWalker (returnCommand) {
   let expression = null;
   if (returnCommand.expression !== null) {
     expression = expressionWalker(returnCommand.expression);
-  }
+    }
   return {
     type: "return",
     expression,
-  };
-}
+    };
+  }
+
 
 function breakWalker (_) {
   return { type: "break" };
-}
+  }
+
 
 /**
  * @param {Commands.For} forLoop
@@ -107,9 +115,7 @@ 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 step_expression = forLoop.for_pass ? expressionWalker(forLoop.for_pass) : [];
   const commands = forLoop.commands.map(commandWalker);
   return {
     type: "repeatNtimes",
@@ -118,8 +124,8 @@ function forWalker (forLoop) {
     condition,
     step_expression,
     commands,
-  };
-}
+    };
+  }
 
 /**
  * @param {Commands.While} whileLoop
@@ -132,8 +138,9 @@ function whileWalker (whileLoop) {
     type,
     expression,
     commands,
-  };
-}
+    };
+  }
+
 
 /**
  * @param {Commands.IfThenElse} ifthenelse
@@ -148,16 +155,17 @@ function ifThenElseWalker (ifthenelse) {
       ifFalse = ifthenelse.ifFalse.commands.map(commandWalker);
     } else {
       ifFalse = [ifThenElseWalker(ifthenelse.ifFalse)];
+      }
     }
-  }
   return {
     type: "iftrue",
     expression,
     ifTrue,
     ifFalse,
-  };
+    };
 }
 
+
 /**
  * @param {Commands.Assign} assingment
  * */
@@ -170,29 +178,27 @@ function assignmentWalker (assingment) {
     if (assingment.column) {
       arrayClass = "matrix";
       column = expressionWalker(assingment.column);
-    }
-    variable = [
-      {
+      }
+    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 },
-    ];
-  }
+    variable = [ { instance: "expression", type: TYPES.VARIABLE, value: assingment.id }, ];
+    }
   const expression = expressionWalker(assingment.expression);
   return {
     type: "attribution",
     variable,
     expression,
-  };
-}
+    };
+  }
+
 
 /**
  * @param {Command} command
@@ -217,10 +223,11 @@ function commandWalker (command) {
     parsedCommand = forWalker(command);
   } else {
     throw new Error("not implemented");
-  }
+    }
   parsedCommand.line = command.sourceInfo.line;
   return parsedCommand;
-}
+  }
+
 
 /**
  * @param {Commands.FunctionCall} functionCall
@@ -229,33 +236,33 @@ 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;
+    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
  * */
@@ -268,22 +275,19 @@ function functionWalker (func) {
     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.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
@@ -299,15 +303,16 @@ function functionParameterWalker (formalParameter) {
     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
@@ -323,7 +328,7 @@ function variableDeclarationWalker (command, global = false) {
     dimension: 0,
     value: 0,
     is_const: false,
-  };
+    };
   variable.is_const = global && command.isConst;
   if (command instanceof Commands.ArrayDeclaration) {
     // array
@@ -332,31 +337,26 @@ function variableDeclarationWalker (command, global = false) {
     if (command.isVector) {
       variable.columns = lines.value;
       variable.dimension = 1;
-      const values = command.initial.value.map((exp) =>
-        variableInitialWalker(exp)
-      );
+      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))
-      );
+      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
- * */
+
+/// @param {any} expression
 function variableInitialWalker (expression) {
   if (expression instanceof Expressions.UnaryApp) {
     const left = variableInitialWalker(expression.left);
@@ -373,39 +373,32 @@ function variableInitialWalker (expression) {
   } else if (expression instanceof Literal) {
     let value = expression.value;
     if (expression.value.toNumber) {
-      if (
-        Types.REAL.isCompatible(expression.type) &&
-        expression.value.decimalPlaces() == 0
-      ) {
+      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 {[]}
- **/
+
+/// @return {[]}
 function expressionWalker (expression) {
   let result;
   if (expression instanceof Expressions.VariableLiteral) {
-    result = [
-      { instance: "expression", type: TYPES.VARIABLE, value: expression.id },
-    ];
+    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];
@@ -423,7 +416,7 @@ function expressionWalker (expression) {
       ...left,
       { instance: "operator", type: opType, value: opValue },
       ...right,
-    ];
+      ];
   } else if (expression instanceof Expressions.ArrayAccess) {
     const line = expressionWalker(expression.line);
     let arrayClass = "vector";
@@ -431,27 +424,25 @@ function expressionWalker (expression) {
     if (expression.column) {
       arrayClass = "matrix";
       column = expressionWalker(expression.column);
-    }
-    result = [
-      {
+      }
+    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 = [
-      {
+    result = [ {
         instance: "expression",
         class: "simple",
         type: TYPES.CONST,
         value: convertBoolToString(value),
-      },
-    ];
+        },
+      ];
   } else {
     let value = expression.value;
     if (expression.value.toNumber) {
@@ -462,31 +453,34 @@ function expressionWalker (expression) {
         value = Number(expression.value.toFixed(2));
       } else {
         value = expression.value.toNumber();
+        }
       }
+    result = [ { instance: "expression", class: "simple", type: TYPES.CONST, value: value, }, ];
     }
-    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
- * */
+
+/// @param {string} text
+/// @calledby js/util/iassignHelpers.js!setPreviousAlgorithm(code)
 export function parseCode (text) {
+  console.log("js/util/parseFromVisual.js!parseCode(text): can this function be removed? If is it appearing in log, then no...");
+  //D console.trace();
+  return parserCodeVisual(text);
+  }
+
+/// @param {string} text
+/// @calledby js/util/iassignHelpers.js!setPreviousAlgorithm(code)
+export function parserCodeVisual (text) { // Gleyce
+  console.log("js/util/parseFromVisual.js!parserCodeVisual(text): starting");
+  //D console.trace();
   const parser = IVProgParser.createParser(text, false);
   const codeLinesMap = new Map();
   const tokens = Array.from(parser.lexer.reset(text));
@@ -494,29 +488,63 @@ export function parseCode (text) {
   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);
+
+    //Gleyce start: new code to read IVPH file with comment (//)
+    const allComments = [];
+    for (const [line, commentTokens] of codeLinesMap.entries()) {
+      for (const token of commentTokens) {
+        const commentText = token.text.replace(/^\/\//, '').trim();
+        allComments.push({
+          type: "comment",
+          comment_text: commentText,
+          line: token.line,
+          });
+        }
+      }
+    const astFunctions = program.functions;
+    functions.forEach((visualFunc, index) => {
+      const astFunc = astFunctions[index];
+      const funcStartLine = astFunc.sourceInfo.line;
+      let funcEndLine;
+      if (astFunctions[index + 1]) {
+        funcEndLine = astFunctions[index + 1].sourceInfo.line;
+      } else {
+        funcEndLine = Infinity;
+        }
+      const funcComments = allComments.filter(comment =>
+        comment.line > funcStartLine && comment.line < funcEndLine
+        );
+      if (funcComments.length > 0) {
+        const allCommands = [...visualFunc.commands, ...funcComments];
+        allCommands.sort((a, b) => a.line - b.line);
+        visualFunc.commands = allCommands;
+        }
+      });
+    //Gleyce end: new code to read IVPH file with comment (//)
+
     return { globals, functions };
   } catch (e) {
     console.error(e);
     return null;
-  }
-}
+    }
+  }