Commits

Alex Gaynor committed bc71a31

Comparisons and more parsing.

Comments (0)

Files changed (3)

minijs/grammar.txt

+IGNORE: "[ \t\n]";
+
+ADD_OPER: "[+-]";
+MULT_OPER: "[*/]";
+COMP_OPER: "(==)|(>=)|(<=)|>|<|(!=)";
+
 FLOAT: "[0-9]+";
+
 main: statement* [EOF];
 
 statement: expr ";";
 
 expr: comparison;
 
-comparison: primary;
+comparison: additive COMP_OPER comparison | additive;
+additive: multitive ADD_OPER additive | multitive;
+multitive: primary MULT_OPER multitive | primary;
 primary: atom;
-atom: FLOAT;
+atom: FLOAT;
     def __init__(self, expr):
         self.expr = expr
 
+class BinOp(Node):
+    def __init__(self, op, lhs, rhs):
+        self.op = op
+        self.lhs = lhs
+        self.rhs = rhs
+
 class ConstantFloat(Node):
     def __init__(self, floatval):
         self.floatval = floatval
     def visit_expr(self, node):
         if node.symbol == "expr":
             node = node.children[0]
-        if node.symbol == "comparison":
+
+        symname = node.symbol
+        if symname in ["additive", "multitive", "comparison"]:
             return self.visit_subexpr(node)
-        elif node.symbol == "primary":
+        elif symname == "primary":
             return self.visit_primary(node)
         raise NotImplementedError
 
     def visit_subexpr(self, node):
         if len(node.children) == 1:
             return self.visit_expr(node.children[0])
+        return BinOp(
+            node.children[1].additional_info,
+            self.visit_expr(node.children[0]),
+            self.visit_expr(node.children[2]),
+        )
         raise NotImplementedError
 
     def visit_primary(self, node):

tests/test_parser.py

-from minijs.parser import Block, Stmt, ConstantFloat
+from minijs.parser import Block, Stmt, BinOp, ConstantFloat
 
 
 class TestParser(object):
     def test_const_float(self, space):
-        assert space.parse("1;") == Block([Stmt(ConstantFloat(1))])
+        assert space.parse("1;") == Block([Stmt(ConstantFloat(1))])
+
+    def test_binary_expressions(self, space):
+        assert space.parse("1 + 1;") == Block([Stmt(BinOp("+", ConstantFloat(1), ConstantFloat(1)))])
+        assert space.parse("2 - 3;") == Block([Stmt(BinOp("-", ConstantFloat(2), ConstantFloat(3)))])
+
+    def test_multi_term_expr(self, space):
+        assert space.parse("1 - 2 * 3;") == Block([Stmt(BinOp("-", ConstantFloat(1), BinOp("*", ConstantFloat(2), ConstantFloat(3))))])
+
+    def test_comparisons(self, space):
+        assert space.parse("1 > 2;") == Block([Stmt(BinOp(">", ConstantFloat(1), ConstantFloat(2)))])
+