Program examples
These are small, complete Reed modules. Each page shows a feature inside a running program, because the interesting parts of Reed usually appear where declarations, control flow, and lowering meet.
How to read an example
Every page follows the same pattern:
- The module, with comments on the lines where a choice matters. Read the code first. The comments are the notes you would want from someone who already debugged it. Reed has line comments only;
/* */is a syntax error. - Why it works that way, usually tied back to a WebAssembly rule or to the lowering Reed has to produce.
- Expected result, plus links to the rules behind the example.
These pages explain behavior, but the authoritative specification is still the source of truth for grammar, type rules, feature gates, and lowering. For compact syntax lookup, use the cheatsheet. For missing pieces and rough edges, see limitations.
Each module below is editable and compiles in the browser. If a detail feels abstract, change the source and watch the emitted WAT move with it.
Running them yourself
Most examples export a zero-argument check() -> i32. A result of 0 means the program observed the expected behavior. A nonzero value points at the path that surprised it.
reedc build program.reed -o program.wat
wasmtime run --invoke check program.wat
The repository's black-box test harness uses the same convention. A module that compiles and passes wasm-tools validate is only well-formed WebAssembly. It is not proof that the program means what the Reed source says. For control flow or evaluation order, run it.
Choose a program
-
Counter and globals — mutable globals, and why identifier case decides which namespace a name resolves in.
-
Range sum and structured loops —
foras sugar over a counter, versus a labelled loop carrying state as a block parameter. -
GC narrowing —
istests, why they only narrow immutable locals, and thebr_on_castlowering. -
Mutable arrays — nominal GC array types and indexed access.
-
Raw WebAssembly operations — the
wasm.<opcode>(...)escape hatch and the opcode catalog. -
Linear memory and function tables — byte-addressed memory versus reference tables, both named explicitly.
-
WASI Preview 1 entry point — imports,
start, and process exit. -
Compile-time generated dispatch —
switcharms generated bycomptime for, lowered to onebr_table, resized with--define. -
Splitting a program across files — a
publibrary, a shared macro, and three files compiling to one module. -
Type switches and checked exceptions — an expression-tree interpreter dispatching on runtime type, with its one failure path declared in every signature that carries it.
-
Word frequency with the standard library — four
std:modules composing into one program, and what dead-code elision actually leaves behind. -
Bit-packed values — a packed struct, a C-style enum, and a derived
const, with nothing left in the emitted module. -
A generic ring buffer — one
comptime funcinstantiated for two element types, and what the module contains afterward.