Thanks for contributing. This repo is intentionally small, stream-first, and hostile to bloat.
zasm is a two-stage toolchain:
zas— zASM (text) → JSONL IR (one record per line) on stdoutzld— JSONL IR → WAT (single module) on stdoutzrun— local runner/harness (Wasmtime host) for tests + debugging
Design rule: stage boundaries are stable. If you change the JSONL IR, you are changing the contract.
- All contributions are accepted under GPL-3.0-or-later (see
LICENSE.md). - By submitting a PR, you agree your contribution may be redistributed under that license.
- Trademarks: “zasm” and related marks are not granted under the GPL. Don’t use the project name/logo to market forks.
clang(orcc)- GNU Bison 3.x (macOS
/usr/bin/bisonis often too old) flexmake
Homebrew:
brew install bison flexThen either:
export PATH="/opt/homebrew/opt/bison/bin:/opt/homebrew/opt/flex/bin:$PATH"or build with overrides:
make BISON=/opt/homebrew/opt/bison/bin/bison FLEX=/opt/homebrew/opt/flex/bin/flexmake zas zld zrunOutputs:
bin/zasbin/zldbin/zrun
cat examples/hello.asm | bin/zas | bin/zld > build/out.wat(Optional) if you have WABT installed:
wat2wasm build/out.wat -o build/out.wasmzrun exists so we can test without depending on Lembeh being finished.
# compile
cat examples/hello.asm | bin/zas | bin/zld > build/hello.wat
# run (writes stdout bytes to a file, logs to stderr)
./bin/zrun build/hello.wat --in examples/input.txt --out build/out.txtSee Makefile for current smoke targets.
We prefer golden tests:
- input fixture → expected output bytes
- keep tests deterministic (no timestamps, no randomness)
Run:
make testIf you add a new opcode or directive, add at least:
- a tiny
.asmprogram inexamples/ - a golden test that exercises it end-to-end (
zas | zld | zrun)
When adding instructions/directives, do the minimum to keep the system consistent:
-
Parser (zas)
- update lexer/parser to accept the syntax
- emit JSONL IR records
-
Lowering (zld)
- implement semantics in
wat_emit.c - reject unsupported forms with clear errors (include line numbers)
- implement semantics in
-
Example + test
Guidelines:
- Prefer incremental additions (one opcode, one PR).
- Validate operand forms strictly.
- If an instruction has multiple legal forms, implement one first, then extend.
If you need to change the IR schema:
- Update the schema in
schema/. - Update both
zasandzldin the same PR. - Add a migration note in the PR description.
Strong preference: extend rather than break. New fields should be optional when possible.
- C is C11.
- Keep code boring and readable.
- Avoid hidden global state.
- Errors should include
tool: messageand a source line if available.
- Builds:
make zas zld zrun - Tests:
make test - Added/updated examples if behavior changes
- IR/schema updated if needed
- No gratuitous refactors (separate PRs)
If you find a security issue (especially around parsing or bounds handling), please open a private report instead of posting a public issue.
Welcome aboard.