def test_comparision_correct(self, arg1, arg2): tree = tr("op_3_0", tr("variable", "a"), tr("variable", "b")) stack = Stack() stack.add_global("a", arg1) stack.add_global("b", arg2) expr: Expression = parser.handle(tree, stack) assert expr.type == Bool
def test_negation_correct_type(self, type): tree = tr("negation", tr("variable", "a")) stack = Stack() stack.add_global("a", type) expression = parser.handle(tree, stack) assert expression.expression == ["-(", "a", ")"] assert expression.type == type
def test_exception(): code = """ func f() throw() end f() """ stack = Stack() stack.add_global("throw", Function(([], Void))) expressions = parser.parse(code, stack) def throw_function(): raise ValueError("~~error~~") writer = MockTracebackWriter() writer.print_traceback = MagicMock() context = ExecutionContext({"throw": throw_function}) context.compile(expressions) context.execute(writer) error: RuntimeError = writer.print_traceback.call_args_list[0][0][0] assert str(error) == "~~error~~" assert tuple(error.stack_entries[0]) == ("f", 2) assert tuple(error.stack_entries[1]) == (None, 3) assert context.code_map[2] == 2 assert context.code_map[3] == 5
def test_execution_integration(): """ Computing pi by integrating: \\frac{\\pi}{2} = \\int^1_{-1} \\sqrt{1 - x^2} dx """ code = """ let delta_x: real = 0.001 let x: real = -1 let y: real = sqrt(1 - x * x) let result: real while x + delta_x < 1 do let next_x: real = x + delta_x let next_y: real = sqrt(1 - next_x * next_x) result = result + (y + next_y) / 2 * delta_x y = next_y x = next_x end print(result * 2) """ stack = Stack() stack.add_global("print", Function(([Real], Void))) stack.add_global("sqrt", Function(([Real], Real))) expressions = parser.parse(code, stack) context = ExecutionContext(dict(print=MagicMock(), sqrt=math.sqrt)) context.compile(expressions) context.execute(MockTracebackWriter()) return_value = context.globals["print"].call_args[0][0] assert abs(return_value - math.pi) < 0.01
def test_global_variable_exist(): tree = tr("variable", "a") stack = Stack() stack.add_global("a", Real) expression: Expression = parser.handle(tree, stack) assert expression.type == Real assert expression.expression == ["a"]
def test_comparision_incorrect(self, arg1, arg2): tree = tr("op_3_0", tr("variable", "a"), tr("variable", "b")) stack = Stack() stack.add_global("a", arg1) stack.add_global("b", arg2) with pytest.raises(CompileTimeError): parser.handle(tree, stack)
def test_list_type_error(self): stack = Stack() stack.add_global("a", List(Bool)) tree = tr("var_assignment", tr("collection_item", tr("variable", "a"), tr("int_literal", "2")), tr("int_literal", "42")) with pytest.raises(ValueTypeError): parser.handle(tree, stack)
def test_list(self): stack = Stack() stack.add_global("a", List(Real)) tree = tr("var_assignment", tr("collection_item", tr("variable", "a"), tr("int_literal", "2")), tr("int_literal", "42")) expression = parser.handle(tree, stack) assert expression.expression == ["(", "a", ")[", "2", "]", " = ", "42"]
def test_no_args(self): stack = Stack() stack.add_global("func", Function(([], Integer))) tree = tr("func_call", "func") expression = parser.handle(tree, stack) assert expression.type == Integer assert expression.expression == ["func", "()"]
def test_list_reference(): stack = Stack() stack.add_global("a", List(Bool)) tree = tr("collection_item", tr("variable", "a"), tr("int_literal", "12")) expression = parser.handle(tree, stack) assert expression.expression == ["(", "a", ")[", "12", "]"] assert expression.type == Bool
def test_globals(): stack = Stack() stack.add_global("a", List(Integer)) stack.add_variable("b", Real) g = stack.get_variable("a") assert g.type == List(Integer) assert g.number == -1 stack.add_variable("a", Bool) g = stack.get_variable("a") assert g.type == Bool assert g.number == 1
def test_pascals_triangle(): """ Computes five lines of Pascal's triangle: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 Values are returned via `print` function line by line separated by `0`. """ code = """ let result: list of list of int let row_size: int = 1 repeat 5 times let row: list of int = new_list(row_size, 1) let i: int = 1 while i < row_size - 1 do row[i] = result[size(result) - 1][i] + result[size(result) - 1][i - 1] i = i + 1 end add_last(result, row) row_size = row_size + 1 end for row in result do for x in row do print(x) end print(0) end """ stack = Stack() stack.add_global("print", Function(([Integer], Void))) stdlib.initialize_stack(stack) expressions = parser.parse(code, stack) print_fn = MagicMock() context = ExecutionContext(dict(print=print_fn, **stdlib.exec_globals)) context.compile(expressions) context.execute(MockTracebackWriter()) return_value = [x[0][0] for x in print_fn.call_args_list] assert return_value == [ 1, 0, 1, 1, 0, 1, 2, 1, 0, 1, 3, 3, 1, 0, 1, 4, 6, 4, 1, 0 ]
def test_function_call(self, is_global): stack = Stack() stack.add_variable("array", List(Integer)) func = Function(([Integer, Real, List(Integer)], Void)) if is_global: stack.add_global("func", func) else: stack.add_variable("func", func) tree = tr("func_call", "func", tr("int_literal", "1"), tr("int_literal", "2"), tr("variable", "array")) expression = parser.handle(tree, stack) assert expression.type == Void func_name = "func" if is_global else "var_1" assert expression.expression == [func_name, "(", "1", ", ", "2", ", ", "var_0", ")"]
def test_execution_gcd(): code = """ let a: int = 15 let b: int = 6 while a != 0 and b != 0 do if a > b then a = a - b else b = b - a end end print (a + b) """ stack = Stack() stack.add_global("print", Function(([Integer], Void))) expressions = parser.parse(code, stack) context = ExecutionContext(dict(print=MagicMock())) context.compile(expressions) context.execute(MockTracebackWriter()) assert tuple(context.globals["print"].call_args[0]) == (3, )
def test_functions(): code = """ func compute() func r(x: int): int func g(x: int): int return x - 1 end let c: int while x != 0 do x = g(x) c = c + 1 end return c end let i: int = 1 while true do if i == 5 then return end print(r(i)) i = i + 1 end end compute() """ stack = Stack() stack.add_global("print", Function(([Integer], Void))) stdlib.initialize_stack(stack) expressions = parser.parse(code, stack) print_fn = MagicMock() context = ExecutionContext(dict(print=print_fn, **stdlib.exec_globals)) context.compile(expressions) context.execute(MockTracebackWriter()) return_value = [x[0][0] for x in print_fn.call_args_list] assert return_value == [1, 2, 3, 4]
def test_execution_simple(): code = """ let x: int = -15 let y: int = x * abs(x + a) print(x * y) """ stack = Stack() stack.add_global("a", Integer) stack.add_global("abs", Function(([Integer], Integer))) stack.add_global("print", Function(([Integer], Void))) expressions = parser.parse(code, stack) globals = {"a": 10, "abs": abs, "print": MagicMock()} context = ExecutionContext(globals) context.compile(expressions) context.execute(MockTracebackWriter()) assert tuple(globals["print"].call_args[0]) == (1125, )
def create_stack(a: Type, b: Type, c: Type) -> Stack: stack = Stack() stack.add_global("a", a) stack.add_global("b", b) stack.add_global("c", c) return stack
def test_readonly(self): stack = Stack() stack.add_global("var", Real) tree = tr("var_assignment", "var", tr("int_literal", "0")) with pytest.raises(CompileTimeError): parser.handle(tree, stack)
def test_type_error(self): stack = Stack() stack.add_global("var", List(Integer)) tree = tr("var_assignment", "var", tr("int_literal", "0")) with pytest.raises(CompileTimeError): parser.handle(tree, stack)
def test_list_reference_not_array(): stack = Stack() stack.add_global("a", Real) tree = tr("collection_item", tr("variable", "a"), tr("int_literal", "12")) with pytest.raises(ValueTypeError): parser.handle(tree, stack)
def test_negation_illegal_type(self): tree = tr("negation", tr("variable", "a")) stack = Stack() stack.add_global("a", Bool) with pytest.raises(ValueTypeError): parser.handle(tree, stack)
def test_list_reference_wrong_index_type(): stack = Stack() stack.add_global("a", List(Integer)) tree = tr("collection_item", tr("variable", "a"), tr("float_literal", "12.2")) with pytest.raises(ValueTypeError): parser.handle(tree, stack)
def create_stack(): stack = Stack() stack.add_global("a", Pattern) stack.add_global("b", Pattern) stack.add_global("c", Side) return stack