Ver Fonte

feat: implement parsers for missing visual UI commands

Implement return and break command parser for visual UI
Implement while and doWhile (repeatUntil) parser for visual UI
Implement switch case parser for visual UI
Add error log for exception during parseCode calls
Add line information for all commands parsed by parseCode
Lucas de Souza há 2 anos atrás
pai
commit
b53c89bbc5
2 ficheiros alterados com 105 adições e 12 exclusões
  1. 10 6
      js/ast/ivprogParser.js
  2. 95 6
      js/util/parseFromVisual.js

+ 10 - 6
js/ast/ivprogParser.js

@@ -14,9 +14,9 @@ export class IVProgParser {
     const lexer = LanguageService.getCurrentLexer();
     const parser = new IVProgParser(input, lexer);
     if (fill) {
-      parser.fill()
+      parser.fill();
     }
-    return parser
+    return parser;
   }
 
   // <BEGIN scope consts>
@@ -43,7 +43,7 @@ export class IVProgParser {
       offset: -1,
       lineBreaks: false,
       type: "EOF",
-    }
+    };
   }
 
   /**
@@ -103,7 +103,7 @@ export class IVProgParser {
     // if(index === null)
     //   index = this.pos;
     if (index >= this.tokenStream.length) {
-      return IVProgParser.EOF_TOKEN
+      return IVProgParser.EOF_TOKEN;
     }
     return this.tokenStream[index];
   }
@@ -173,7 +173,7 @@ export class IVProgParser {
       this.pos++;
       this.consumeNewLines();
       if (!this.isEOF()) {
-        console.log(this.getToken())
+        console.log(this.getToken());
         throw SyntaxErrorFactory.extra_lines();
       }
       this.popVariableStack();
@@ -757,6 +757,7 @@ export class IVProgParser {
       throw SyntaxErrorFactory.main_parameters();
     }
     this.popScope();
+    func.sourceInfo = SourceInfo.createSourceInfo(funcIDToken);
     return func;
   }
 
@@ -1125,6 +1126,7 @@ export class IVProgParser {
   }
 
   parseReturn () {
+    const token = this.getToken();
     this.pos++;
     let exp = null;
     if (!this.checkEOS(true)) {
@@ -1132,7 +1134,9 @@ export class IVProgParser {
       this.checkEOS();
     }
     this.pos++;
-    return new Commands.Return(exp);
+    const returnCommand =  new Commands.Return(exp);
+    returnCommand.sourceInfo = SourceInfo.createSourceInfo(token);
+    return returnCommand;
   }
 
   parseIDCommand () {

+ 95 - 6
js/util/parseFromVisual.js

@@ -1,5 +1,4 @@
 import { IVProgParser } from "../ast/ivprogParser";
-
 import * as Expressions from "../ast/expressions";
 import { Types } from "../typeSystem/types";
 import { convertBoolToString } from "../typeSystem/parsers";
@@ -54,6 +53,80 @@ function getOpType (op) {
   }
 }
 
+/**
+ * @param {Commands.Case} switchCase
+ * */
+function switchCaseWalker (switchCase) {
+  const commands = switchCase.commands.map(commandWalker);
+  const expression = switchCase.isDefault
+    ? null
+    : expressionWalker(switchCase.expression);
+  return {
+    type: "switchcase",
+    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 = forLoop.for_id;
+//   const commands = forLoop.commands.map(commandWalker)
+//
+//     return {var_attribution,
+//  var_incrementation,
+//  expression1,
+//  expression2,
+//  expression3,
+//  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
  * */
@@ -117,14 +190,26 @@ function assignmentWalker (assingment) {
  * @param {Command} command
  * */
 function commandWalker (command) {
+  let parsedCommand = null;
   if (command instanceof Commands.FunctionCall) {
-    return functionCallWalker(command);
+    parsedCommand = functionCallWalker(command);
   } else if (command instanceof Commands.Assign) {
-    return assignmentWalker(command);
+    parsedCommand = assignmentWalker(command);
   } else if (command instanceof Commands.IfThenElse) {
-    return ifThenElseWalker(command);
+    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 {
+    throw new Error("not implemented");
   }
-  throw new Error("not implemented");
+  parsedCommand.line = command.sourceInfo.line;
+  return parsedCommand;
 }
 
 /**
@@ -167,6 +252,7 @@ function functionCallWalker (functionCall) {
 function functionWalker (func) {
   const funcDeclaration = {
     name: func.name,
+    line: func.sourceInfo.line,
     return_type: "",
     return_dimensions: 0,
     parameters_list: [],
@@ -195,6 +281,7 @@ function functionWalker (func) {
 function functionParameterWalker (formalParameter) {
   const variable = {
     name: formalParameter.id,
+    line: formalParameter.sourceInfo.line,
     type: "",
     rows: 0,
     columns: 0,
@@ -219,6 +306,7 @@ function functionParameterWalker (formalParameter) {
 function variableDeclarationWalker (command, global = false) {
   const variable = {
     name: command.id,
+    line: command.sourceInfo.line,
     type: "",
     rows: 0,
     columns: 0,
@@ -418,7 +506,8 @@ export function parseCode (text) {
     );
     const functions = program.functions.map(functionWalker);
     return { globals, functions };
-  } catch {
+  } catch (e) {
+    console.error(e)
     return null;
   }
 }