Stumbled upon the Overengineered calculator: Zig + QBE blog article when browsing reddit and thought it would be cool to run the snippets in the browser.
qbe-wasm does not have wasi support, so this demo uses a quick and dirty printf. Please remember, this is just a demo...
# ld means: as long integer
data $fmt = { b "%ld\n", b 0 }
export function w $main() {
@start
%.0 =l mul 2, 2
%.1 =l add 2, %.0
# call C printf function, needs linking with libc, to print the result
call $printf(l $fmt, ..., l %.1)
ret 0
}
qbe-wasm -o snippet1.wasm snippet1.qbe
2 + 2 * 2 =
qbe-wasm -t wat -o snippet1.wat snippet1.qbe
(module
(type $0 (func (result i32)))
(type $1 (func (param i64 i64)))
(import "env" "printf" (func $printf (param i64 i64)))
(memory $mem 1 1)
(data $fmt_0 (i32.const 0) "%ld\n")
(export "main" (func $main))
(export "mem" (memory $mem))
(func $main (result i32)
(i64.store
(i32.const 6)
(i64.const 6)
)
(call $printf
(i64.const 0)
(i64.const 6)
)
(i32.const 0)
)
)
data $fmt = { b "%ld\n", b 0 }
export function w $main() {
@start
%.0 =l neg 2
%.1 =l div 4, 2
%.2 =l mul 2, %.1
%.3 =l add %.0, %.2
call $printf(l $fmt, ..., l %.3)
ret 0
}
qbe-wasm -o snippet2.wasm snippet2.qbe
-2 + 2 * (4 / 2) =
qbe-wasm -t wat -o snippet2.wat snippet2.qbe
(module
(type $0 (func (result i32)))
(type $1 (func (param i64 i64)))
(import "env" "printf" (func $printf (param i64 i64)))
(memory $mem 1 1)
(data $fmt_0 (i32.const 0) "%ld\n")
(export "main" (func $main))
(export "mem" (memory $mem))
(func $main (result i32)
(i64.store
(i32.const 6)
(i64.const 2)
)
(call $printf
(i64.const 0)
(i64.const 6)
)
(i32.const 0)
)
)
An interesting observation of the wat for snippet2, the blog post mentions that the assembly generated did not fold the constants. They do, however, get folded when compiling to wat/wasm via qbe-wasm.
This is because qbe-wasm uses QBE+binaryen, so I take no direct credit for this, just thought it was worth mentioning.