diff --git a/Makefile b/Makefile index ad186c2..dc07094 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,9 @@ venv/.done: requirements.txt venv/bin/python3 -m pip install -r $^ touch $@ +clean-examples: + rm -f examples/*.wat examples/*.wasm examples/*.wat.html examples/*.py.html + .SECONDARY: # Keep intermediate files .PHONY: examples diff --git a/phasm/codestyle.py b/phasm/codestyle.py index f1031ad..48b9606 100644 --- a/phasm/codestyle.py +++ b/phasm/codestyle.py @@ -23,6 +23,9 @@ def type3(inp: Type3OrPlaceholder) -> str: """ assert isinstance(inp, Type3), TYPE3_ASSERTION_ERROR + if inp is type3types.none: + return 'None' + if isinstance(inp, type3types.AppliedType3): if inp.base == type3types.tuple: return '(' + ', '.join( diff --git a/phasm/compiler.py b/phasm/compiler.py index 5ba2793..a511d0e 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -40,6 +40,9 @@ def type3(inp: type3types.Type3OrPlaceholder) -> wasm.WasmType: """ assert isinstance(inp, type3types.Type3), type3types.TYPE3_ASSERTION_ERROR + if inp == type3types.none: + return wasm.WasmTypeNone() + if inp == type3types.u8: # WebAssembly has only support for 32 and 64 bits # So we need to store more memory per byte diff --git a/phasm/type3/constraintsgenerator.py b/phasm/type3/constraintsgenerator.py index 241d0ec..2093303 100644 --- a/phasm/type3/constraintsgenerator.py +++ b/phasm/type3/constraintsgenerator.py @@ -115,6 +115,8 @@ def expression(ctx: Context, inp: ourlang.Expression) -> Generator[ConstraintBas raise NotImplementedError(expression, inp) def function(ctx: Context, inp: ourlang.Function) -> Generator[ConstraintBase, None, None]: + assert not inp.imported + if isinstance(inp, ourlang.StructConstructor): return @@ -136,4 +138,7 @@ def module(ctx: Context, inp: ourlang.Module) -> Generator[ConstraintBase, None, yield from module_constant_def(ctx, cdef) for func in inp.functions.values(): + if func.imported: + continue + yield from function(ctx, func) diff --git a/tests/integration/test_lang/test_interface.py b/tests/integration/test_lang/test_interface.py index cbacd73..a8dfc32 100644 --- a/tests/integration/test_lang/test_interface.py +++ b/tests/integration/test_lang/test_interface.py @@ -1,9 +1,11 @@ import pytest +from phasm.type3.entry import Type3Exception + from ..helpers import Suite @pytest.mark.integration_test -def test_imported(): +def test_imported_ok(): code_py = """ @imported def helper(mul: i32) -> i32: @@ -25,3 +27,53 @@ def testEntry() -> i32: ) assert 8476 == result.returned_value + +@pytest.mark.integration_test +def test_imported_side_effect_no_return(): + code_py = """ +@imported +def helper(mul: u8) -> None: + pass + +@exported +def testEntry() -> None: + return helper(3) +""" + prop = None + + def helper(mul: int) -> None: + nonlocal prop + prop = mul + + result = Suite(code_py).run_code( + runtime='wasmer', + imports={ + 'helper': helper, + } + ) + + assert None is result.returned_value + assert 3 == prop + +@pytest.mark.integration_test +def test_imported_type_mismatch(): + code_py = """ +@imported +def helper(mul: u8) -> u8: + pass + +@exported +def testEntry(x: u32) -> u8: + return helper(x) +""" + + def helper(mul: int) -> int: + return 4238 * mul + + with pytest.raises(Type3Exception, match=r'u32 must be u8 instead'): + Suite(code_py).run_code( + runtime='wasmer', + imports={ + 'helper': helper, + } + )