Browse Source

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

+ 95 - 6
js/util/parseFromVisual.js

@@ -1,5 +1,4 @@
 import { IVProgParser } from "../ast/ivprogParser";
 import { IVProgParser } from "../ast/ivprogParser";
-
 import * as Expressions from "../ast/expressions";
 import * as Expressions from "../ast/expressions";
 import { Types } from "../typeSystem/types";
 import { Types } from "../typeSystem/types";
 import { convertBoolToString } from "../typeSystem/parsers";
 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
  * @param {Commands.IfThenElse} ifthenelse
  * */
  * */
@@ -117,14 +190,26 @@ function assignmentWalker (assingment) {
  * @param {Command} command
  * @param {Command} command
  * */
  * */
 function commandWalker (command) {
 function commandWalker (command) {
+  let parsedCommand = null;
   if (command instanceof Commands.FunctionCall) {
   if (command instanceof Commands.FunctionCall) {
-    return functionCallWalker(command);
+    parsedCommand = functionCallWalker(command);
   } else if (command instanceof Commands.Assign) {
   } else if (command instanceof Commands.Assign) {
-    return assignmentWalker(command);
+    parsedCommand = assignmentWalker(command);
   } else if (command instanceof Commands.IfThenElse) {
   } 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) {
 function functionWalker (func) {
   const funcDeclaration = {
   const funcDeclaration = {
     name: func.name,
     name: func.name,
+    line: func.sourceInfo.line,
     return_type: "",
     return_type: "",
     return_dimensions: 0,
     return_dimensions: 0,
     parameters_list: [],
     parameters_list: [],
@@ -195,6 +281,7 @@ function functionWalker (func) {
 function functionParameterWalker (formalParameter) {
 function functionParameterWalker (formalParameter) {
   const variable = {
   const variable = {
     name: formalParameter.id,
     name: formalParameter.id,
+    line: formalParameter.sourceInfo.line,
     type: "",
     type: "",
     rows: 0,
     rows: 0,
     columns: 0,
     columns: 0,
@@ -219,6 +306,7 @@ function functionParameterWalker (formalParameter) {
 function variableDeclarationWalker (command, global = false) {
 function variableDeclarationWalker (command, global = false) {
   const variable = {
   const variable = {
     name: command.id,
     name: command.id,
+    line: command.sourceInfo.line,
     type: "",
     type: "",
     rows: 0,
     rows: 0,
     columns: 0,
     columns: 0,
@@ -418,7 +506,8 @@ export function parseCode (text) {
     );
     );
     const functions = program.functions.map(functionWalker);
     const functions = program.functions.map(functionWalker);
     return { globals, functions };
     return { globals, functions };
-  } catch {
+  } catch (e) {
+    console.error(e)
     return null;
     return null;
   }
   }
 }
 }