diff --git a/.gitignore b/.gitignore
index 50765be..7f7c00b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
-*.wasm
-*.wat
+/*.wasm
+/*.wat
+/venv
+
+__pycache__
diff --git a/Makefile b/Makefile
index 7bbb8fb..3ed270c 100644
--- a/Makefile
+++ b/Makefile
@@ -6,3 +6,11 @@
server:
python3.8 -m http.server
+
+test: venv/.done
+ venv/bin/pytest tests
+
+venv/.done: requirements.txt
+ python3.8 -m venv venv
+ venv/bin/python3 -m pip install -r $^
+ touch $@
diff --git a/compile.py b/compile.py
index 2fcaf84..f2c6119 100644
--- a/compile.py
+++ b/compile.py
@@ -138,17 +138,22 @@ class Visitor(ast.NodeVisitor):
def err(msg: str) -> None:
sys.stderr.write('{}\n'.format(msg))
-def main(source: str, sink: str) -> int:
- with open(source, 'r') as fil:
- code = fil.read()
-
- res = ast.parse(code, source)
+def process(input: str, input_name: str) -> str:
+ res = ast.parse(input, input_name)
visitor = Visitor()
visitor.visit(res)
+ return visitor.generate()
+
+def main(source: str, sink: str) -> int:
+ with open(source, 'r') as fil:
+ code_py = fil.read()
+
+ code_wat = process(code_py, source)
+
with open(sink, 'w') as fil:
- fil.write(visitor.generate())
+ fil.write(code_wat)
return 0
diff --git a/func.html b/func.html
deleted file mode 100644
index 4967ac5..0000000
--- a/func.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
- Simple add example
-
-
-
-
-
-
-
diff --git a/log.html b/log.html
deleted file mode 100644
index 8f97d5d..0000000
--- a/log.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
- Simple log example
-
-
-
-
-
-
-
diff --git a/log.py b/log.py
deleted file mode 100644
index 6985c05..0000000
--- a/log.py
+++ /dev/null
@@ -1,6 +0,0 @@
-@external('console')
-def log(msg: i32) -> None:
- ...
-
-def logIt():
- log(13 + 13 * 123)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..9e01a86
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+pywasm==1.0.7
+pytest==6.2.2
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/integration/test_fib.py b/tests/integration/test_fib.py
new file mode 100644
index 0000000..bcd4719
--- /dev/null
+++ b/tests/integration/test_fib.py
@@ -0,0 +1,85 @@
+import io
+import subprocess
+import sys
+from tempfile import NamedTemporaryFile
+
+from pywasm import binary
+from pywasm import Runtime
+
+from compile import process
+
+def wat2wasm(code_wat):
+ with NamedTemporaryFile('w+t') as input_fp:
+ input_fp.write(code_wat)
+ input_fp.flush()
+
+ with NamedTemporaryFile('w+b') as output_fp:
+ result = subprocess.run(
+ [
+ 'wat2wasm',
+ input_fp.name,
+ '-o',
+ output_fp.name,
+ ],
+ check=True,
+ )
+
+ output_fp.seek(0)
+
+ return output_fp.read()
+
+class SuiteResult:
+ def __init__(self):
+ self.log_int32_list = []
+
+ def callback_log_int32(self, store, value):
+ del store # auto passed by pywasm
+
+ self.log_int32_list.append(value)
+
+ def make_imports(self):
+ return {
+ 'console': {
+ 'logInt32': self.callback_log_int32,
+ }
+ }
+
+class Suite:
+ def __init__(self, code_py, test_name):
+ self.code_py = code_py
+ self.test_name = test_name
+
+ def run_code(self, *args):
+ """
+ Compiles the given python code into wasm and
+ then runs it
+
+ Returned is an object with the results set
+ """
+ code_wat = process(self.code_py, self.test_name)
+ sys.stderr.write(code_wat)
+
+ code_wasm = wat2wasm(code_wat)
+ module = binary.Module.from_reader(io.BytesIO(code_wasm))
+
+ result = SuiteResult()
+ runtime = Runtime(module, result.make_imports(), {})
+
+ result.returned_value = runtime.exec('testEntry', args)
+
+ return result
+
+def test_fib():
+ code_py = """
+@external('console')
+def logInt32(value: i32) -> None:
+ ...
+
+def testEntry():
+ logInt32(13 + 13 * 123)
+"""
+
+ result = Suite(code_py, 'test_fib').run_code()
+
+ assert None is result.returned_value
+ assert [1612] == result.log_int32_list