mwa
A Wasm macro assembler implemented in WAT.
Reads a WAT-like S-expression source with macros, reader macros, splices, and gensyms; emits a Wasm module. The compiler itself is written in WAT and compiled to Wasm.
example
The prelude registers reader macros so &x reads as (local.get $x) and #42 as (i32.const 42). Operator atoms like +, >>u, and, @8u, ! are aliases for the matching i32.* ops and work in both prefix and postfix position. (fun NAME (sig) body) desugars to (func ...) with name type ... -> rtype in sig. User macros compose with all of it.
(module
(memory (export "memory") 1)
(const $W 64)
;; pack 0x00BBGGRR into 0xAABBGGRR with full alpha
(fun $pk ($c i32 -> i32)
&c #16 >>u
&c #0xff00 and or
&c #16 << or
#0xff000000 or)
;; saturating byte add: mem[a] = clamp(mem[a] + d, 0, 255)
(fun $b+ ($d i32 $a i32)
(local $v i32)
&a &a @8u &d + local.set $v
#255 &v &v #255 > select local.set $v
#0 &v &v #0 < select !8)
;; user macro: only call $b+ when cond is true
(macro $dist (cond addr)
`($when ,cond (call $b+ &err ,addr)))
;; fill row $y with packed color $c
(fun $row ($y i32 $c i32)
(local $x i32)
($for $x #0 #$W 1
&y #$W * &x + #2 <<
&c call $pk
!)))build
make # build dist/mwa
make test # run the test suite
make install # install to $PREFIX (default /usr/local)Then:
mwa < in.mwa > out.wasm