Browse Source

feat: implement initial code parser for visual UI

Implement globals variables parser for visual UI
Implement function parser for visual UI
Implement function variable for visual UI
Lucas de Souza 2 years ago
parent
commit
aa5fd39869
1 changed files with 133 additions and 0 deletions
  1. 133 0
      js/util/parseFromVisual.js

+ 133 - 0
js/util/parseFromVisual.js

@@ -2,6 +2,8 @@ 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";
 
 const TYPES = {
   VARIABLE: "var",
@@ -49,7 +51,105 @@ function getOpType (op) {
       return TYPES.LOGIC;
   }
 }
+/**
+ * @param {Commands.Function} func
+ * */
+function functionWalker (func) {
+  const funcDeclaration = {
+    name: func.name,
+    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
+  );
+  return funcDeclaration;
+}
+
+/**
+ * @param {Commands.FormalParameter} formalParameter
+ * */
+function functionParameterWalker (formalParameter) {
+  const variable = {
+    name: formalParameter.id,
+    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,
+    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.rows = 1;
+      variable.columns = lines.value;
+      variable.dimension = 1;
+      const values = command.initial.map(
+        (exp) => expressionWalker(exp).pop().value
+      );
+      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.map((rows) =>
+        rows.map((exp) => expressionWalker(exp).pop().value)
+      );
+      variable.value = values;
+    }
+  } else {
+    // atomic
+    variable.type = command.type.value;
+    variable.value = expressionWalker(command.initial).pop().value;
+  }
+  return variable;
+}
+
+/**
+ *
+ * @return {[]}
+ **/
 function expressionWalker (expression) {
   let result;
   if (expression instanceof Expressions.VariableLiteral) {
@@ -141,3 +241,36 @@ export function parseExpression (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);
+  const program = parser.parseTree();
+  const globals = program.global.map((decl) =>
+    variableDeclarationWalker(decl, true)
+  );
+  const functions = program.functions.map(functionWalker);
+  return { globals, functions };
+}