f3bc270904
README: 392 tests, 200+ words, 12 word sets, optimization pipeline described CLAUDE.md: 200+ words, 12 word sets, 392 tests, added optimizer/config/consolidate to key files OPTIMIZATIONS.md: update all 14 section statuses (12 done, 2 not started) WAFER.md: correct line counts, add optimizer/config/consolidate/types to project layout, add FSP global
3.1 KiB
3.1 KiB
WAFER Project Conventions
What is WAFER?
WAFER (WebAssembly Forth Engine in Rust) is an optimizing Forth 2012 compiler targeting WebAssembly. Currently a working Forth system with 200+ words, JIT compilation, 12 word sets at 100% compliance, and a full optimization pipeline (peephole, constant folding, inlining, strength reduction, DCE, tail calls, stack-to-local promotion, consolidation).
Architecture
- Each Forth word compiles to its own WASM module via
wasm-encoder - Modules share memory, globals (dsp/rsp), and a function table via wasmtime imports
- IR-based compilation: Forth ->
Vec<IrOp>-> WASM codegen -> wasmtime instantiation - Dictionary: linked-list in a
Vec<u8>buffer simulating WASM linear memory - Primitives: either IR-based (compiled to WASM) or host functions (Rust closures in wasmtime)
Key Files
crates/core/src/outer.rs-- ForthVM: the main runtime, outer interpreter, compiler, all primitivescrates/core/src/codegen.rs-- IR-to-WASM translation, module generation, wasmtime execution testscrates/core/src/dictionary.rs-- Dictionary data structure with create/find/revealcrates/core/src/ir.rs-- IrOp enum (the intermediate representation)crates/core/src/memory.rs-- Memory layout constants (stack regions, dictionary base, etc.)crates/core/src/optimizer.rs-- IR optimization passes (peephole, fold, inline, DCE, etc.)crates/core/src/config.rs-- WaferConfig: unified optimization configurationcrates/core/src/consolidate.rs-- Consolidation recompiler (single-module direct calls)crates/cli/src/main.rs-- CLI REPL with rustyline
Adding a New Word
IR primitive (simple stack/arithmetic/logic -- preferred when possible):
self.register_primitive("WORD_NAME", false, vec![IrOp::Dup, IrOp::Mul])?;
Host function (needs Rust logic -- I/O, dictionary manipulation, complex stack access):
let func = Func::new(&mut self.store, func_type.clone(), move |mut caller, _params, _results| {
// manipulate memory/globals directly
Ok(())
});
self.register_host_primitive("WORD_NAME", false, func)?;
Special interpreter token (defining words like VARIABLE, CONSTANT, CREATE):
Handle in interpret_token_immediate() or compile_token() as a special case.
Code Style
cargo fmt --allandcargo clippy --workspacemust pass with no warnings- Every public function needs a doc comment
- Use
thiserrorfor error types in core crate,anyhowfor CLI - Prefer returning
Resultover panicking
Testing
- Run
cargo test --workspacebefore committing (currently 392 tests: 380 unit + 1 benchmark + 11 compliance) - Forth 2012 compliance:
cargo test -p wafer-core --test compliance - Test helper in outer.rs:
eval_output("forth code")returns printed output as String - Test helper:
eval_stack("forth code")returns data stack as Vec
Key Principles
- Correctness first, performance second
- Maximize Forth, minimize Rust (self-hosting goal -- not yet started)
- Test-driven: if it's not tested, it doesn't work
- Every word set at 100% compliance before moving to the next
- Never break existing tests