Commits

Maciej Fijalkowski committed 38539bb

implement while

  • Participants
  • Parent commits 6edfc2f

Comments (0)

Files changed (3)

kermit/grammar.txt

 
 IGNORE: "[ \t\n]";
 DECIMAL: "-?0|[1-9][0-9]*";
-ADD_SYMBOL: "[-+]";
+ADD_SYMBOL: "(==)|[-+]";
 VARIABLE: "[a-zA-Z_][a-zA-Z0-9_]*";
 
 main: statement* [EOF];
 
-statement: expr ";" | VARIABLE "=" expr ";";
+statement: expr ";" | VARIABLE "=" expr ";" | "while" "(" expr ")" "{" statement* "}";
 
 expr: atom ADD_SYMBOL expr | atom;
 

kermit/sourceparser.py

         self.varname = varname
         self.expr = expr
 
+class While(Node):
+    """ Simple loop
+    """
+    def __init__(self, cond, body):
+        self.cond = cond
+        self.body = body
+
 class Transformer(object):
     """ Transforms AST from the obscure format given to us by the ennfparser
     to something easier to work with
     """
-    def visit_main(self, node):
-        star = node.children[0]
+    def _grab_stmts(self, star):
         stmts = []
         while len(star.children) == 2:
             stmts.append(self.visit_stmt(star.children[0]))
             star = star.children[1]
         stmts.append(self.visit_stmt(star.children[0]))
+        return stmts
+    
+    def visit_main(self, node):
+        stmts = self._grab_stmts(node.children[0])
         return Block(stmts)
 
     def visit_stmt(self, node):
         if len(node.children) == 4:
             return Assignment(node.children[0].additional_info,
                               self.visit_expr(node.children[2]))
+        if node.children[0].additional_info == 'while':
+            cond = self.visit_expr(node.children[2])
+            stmts = self._grab_stmts(node.children[5])
+            return While(cond, Block(stmts))
         raise NotImplementedError
 
     def visit_expr(self, node):

kermit/test/test_parser.py

 
 from kermit.sourceparser import parse, Stmt, Block, ConstantInt, BinOp,\
-     Variable, Assignment
+     Variable, Assignment, While
 
 def test_parse_basic():
     assert parse('13;') == Block([Stmt(ConstantInt(13))])
 
 def test_assignment():
     assert parse('a = 3;') == Block([Assignment('a', ConstantInt(3))])
+
+def test_while():
+    assert parse('while (1) { a = 3; }') == Block([While(ConstantInt(1),
+              Block([Assignment('a', ConstantInt(3))]))])