Forráskód Böngészése

Implement SwitchCase parser and a test case

Lucas de Souza 6 éve
szülő
commit
4573b5bfef

+ 15 - 0
js/ast/commands/case.js

@@ -0,0 +1,15 @@
+export class Case {
+
+  constructor (expression) {
+    this.expression = expression;
+    this.commands = [];
+  }
+
+  setCommands (commands) {
+    this.commands = commands;
+  }
+
+  get isDefault () {
+    return this.expression === null;
+  }
+}

+ 5 - 1
js/ast/commands/index.js

@@ -9,6 +9,8 @@ import { Function } from './function';
 import { IfThenElse } from './ifThenElse';
 import { CommandBlock } from './commandBlock';
 import { DoWhile } from './doWhile';
+import { Switch } from './switch';
+import { Case } from './case';
 
 export {
   Break,
@@ -21,5 +23,7 @@ export {
   Function,
   IfThenElse,
   CommandBlock,
-  DoWhile
+  DoWhile,
+  Switch,
+  Case
 };

+ 6 - 0
js/ast/commands/switch.js

@@ -0,0 +1,6 @@
+export class Switch {
+  
+  constructor (cases) {
+    this.cases = cases;
+  }
+}

+ 34 - 3
js/ast/ivprogParser.js

@@ -568,14 +568,14 @@ export class IVProgParser {
     this.checkOpenCurly();
     this.pos++;
     this.consumeNewLines();
-    const switchCases = this.parseCases();
+    const casesList = this.parseCases();
     this.consumeNewLines();
     this.checkCloseCurly();
     this.pos++;
     this.consumeNewLines();
 
     this.popScope();
-    return null;
+    return new Commands.Switch(casesList);
   }
 
   parseDoWhile () {
@@ -730,7 +730,38 @@ export class IVProgParser {
     if(token.type !== this.lexerClass.RK_CASE) {
       throw SyntaxError.createError(this.lexer.literalNames[this.lexerClass.RK_CASE], token);
     }
-
+    this.pos++;
+    const nextToken = this.getToken();
+    if(nextToken.type === this.lexerClass.RK_DEFAULT) {
+      this.pos++;
+      const colonToken = this.getToken();
+      if (colonToken.type !== this.lexerClass.COLON) {
+        throw SyntaxError.createError(':', colonToken);
+      }
+      this.pos++;
+      this.consumeNewLines();
+      const block = this.parseCommandBlock(true);
+      const defaultCase = new Commands.Case(null);
+      defaultCase.setCommands(block.commands);
+      return [defaultCase];
+    } else {
+      const exp = this.parseExpressionOR();
+      const colonToken = this.getToken();
+      if (colonToken.type !== this.lexerClass.COLON) {
+        throw SyntaxError.createError(':', colonToken);
+      }
+      this.pos++;
+      this.consumeNewLines();
+      const block = this.parseCommandBlock(true);
+      const aCase = new Commands.Case(exp);
+      aCase.setCommands(block.commands);
+      const caseToken = this.getToken();
+      if(caseToken.type === this.lexerClass.RK_CASE) {
+        return [aCase].concat(this.parseCases());
+      } else {
+        return [aCase];
+      }
+    }
   }
 
   /*

+ 25 - 0
tests/test12.spec.js

@@ -0,0 +1,25 @@
+import Lexers from './../grammar/';
+import {
+    IVProgParser
+} from './../js/ast/ivprogParser';
+import {
+    SyntaxError
+} from './../js/ast/SyntaxError';
+
+describe('SwitchCase command', () => {
+    let input = `funcao inteiro test(real i) {
+      escolha (i) {
+        caso 1:
+          retorne 0
+        casocontrario:
+          retorne 4
+      }
+    }`;
+    const lexer = Lexers['pt_br'];
+
+    it(`should not result in SyntaxError`, () => {
+        const as = new IVProgParser(input, lexer);
+        const fun = as.parseFunction.bind(as);
+        expect(fun).not.toThrow(SyntaxError);
+    });
+});