def test_mixed_arithmetic(self): n0, n1, n2 = model.Number(1), model.Number(2), model.Number(3) add = model.BinaryOperation(n1, "+", n2) mul = model.BinaryOperation(n0, "*", add) printer = PrettyPrinter() result = printer.visit(mul) assert result == "(1) * ((2) + (3));\n"
def test_num_num(self): n0, n1, n2 = model.Number(4), model.Number(2), model.Number(3) mul = model.BinaryOperation(n0, "*", model.BinaryOperation(n1, "+", n2)) folder = ConstantFolder() tree = folder.visit(mul) assert isinstance(tree, model.Number) and tree.value == 20
def test_conditional(self): scope = model.Scope() scope["a"] = model.Number(10) cond = model.Conditional( model.BinaryOperation(model.Number(4), ">", model.Number(3)), [ model.Assign( "x", model.BinaryOperation(model.Number(3), "-", model.Number(5))), model.Assign( "y", model.BinaryOperation(model.Number(5), "*", model.Number(5))) ], [ model.Assign( "x", model.BinaryOperation(model.Reference("a"), "*", model.Number(0))) ]) folder = ConstantFolder() tree = folder.visit(cond) assert (isinstance(tree, model.Conditional) and tree.condition.value > 0 and isinstance(tree.if_true[0], model.Assign) and tree.if_true[0].value.value == -2 and isinstance(tree.if_true[1], model.Assign) and tree.if_true[1].value.value == 25 and len(tree.if_true) == 2 and len(tree.if_false) == 1 and isinstance(tree.if_false[0], model.Assign) and tree.if_false[0].value.value == 0)
def visit_binary_operation(self, binary_operation): lhs = binary_operation.lhs.accept(self) rhs = binary_operation.rhs.accept(self) if type(lhs) == m.Number and type(rhs) == m.Number: return m.BinaryOperation(lhs, binary_operation.op, rhs).evaluate(self.scope) if (type(rhs) == m.Number and rhs.value == 0 and type(lhs) == m.Reference and binary_operation.op == "*"): return m.Number(0) if (type(lhs) == m.Number and lhs.value == 0 and type(rhs) == m.Reference and binary_operation.op == "*"): return m.Number(0) if (type(lhs) == m.Reference and type(rhs) == m.Reference and lhs.name == rhs.name and binary_operation.op == '-'): return m.Number(0) return m.BinaryOperation(lhs, binary_operation.op, rhs)
def test_assign(self): n1, n2 = model.Number(2), model.Number(3) assign = model.Assign("x", model.BinaryOperation(n1, "+", n2)) folder = ConstantFolder() tree = folder.visit(assign) assert isinstance(tree.value, model.Number) assert tree.value.value == 5
def test_ref_num(self): scope = model.Scope() scope["a"] = model.Number(10) op = model.BinaryOperation(model.Reference("a"), "*", model.Number(0)) folder = ConstantFolder() tree = folder.visit(op) assert isinstance(tree, model.Number) and tree.value == 0
def test_binary_operation(): a = model.Number(10) b = model.Number(20) for op in [ "+", "-", "*", "/", "%", "==", "!=", "<", ">", "<=", ">=", "&&", "||" ]: model.BinaryOperation(a, op, b).evaluate(model.Scope())
def test_ref_num_var(self): op = model.BinaryOperation(model.Reference("a"), "+", model.Number(0)) folder = ConstantFolder() tree = folder.visit(op) assert (isinstance(tree, model.BinaryOperation) and tree.op == "+" and isinstance(tree.rhs, model.Number) and tree.rhs.value == 0 and isinstance(tree.lhs, model.Reference) and tree.lhs.name == "a")
def test_mixed_conditional(self): scope = model.Scope() scope["a"] = model.Number(-10) scope["b"] = model.Number(5) scope["c"] = model.Number(10) """ if not (a == c) and b < c: print(a) """ conditional = model.Conditional( model.BinaryOperation( model.UnaryOperation( "!", model.BinaryOperation(model.Reference("a"), "==", model.Reference("c"))), "&&", model.BinaryOperation(model.Reference("b"), "<", model.Number(42))), [model.Assign("res", model.Reference("a"))]) printer = PrettyPrinter() result = printer.visit(conditional) assert (result == "if ((!((a) == (c))) && ((b) < (42))) {\n\tres =" + " a;\n};\n")
def test_bool_print(): strio = io.StringIO() old_stdout = sys.stdout sys.stdout = strio try: a = model.Number(10) b = model.Number(20) for op in ["==", "!=", "<", ">", "<=", ">=", "&&", "||"]: model.Print(model.BinaryOperation(a, op, b)).evaluate(model.Scope()) finally: sys.stdout = old_stdout map(int, strio.getvalue().split())
def parse_binary(self, min_precedence=LOWEST_PRECEDENCE): left = self.parse_unary() precedence = self.PRECEDENCE.get(self.peek_token().value, 0) while precedence >= min_precedence: operator = self.peek_token() while self.PRECEDENCE.get(operator.value, 0) == precedence: self.drop_tokens() right = self.parse_binary(precedence + 1) left = model.BinaryOperation(left, operator.value, right) operator = self.peek_token() precedence -= 1 return left
def test_function_call(self): scope = model.Scope() scope["x"] = model.Number(10) function = model.Function(["a", "b", "c"], []) model.FunctionDefinition("f", function).evaluate(scope) call = model.FunctionCall(model.Reference("f"), [ model.BinaryOperation(model.Number(2), "*", model.Number(3)), model.BinaryOperation(model.Number(0), "*", model.Reference("x")), model.Reference("x") ]) folder = ConstantFolder() tree = folder.visit(call) assert (isinstance(tree, model.FunctionCall) and isinstance(tree.fun_expr, model.Reference) and tree.fun_expr.name == "f" and len(tree.args) == 3 and isinstance(tree.args[0], model.Number) and tree.args[0].value == 6 and isinstance(tree.args[1], model.Number) and tree.args[1].value == 0 and isinstance(tree.args[2], model.Reference) and tree.args[2].name == "x")
def visit_binary_operation(self, bin_op): lhs = self.visit(bin_op.lhs) rhs = self.visit(bin_op.rhs) if (bin_op.op == '*' and (isinstance(lhs, model.Number) and lhs.number == 0 and isinstance(rhs, model.Reference) or isinstance(rhs, model.Number) and rhs.number == 0 and isinstance(lhs, model.Reference))) or \ (isinstance(lhs, model.Reference) and isinstance(rhs, model.Reference) and bin_op.op == '-' and lhs.name == rhs.name): return model.Number(0) if isinstance(lhs, model.Number) and isinstance(rhs, model.Number): return model.Number(bin_op.operations[bin_op.op](lhs.number, rhs.number)) return model.BinaryOperation(lhs, bin_op.op, rhs)
def test_function_definition(self): scope = model.Scope() function = model.Function(["a"], [ model.Print( model.BinaryOperation(model.Reference('a'), '-', model.Reference("a"))) ]) definition = model.FunctionDefinition("f", function) folder = ConstantFolder() tree = folder.visit(definition) assert (isinstance(tree, model.FunctionDefinition) and tree.name == "f" and len(tree.function.args) == 1 and len(tree.function.body) == 1 and isinstance(tree.function.body[0], model.Print) and isinstance(tree.function.body[0].expr, model.Number) and tree.function.body[0].expr.value == 0)
def mytest(): printer = PrettyPrinter() cond2 = model.Conditional(model.Number(30), [model.Number(10)], [model.Number(20)]) cond = model.Conditional( model.Number(42), [model.Number(1), cond2, model.Number(3)], [model.Number(4), model.Number(5)]) cond3 = model.Conditional(model.Number(228), [], []) func2 = model.Function(('p111', 'p222'), [ model.Reference("x"), model.Print(model.Reference("p111")), model.Read("myVar") ]) fd2 = model.FunctionDefinition("anotherPrettyFunc", func2) func = model.Function( (), [model.UnaryOperation("-", model.Number(100000000)), fd2, cond, cond3]) fd = model.FunctionDefinition("myPrettyFunc", func) printer.visit(fd) asd = model.BinaryOperation( model.BinaryOperation(model.Number(123), "+", model.Reference("xx")), "*", model.UnaryOperation( "-", model.BinaryOperation(model.Reference("xx"), "+", model.Reference("yy")))) printer.visit(asd) asd2 = model.BinaryOperation( model.BinaryOperation(model.Number(123), "/", model.Reference("xx")), "/", model.BinaryOperation( model.BinaryOperation(model.Reference("xx"), "/", model.Reference("yy")), "/", model.BinaryOperation(model.Number(123), "/", model.Reference("yy")))) printer.visit(asd2) printer.visit(model.FunctionCall(model.Reference("func"), [asd, asd2])) cond4 = model.Conditional(model.Number(228), []) printer.visit(cond4)
def test_function_with_body_args(self): parent = model.Scope() parent["f"] = model.Function(("a", "b"), [ model.Print( model.BinaryOperation(model.Reference("a"), "+", model.Reference("b"))) ]) parent["x"] = model.Number(10) scope = model.Scope(parent) scope["y"] = model.Number(20) definition = model.FunctionDefinition("f", parent["f"]) printer = PrettyPrinter() result = printer.visit(definition) assert result == "def f(a, b) {\n\tprint (a) + (b);\n};\n" definition.evaluate(scope) call = model.FunctionCall( model.Reference("f"), [model.Number(5), model.UnaryOperation("-", model.Number(3))]) result = printer.visit(call) assert result == "f(5, -(3));\n"
def test(): folder = ConstantFolder() prr = printer.PrettyPrinter() oper = model.BinaryOperation( model.BinaryOperation( model.BinaryOperation( model.BinaryOperation(model.Number(2), "+", model.Number(3)), "/", model.BinaryOperation(model.Number( 2), "+", model.Reference("x")) ), "/", model.BinaryOperation( model.BinaryOperation(model.Reference( "x"), "-", model.Reference("x")), "/", model.BinaryOperation(model.Reference( "x"), "-", model.Reference("y")) ) ), "/", model.BinaryOperation( model.BinaryOperation( model.BinaryOperation(model.Number( 0), "*", model.Reference("x")), "/", model.UnaryOperation("!", model.Reference("x")) ), "/", model.UnaryOperation("-", model.Number(30)) ), ) opr = model.Conditional(model.UnaryOperation("!", model.Number(2)), [model.Print(model.Number(2))]) prr.visit(oper) prr.visit(opr) noper = folder.visit(oper) nopr = folder.visit(opr) prr.visit(noper) prr.visit(nopr)
def main(): v = PrettyPrinter() v.visit(m.Print(m.Number(10))) v.visit(m.UnaryOperation('-', m.Number(10))) v.visit( m.BinaryOperation( m.BinaryOperation(m.Reference('foo'), '+', m.Number(7)), '*', m.Number(2))) v.visit(m.Read("read")) v.visit( m.Conditional( m.Number(5), [m.BinaryOperation(m.Reference('var'), '-', m.Number(-5))])) v.visit( m.FunctionDefinition( 'summer', m.Function(['a', 'b'], [ m.Print( m.BinaryOperation(m.Reference('a'), '+', m.Reference('b'))), m.BinaryOperation(m.Reference('a'), '+', m.Reference('b')) ]))) v.visit( m.FunctionCall( m.Reference('summer'), [m.Number(1), m.BinaryOperation(m.Number(2), '+', m.Number(3))])) v.visit( m.Print( m.Conditional(m.BinaryOperation(m.Number(4), '-', m.Number(4)), [], [ m.BinaryOperation(m.Number(9), '/', m.Number(3)), m.Reference('var') ]))) v.visit( m.FunctionDefinition( 'abs', m.Function(['a', 'b'], [ m.Conditional( m.BinaryOperation( m.BinaryOperation(m.Reference('a'), '-', m.Reference('b')), '>', m.Number(0)), [ m.Print( m.BinaryOperation(m.Reference('a'), '-', m.Reference('b'))) ], [ m.Print( m.BinaryOperation(m.Reference('b'), '-', m.Reference('a'))) ]) ]))) v.visit( m.FunctionCall( m.Reference('abs'), [m.Number(23), m.UnaryOperation('-', m.Number(-30))])) v.visit(m.FunctionDefinition('fu', m.Function([], []))) v.visit(m.FunctionCall(m.Reference('fu'), [])) v.visit(m.Print(m.BinaryOperation(m.Number(5), '&&', m.Number(6)))) v.visit(m.Print(m.BinaryOperation(m.Number(3), '<', m.Number(5)))) v.visit(m.Print(m.Conditional(m.Number(3), None, None))) v.visit(m.Print(m.BinaryOperation(m.Number(1), '||', m.Number(4))))
def test_unary_operation(self): op = model.UnaryOperation( "-", model.BinaryOperation(model.Number(1), "+", model.Number(2))) folder = ConstantFolder() tree = folder.visit(op) assert isinstance(tree, model.Number) and tree.value == -3
def test_print(self): n1, n2 = model.Number(2), model.Number(3) pr = model.Print(model.BinaryOperation(n1, "+", n2)) folder = ConstantFolder() tree = folder.visit(pr) assert isinstance(tree, model.Print) and tree.expr.value == 5
def test_arithmetic_print(self): my_print = model.Print( model.BinaryOperation(model.Number(0), "+", model.Number(1))) printer = PrettyPrinter() result = printer.visit(my_print) assert result == "print (0) + (1);\n"