From 83b0b705ae9eaa094665280806f0c354d80b01c2 Mon Sep 17 00:00:00 2001 From: "Johan B.W. de Vries" Date: Sun, 19 Jun 2022 15:20:47 +0200 Subject: [PATCH] If statement, more operators --- py2wasm/compiler.py | 29 +++++++++++++++++++++++++++++ py2wasm/ourlang.py | 2 +- tests/integration/test_simple.py | 16 +++++++--------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/py2wasm/compiler.py b/py2wasm/compiler.py index 425adb6..72a87a3 100644 --- a/py2wasm/compiler.py +++ b/py2wasm/compiler.py @@ -28,6 +28,13 @@ OPERATOR_MAP = { '-': 'sub', } +I32_OPERATOR_MAP = { # TODO: Introduce UInt32 type + '<': 'lt_s', + '>': 'gt_s', + '<=': 'le_s', + '>=': 'ge_s', +} + def expression(inp: ourlang.Expression) -> Statements: if isinstance(inp, ourlang.ConstantInt32): yield wasm.Statement('i32.const', str(inp.value)) @@ -57,6 +64,9 @@ def expression(inp: ourlang.Expression) -> Statements: if operator := OPERATOR_MAP.get(inp.operator, None): yield wasm.Statement(f'i32.{operator}') return + if operator := I32_OPERATOR_MAP.get(inp.operator, None): + yield wasm.Statement(f'i32.{operator}') + return if isinstance(inp.type, ourlang.OurTypeInt64): if operator := OPERATOR_MAP.get(inp.operator, None): yield wasm.Statement(f'i64.{operator}') @@ -78,11 +88,30 @@ def statement_return(inp: ourlang.StatementReturn) -> Statements: yield from expression(inp.value) yield wasm.Statement('return') +def statement_if(inp: ourlang.StatementIf) -> Statements: + yield from expression(inp.test) + + yield wasm.Statement('if') + + for stat in inp.statements: + yield from statement(stat) + + if inp.else_statements: + yield wasm.Statement('else') + for stat in inp.else_statements: + yield from statement(stat) + + yield wasm.Statement('end') + def statement(inp: ourlang.Statement) -> Statements: if isinstance(inp, ourlang.StatementReturn): yield from statement_return(inp) return + if isinstance(inp, ourlang.StatementIf): + yield from statement_if(inp) + return + raise NotImplementedError(statement, inp) def function_argument(inp: Tuple[str, ourlang.OurType]) -> wasm.Param: diff --git a/py2wasm/ourlang.py b/py2wasm/ourlang.py index b471514..16661c8 100644 --- a/py2wasm/ourlang.py +++ b/py2wasm/ourlang.py @@ -708,7 +708,7 @@ class OurVisitor: self.visit_Module_FunctionDef_stmt(module, function, our_locals, stmt) ) - for stmt in node.body: + for stmt in node.orelse: result.else_statements.append( self.visit_Module_FunctionDef_stmt(module, function, our_locals, stmt) ) diff --git a/tests/integration/test_simple.py b/tests/integration/test_simple.py index c1af722..f54a715 100644 --- a/tests/integration/test_simple.py +++ b/tests/integration/test_simple.py @@ -150,24 +150,22 @@ def testEntry() -> i32: assert [] == result.log_int32_list @pytest.mark.integration_test -def test_if_simple(): +@pytest.mark.parametrize('inp', [9, 10, 11, 12]) +def test_if_simple(inp): code_py = """ @exported def testEntry(a: i32) -> i32: if a > 10: - return 1 + return 15 - return 0 + return 3 """ + exp_result = 15 if inp > 10 else 3 suite = Suite(code_py, 'test_return') - result = suite.run_code(10) - assert 0 == result.returned_value - assert [] == result.log_int32_list - - result = suite.run_code(11) - assert 1 == result.returned_value + result = suite.run_code(inp) + assert exp_result == result.returned_value @pytest.mark.integration_test @pytest.mark.skip('Such a return is not how things should be')