purescript-rs is a learning compiler that compiles a growing subset of
PureScript to portable WebAssembly and runs it on a WASI 0.2 runtime. It is
built as a sequence of small, testable stages and is not a replacement for the
official PureScript compiler.
The compiler currently:
- inspects source through every frontend stage:
lex,layout,parse,ast,hir,check,check-program, andcheck-program-kinds; - lowers the supported subset through Typed Core, closure-converted CC IR, and a MIR/CFG to a validated WASI 0.2 Component Model artifact, and prints the corresponding WAT;
- exports
wasi:cli/run@0.2.12, somain's result becomes the process exit code throughwasi:cli/exit;loganderrorwrite towasi:cli/stdoutandwasi:cli/stderr, andnowreads the monotonic clock.
The supported subset includes linked source modules, direct and higher-order
functions with scalar-capturing closures, Int/Boolean/Number/Char/
String/Unit, arithmetic and comparisons, scalar let, if, case,
nullary and field data types, newtypes, closed concrete records and record
updates, concrete scalar arrays, parameterized ADTs with the erased
representation, and the console, clock, and random WASI capabilities.
Still open:
- type classes and dictionary passing, open rows, and generic aggregates;
- the complete scalar and numeric operation set (scalars);
- broader aggregate coverage for the target-neutral variant representation and the canonical ABI boundary (CC IR, linear ABI boundary);
- the broader canonical ABI and ownership rules (canonical ABI).
General PureScript compatibility and the official runtime suite remain future work.
# Frontend inspection
cargo run -- lex examples/basic.purs
cargo run -- layout examples/basic.purs
cargo run -- parse examples/basic.purs
cargo run -- ast examples/basic.purs
cargo run -- hir examples/resolved.purs
cargo run -- check examples/basic.purs
cargo run -- check-program-kinds examples/basic.purs
cargo run -- dump mir examples/basic.purs
# Build, print, and run
cargo run -- build examples/basic.purs -o /tmp/basic.wasm
wasmtime run /tmp/basic.wasm; echo $? # prints 42
cargo run -- wat examples/basic.purs -o /tmp/basic.wat
cargo run -- build examples/hello.purs -o /tmp/hello.wasm
wasmtime run /tmp/hello.wasm # prints "hello world"build <file.purs>... resolves and links every listed module with the embedded
Prelude and writes the artifact. wat <file.purs>... renders the text form.
dump <core|cc|mir> <file.purs> prints an intermediate IR for debugging.
| Crate | Responsibility |
|---|---|
psrs-span |
Source text, byte ranges, and line/column mapping. |
psrs-syntax |
Lexing, layout insertion, and parsing. |
psrs-cst |
Concrete syntax tree with source ranges. |
psrs-ast |
Normalized AST and CST-to-AST lowering. |
psrs-resolve |
Locals, same-module names, and whole-program module graphs into HIR. |
psrs-hir |
Resolved HIR nodes and stable declaration/local IDs. |
psrs-kind |
Kind inference and unification with official kind diagnostics. |
psrs-thir |
Typed expressions. |
psrs-typecheck |
Rank-1 polymorphic type inference. |
psrs-desugar |
Operator desugaring while preserving HIR. |
psrs-core |
Typed Core and its HIR lowering. |
psrs-backend |
CC IR, MIR/CFG, structured Wasm encoding, validation, and WAT. |
psrs-driver |
Wires the compiler passes together. |
psrs-cli |
Source inspection, build, wat, and dump commands. |
The architecture defines twelve major passes across six long-lived IR families; see D-01.
The artifact contract is an explicit capability profile for a pinned wasmtime
release, not every feature a runtime happens to support. The stable profile
enables Wasm GC, reference types, typed function references, and the synchronous
WASI 0.2 Component Model path; SIMD, tail calls, exceptions, threads, memory64,
and WASI 0.3 stay disabled until their lowerings and tests land. Wasm GC is the
only language heap; linear memory is reserved for the canonical ABI boundary
(DEC-09). See
DEC-05 and
capability profile.
- Feature catalog: user-facing behavior and acceptance criteria.
- Design documents: implementation and IR architecture.
- Decision records: only major, durable choices.
- Repository instructions: documentation, code, and validation rules for contributors and coding agents.
The user-facing goals are F-01 and F-02. Their implementations are specified by D-01 and wasm encoding. The backend is split across capability profile (capability profile), IR boundaries (IR boundaries and verification), canonical ABI (WIT imports and canonical ABI), erasure (generic values), scalars (scalar and numeric lowering), and linear ABI boundary (canonical ABI boundary), with the concrete GC layouts and execution-evidence matrix in data representation. The frontend design includes the PureScript type system; D-04 tracks feature coverage and official-suite progress under DEC-04.
For a guided, interactive overview of P0 through P11, use the React application
in psrs-explorer/. It labels compact teaching forms as curated
and links to CLI commands for real compiler output.
Decision records:
- DEC-01 — distinct IR boundaries
- DEC-02 — thin structured Wasm encoding
- DEC-03 — PureScript-faithful type system and effect encoding
- DEC-04 — frontend and backend feature matrices
- DEC-05 — Wasmtime feature set
- DEC-06 — runtime interface via WIT
- DEC-07 — parameterized-ADT representation
cargo fmt --all --check
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warningsThe optional upstream differential test checks the front end against the
official purs compiler on a small manifest of cases. It skips when purs or a
PureScript checkout is unavailable:
PURESCRIPT_REPO=/path/to/purescript cargo test -p psrs-driver --test upstream