Prior to this PR, each type would have its own handwritten test suite. The end result was that not all types were tested for all situations. This PR adds a framework based on a Markdown file, which generates the basic tests for the types defined in json files. These are auto generated and updated by the Makefile before the test suite is run. Also, a number of unsupported type combinations are now supported. Also, we now support negative literals. Also, allocation calculation fixes for nested types. Also, the test helpers can now properly import and export typed variables such as bytes, static arrays and tuples. This may come in handy when it comes to phasm platform wanting to route data. Also, adds better support for i8 type. Also, started on a runtime.py, since there's quite some code now that deals with compile time handling of WebAssembly stuff. Also, minor improvement to the type constrains, namely we better match 'tuple' literals with static array types. Also, reduced spam when printing the type analysis results; constraints that go back on the backlog are now no longer printed one by one. It now also prints the end results of the typing analysis. Also, reorganized the big test_primitives test into type classes. Also, replaced pylint with ruff.
phasm
Elevator pitch
A programming language, that looks like Python, handles like Haskell, and compiles directly to WebAssembly.
Project state
This is a hobby project for now. Use at your own risk.
How to run
You should only need make and python3. Currently, we're working with python3.10, since we're using the python ast parser, it might not work on other versions.
To run the examples:
make examples
To run the tests:
make test
To run the linting and type checking:
make lint typecheck
To compile a Phasm file:
python3.10 -m phasm source.py output.wat
Additional required tools
At the moment, the compiler outputs WebAssembly text format. To actually get a binary, you will need the wat2wasm tool[6].
Example
For more examples, see the examples directory.
def helper(n: u64, a: u64, b: u64) -> u64:
if n < 1:
return a + b
return helper(n - 1, a + b, a)
@exported
def fib(n: u64) -> u64:
if n == 0:
return 0
if n == 1:
return 1
return helper(n - 1, 0, 1)
Gotcha's
- When importing and exporting unsigned values to WebAssembly, they will become signed, as WebAssembly has no native unsigned type. You may need to cast or reinterpret them.
- Currently, Phasm files have the .py extension, which helps with syntax highlighting, that might change in the future.
Contributing
At this time, we're mostly looking for use cases for WebAssembly, other than to compile existing C code and running them in the browser. The goal of WebAssembly is to enable high-performance applications on web pages[5]. Though most people seem to use it to have existing code run in the browser.
If you have a situation where WebAssembly would be useful for it's speed, we're interested to see what you want to use it for.
Also, if you are trying out Phasm, and you're running into a limitation, we're interested in a minimal test case that shows what you want to achieve and how Phasm currently fails you.
Name origin
- p from python
- ha from Haskell
- asm from WebAssembly
References
[1] https://www.python.org/
[2] https://www.haskell.org/
[3] https://webassembly.org/
[4] https://www.w3.org/TR/wasm-core-1/
[5] https://en.wikipedia.org/w/index.php?title=WebAssembly&oldid=1103639883
[6] https://github.com/WebAssembly/wabt