ca07d358fb
README now documents all 70+ implemented words, working examples, architecture overview, and accurate compliance status. CLAUDE.md updated with actual file descriptions, patterns for adding new words, and current test count.
2.6 KiB
2.6 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 70+ words and JIT compilation.
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/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 185 tests) - 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
- Never break existing tests
- No Co-Authored-By or AI attribution in commits