diff --git a/phasm/compiler.py b/phasm/compiler.py index a83c2cf..22593b8 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -101,6 +101,7 @@ U32_OPERATOR_MAP = { '^': 'xor', '|': 'or', '&': 'and', + '/': 'div_u' # Division by zero is a trap and the program will panic } U64_OPERATOR_MAP = { @@ -113,6 +114,7 @@ U64_OPERATOR_MAP = { '^': 'xor', '|': 'or', '&': 'and', + '/': 'div_u' # Division by zero is a trap and the program will panic } I32_OPERATOR_MAP = { @@ -120,6 +122,7 @@ I32_OPERATOR_MAP = { '>': 'gt_s', '<=': 'le_s', '>=': 'ge_s', + '/': 'div_s' # Division by zero is a trap and the program will panic } I64_OPERATOR_MAP = { @@ -127,6 +130,15 @@ I64_OPERATOR_MAP = { '>': 'gt_s', '<=': 'le_s', '>=': 'ge_s', + '/': 'div_s' # Division by zero is a trap and the program will panic +} + +F32_OPERATOR_MAP = { + '/': 'div' # Division by zero is a trap and the program will panic +} + +F64_OPERATOR_MAP = { + '/': 'div' # Division by zero is a trap and the program will panic } def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None: @@ -251,10 +263,16 @@ def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None: if operator := OPERATOR_MAP.get(inp.operator, None): wgn.add_statement(f'f32.{operator}') return + if operator := F32_OPERATOR_MAP.get(inp.operator, None): + wgn.add_statement(f'f32.{operator}') + return if mtyp == 'f64': if operator := OPERATOR_MAP.get(inp.operator, None): wgn.add_statement(f'f64.{operator}') return + if operator := F64_OPERATOR_MAP.get(inp.operator, None): + wgn.add_statement(f'f64.{operator}') + return raise NotImplementedError(expression, inp.type_var, inp.operator) diff --git a/phasm/parser.py b/phasm/parser.py index 51019be..525fbe2 100644 --- a/phasm/parser.py +++ b/phasm/parser.py @@ -351,6 +351,8 @@ class OurVisitor: operator = '-' elif isinstance(node.op, ast.Mult): operator = '*' + elif isinstance(node.op, ast.Div): + operator = '/' elif isinstance(node.op, ast.LShift): operator = '<<' elif isinstance(node.op, ast.RShift): diff --git a/phasm/typer.py b/phasm/typer.py index 56b1f05..5081dac 100644 --- a/phasm/typer.py +++ b/phasm/typer.py @@ -98,7 +98,7 @@ def expression(ctx: Context, inp: ourlang.Expression) -> 'TypeVar': return right if isinstance(inp, ourlang.BinaryOp): - if inp.operator in ('+', '-', '*', '|', '&', '^'): + if inp.operator in ('+', '-', '*', '/', '|', '&', '^'): left = expression(ctx, inp.left) right = expression(ctx, inp.right) ctx.unify(left, right) diff --git a/tests/integration/test_lang/test_primitives.py b/tests/integration/test_lang/test_primitives.py index 01df9cf..9c3aac2 100644 --- a/tests/integration/test_lang/test_primitives.py +++ b/tests/integration/test_lang/test_primitives.py @@ -226,7 +226,34 @@ def testEntry() -> {type_}: assert TYPE_MAP[type_] == type(result.returned_value) # TODO: Multiplication -# TODO: Division + +@pytest.mark.integration_test +@pytest.mark.parametrize('type_', COMPLETE_INT_TYPES) +def test_division_int(type_): + code_py = f""" +@exported +def testEntry() -> {type_}: + return 10 / 3 +""" + + result = Suite(code_py).run_code() + + assert 3 == result.returned_value + assert TYPE_MAP[type_] == type(result.returned_value) + +@pytest.mark.integration_test +@pytest.mark.parametrize('type_', ALL_FLOAT_TYPES) +def test_division_float(type_): + code_py = f""" +@exported +def testEntry() -> {type_}: + return 10.0 / 8.0 +""" + + result = Suite(code_py).run_code() + + assert 1.25 == result.returned_value + assert TYPE_MAP[type_] == type(result.returned_value) @pytest.mark.integration_test @pytest.mark.parametrize('type_', ['f32', 'f64'])