Fix markdown formatting to pass dprint CI check
This commit is contained in:
+40
-1
@@ -7,14 +7,18 @@ Optimal sequence for learning the entire system. Each step builds on the previou
|
|||||||
## Phase 1: Mental Model Foundation
|
## Phase 1: Mental Model Foundation
|
||||||
|
|
||||||
### 1. `crates/core/src/memory.rs` (148 lines)
|
### 1. `crates/core/src/memory.rs` (148 lines)
|
||||||
|
|
||||||
**Read first.** Defines the physical memory map — every address, every region. You'll reference these constants everywhere else.
|
**Read first.** Defines the physical memory map — every address, every region. You'll reference these constants everywhere else.
|
||||||
|
|
||||||
- Key insight: stacks grow DOWN, dictionary grows UP
|
- Key insight: stacks grow DOWN, dictionary grows UP
|
||||||
- Memorize: DATA_STACK_TOP=0x1600, DICTIONARY_BASE=0x2D40
|
- Memorize: DATA_STACK_TOP=0x1600, DICTIONARY_BASE=0x2D40
|
||||||
- System variables at offset 0: STATE, BASE, >IN, HERE, LATEST, SOURCE-ID, #TIB, HLD, LEAVE-FLAG
|
- System variables at offset 0: STATE, BASE, >IN, HERE, LATEST, SOURCE-ID, #TIB, HLD, LEAVE-FLAG
|
||||||
- Notice how regions are laid out to never overlap (verified by compile-time assertions)
|
- Notice how regions are laid out to never overlap (verified by compile-time assertions)
|
||||||
|
|
||||||
### 2. `crates/core/src/ir.rs` (259 lines)
|
### 2. `crates/core/src/ir.rs` (259 lines)
|
||||||
|
|
||||||
**The central data structure.** Every Forth word compiles to `Vec<IrOp>`. This is the language the optimizer speaks and the codegen consumes.
|
**The central data structure.** Every Forth word compiles to `Vec<IrOp>`. This is the language the optimizer speaks and the codegen consumes.
|
||||||
|
|
||||||
- ~70 variants across 10 categories
|
- ~70 variants across 10 categories
|
||||||
- Pay attention to control-flow variants: `If`, `DoLoop`, `BeginUntil`, `BeginWhileRepeat`, `BeginDoubleWhileRepeat` — they contain nested `Vec<IrOp>` bodies (tree structure, not flat)
|
- Pay attention to control-flow variants: `If`, `DoLoop`, `BeginUntil`, `BeginWhileRepeat`, `BeginDoubleWhileRepeat` — they contain nested `Vec<IrOp>` bodies (tree structure, not flat)
|
||||||
- `Call(WordId)` and `TailCall(WordId)` — how words reference each other
|
- `Call(WordId)` and `TailCall(WordId)` — how words reference each other
|
||||||
@@ -22,9 +26,11 @@ Optimal sequence for learning the entire system. Each step builds on the previou
|
|||||||
- `IrWord` struct: name + body + is_immediate
|
- `IrWord` struct: name + body + is_immediate
|
||||||
|
|
||||||
### 3. `crates/core/src/error.rs` (84 lines)
|
### 3. `crates/core/src/error.rs` (84 lines)
|
||||||
|
|
||||||
**Quick read.** 15 error variants. Note `Throw(i32)` for the Exception word set and `Abort(String)` for ABORT".
|
**Quick read.** 15 error variants. Note `Throw(i32)` for the Exception word set and `Abort(String)` for ABORT".
|
||||||
|
|
||||||
### 4. `crates/core/src/config.rs` (61 lines)
|
### 4. `crates/core/src/config.rs` (61 lines)
|
||||||
|
|
||||||
**Quick read.** 7 optimization flags in two tiers: OptConfig (IR-level) and CodegenOpts (codegen-level). Default = all enabled.
|
**Quick read.** 7 optimization flags in two tiers: OptConfig (IR-level) and CodegenOpts (codegen-level). Default = all enabled.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -32,7 +38,9 @@ Optimal sequence for learning the entire system. Each step builds on the previou
|
|||||||
## Phase 2: Data Structures
|
## Phase 2: Data Structures
|
||||||
|
|
||||||
### 5. `crates/core/src/dictionary.rs` (906 lines)
|
### 5. `crates/core/src/dictionary.rs` (906 lines)
|
||||||
|
|
||||||
**How words live in memory.** The dictionary is a linked list stored in a `Vec<u8>` that simulates WASM linear memory.
|
**How words live in memory.** The dictionary is a linked list stored in a `Vec<u8>` that simulates WASM linear memory.
|
||||||
|
|
||||||
- Entry format: link(4) + flags(1) + name(N) + padding + code_field(4)
|
- Entry format: link(4) + flags(1) + name(N) + padding + code_field(4)
|
||||||
- Flags byte: IMMEDIATE=0x80, HIDDEN=0x40, LENGTH_MASK=0x1F
|
- Flags byte: IMMEDIATE=0x80, HIDDEN=0x40, LENGTH_MASK=0x1F
|
||||||
- `create()` writes the entry, starts HIDDEN; `reveal()` removes HIDDEN flag
|
- `create()` writes the entry, starts HIDDEN; `reveal()` removes HIDDEN flag
|
||||||
@@ -46,7 +54,9 @@ Optimal sequence for learning the entire system. Each step builds on the previou
|
|||||||
## Phase 3: The Pipeline
|
## Phase 3: The Pipeline
|
||||||
|
|
||||||
### 6. `crates/core/src/optimizer.rs` (1013 lines)
|
### 6. `crates/core/src/optimizer.rs` (1013 lines)
|
||||||
|
|
||||||
**IR transformations.** Read the `optimize()` function first to see the pass ordering, then each pass.
|
**IR transformations.** Read the `optimize()` function first to see the pass ordering, then each pass.
|
||||||
|
|
||||||
- `peephole()`: pattern-match adjacent ops. ~15 patterns. Runs to fixpoint. Study each match arm.
|
- `peephole()`: pattern-match adjacent ops. ~15 patterns. Runs to fixpoint. Study each match arm.
|
||||||
- `constant_fold()`: evaluate PushI32+PushI32+BinaryOp at compile time. Also unary and float.
|
- `constant_fold()`: evaluate PushI32+PushI32+BinaryOp at compile time. Also unary and float.
|
||||||
- `strength_reduce()`: multiply by power-of-2 → shift. 0 compare → ZeroEq/ZeroLt.
|
- `strength_reduce()`: multiply by power-of-2 → shift. 0 compare → ZeroEq/ZeroLt.
|
||||||
@@ -56,7 +66,9 @@ Optimal sequence for learning the entire system. Each step builds on the previou
|
|||||||
- Key: `apply_to_bodies()` — every pass recurses into control-flow nested bodies.
|
- Key: `apply_to_bodies()` — every pass recurses into control-flow nested bodies.
|
||||||
|
|
||||||
### 7. `crates/core/src/codegen.rs` (4205 lines) — **The Big One**
|
### 7. `crates/core/src/codegen.rs` (4205 lines) — **The Big One**
|
||||||
|
|
||||||
**IR → WASM translation.** Read in order:
|
**IR → WASM translation.** Read in order:
|
||||||
|
|
||||||
1. **Constants** (lines 1-80): import indices, type indices, DSP/RSP/FSP globals, memory alignment
|
1. **Constants** (lines 1-80): import indices, type indices, DSP/RSP/FSP globals, memory alignment
|
||||||
2. **Helper functions** (lines 80-210): `dsp_dec/inc`, `push_via_local`, `pop`, `peek`, `dsp_writeback/reload`, `rpush_via_local`, `rpop`
|
2. **Helper functions** (lines 80-210): `dsp_dec/inc`, `push_via_local`, `pop`, `peek`, `dsp_writeback/reload`, `rpush_via_local`, `rpop`
|
||||||
3. **Float helpers** (lines 225-330): `fsp_dec/inc`, `fpush_via_local`, `fpop`, `fpeek`, `emit_float_binary/unary/cmp`
|
3. **Float helpers** (lines 225-330): `fsp_dec/inc`, `fpush_via_local`, `fpop`, `fpeek`, `emit_float_binary/unary/cmp`
|
||||||
@@ -66,6 +78,7 @@ Optimal sequence for learning the entire system. Each step builds on the previou
|
|||||||
7. **Stack-to-local promotion**: analysis pass that replaces memory stack operations with WASM locals
|
7. **Stack-to-local promotion**: analysis pass that replaces memory stack operations with WASM locals
|
||||||
|
|
||||||
Key patterns to understand:
|
Key patterns to understand:
|
||||||
|
|
||||||
- DSP cached in local 0: read from global at function entry, write back before calls and at exit
|
- DSP cached in local 0: read from global at function entry, write back before calls and at exit
|
||||||
- Scratch locals at SCRATCH_BASE(1): used as temporaries for stack manipulation
|
- Scratch locals at SCRATCH_BASE(1): used as temporaries for stack manipulation
|
||||||
- `EmitCtx`: carries f64 locals, Forth local base, loop local base, self_word_id for recursion
|
- `EmitCtx`: carries f64 locals, Forth local base, loop local base, self_word_id for recursion
|
||||||
@@ -76,21 +89,27 @@ Key patterns to understand:
|
|||||||
## Phase 4: The Runtime Abstraction
|
## Phase 4: The Runtime Abstraction
|
||||||
|
|
||||||
### 8. `crates/core/src/runtime.rs` (152 lines)
|
### 8. `crates/core/src/runtime.rs` (152 lines)
|
||||||
|
|
||||||
**NEW: Read this before outer.rs.** Defines two traits:
|
**NEW: Read this before outer.rs.** Defines two traits:
|
||||||
|
|
||||||
- `Runtime` — abstraction over WASM execution backend (memory, globals, table, module instantiation, host function registration)
|
- `Runtime` — abstraction over WASM execution backend (memory, globals, table, module instantiation, host function registration)
|
||||||
- `HostAccess` — memory/global ops available to host function callbacks
|
- `HostAccess` — memory/global ops available to host function callbacks
|
||||||
- `HostFn = Box<dyn Fn(&mut dyn HostAccess) -> Result<()>>` — runtime-agnostic host function type
|
- `HostFn = Box<dyn Fn(&mut dyn HostAccess) -> Result<()>>` — runtime-agnostic host function type
|
||||||
- Key insight: ForthVM is now `ForthVM<R: Runtime>`, completely decoupled from wasmtime
|
- Key insight: ForthVM is now `ForthVM<R: Runtime>`, completely decoupled from wasmtime
|
||||||
|
|
||||||
### 8b. `crates/core/src/runtime_native.rs` (328 lines)
|
### 8b. `crates/core/src/runtime_native.rs` (328 lines)
|
||||||
|
|
||||||
**NativeRuntime**: wasmtime implementation of Runtime trait.
|
**NativeRuntime**: wasmtime implementation of Runtime trait.
|
||||||
|
|
||||||
- `CallerHostAccess` wraps wasmtime `Caller` to implement `HostAccess`
|
- `CallerHostAccess` wraps wasmtime `Caller` to implement `HostAccess`
|
||||||
- `NativeRuntime` owns Engine, Store, Memory, Table, Globals
|
- `NativeRuntime` owns Engine, Store, Memory, Table, Globals
|
||||||
- `register_host_func`: creates a wasmtime `Func` that bridges `HostFn` → wasmtime callback
|
- `register_host_func`: creates a wasmtime `Func` that bridges `HostFn` → wasmtime callback
|
||||||
- Study how `instantiate_and_install` provides the 6 imports
|
- Study how `instantiate_and_install` provides the 6 imports
|
||||||
|
|
||||||
### 9. `crates/core/src/outer.rs` — ForthVM struct (lines 1-240)
|
### 9. `crates/core/src/outer.rs` — ForthVM struct (lines 1-240)
|
||||||
|
|
||||||
**Read the struct definition carefully.** ~35 fields. Group them mentally:
|
**Read the struct definition carefully.** ~35 fields. Group them mentally:
|
||||||
|
|
||||||
- Runtime: `rt: R` (generic over Runtime trait — no more direct wasmtime fields)
|
- Runtime: `rt: R` (generic over Runtime trait — no more direct wasmtime fields)
|
||||||
- Compilation state: state, compiling_name, compiling_ir, control_stack, compiling_word_id, compiling_locals
|
- Compilation state: state, compiling_name, compiling_ir, control_stack, compiling_word_id, compiling_locals
|
||||||
- Output: output (Arc<Mutex<String>>)
|
- Output: output (Arc<Mutex<String>>)
|
||||||
@@ -102,7 +121,9 @@ Key patterns to understand:
|
|||||||
- Advanced: marker_states, conditional_skip_depth, next_block_label, substitutions, search_order, next_wid
|
- Advanced: marker_states, conditional_skip_depth, next_block_label, substitutions, search_order, next_wid
|
||||||
|
|
||||||
### 10. `crates/core/src/outer.rs` — new() and primitive registration
|
### 10. `crates/core/src/outer.rs` — new() and primitive registration
|
||||||
|
|
||||||
**How the VM boots.** Read:
|
**How the VM boots.** Read:
|
||||||
|
|
||||||
- `new_with_config()`: creates `R::new()` runtime, then calls `register_primitives()` and loads boot.fth
|
- `new_with_config()`: creates `R::new()` runtime, then calls `register_primitives()` and loads boot.fth
|
||||||
- `register_primitive()`: creates dictionary entry → optimizes IR → compiles to WASM → `rt.instantiate_and_install()`
|
- `register_primitive()`: creates dictionary entry → optimizes IR → compiles to WASM → `rt.instantiate_and_install()`
|
||||||
- `register_host_primitive()`: creates dictionary entry → `rt.register_host_func()` with HostFn closure
|
- `register_host_primitive()`: creates dictionary entry → `rt.register_host_func()` with HostFn closure
|
||||||
@@ -110,7 +131,9 @@ Key patterns to understand:
|
|||||||
- Each host function: study 5-10 representative ones to understand the pattern
|
- Each host function: study 5-10 representative ones to understand the pattern
|
||||||
|
|
||||||
### 11. `crates/core/src/outer.rs` — Outer interpreter loop
|
### 11. `crates/core/src/outer.rs` — Outer interpreter loop
|
||||||
|
|
||||||
**The main loop.** Read:
|
**The main loop.** Read:
|
||||||
|
|
||||||
- `evaluate()`: sets up input buffer, calls `interpret_token()` in a loop
|
- `evaluate()`: sets up input buffer, calls `interpret_token()` in a loop
|
||||||
- `interpret_token()`: conditional compilation, `:` handling, `]` handling, dispatch to compile/interpret mode
|
- `interpret_token()`: conditional compilation, `:` handling, `]` handling, dispatch to compile/interpret mode
|
||||||
- `interpret_token_immediate()`: string literals, dictionary lookup, execute found word, parse number
|
- `interpret_token_immediate()`: string literals, dictionary lookup, execute found word, parse number
|
||||||
@@ -118,7 +141,9 @@ Key patterns to understand:
|
|||||||
- `finish_colon_def()`: optimize → codegen → install
|
- `finish_colon_def()`: optimize → codegen → install
|
||||||
|
|
||||||
### 12. `crates/core/src/outer.rs` — Control flow compilation
|
### 12. `crates/core/src/outer.rs` — Control flow compilation
|
||||||
|
|
||||||
**Most complex part.** 13 `ControlEntry` variants. Understand:
|
**Most complex part.** 13 `ControlEntry` variants. Understand:
|
||||||
|
|
||||||
- `ControlEntry::If { then_body }` → pushed when IF seen, then_body accumulates until ELSE or THEN
|
- `ControlEntry::If { then_body }` → pushed when IF seen, then_body accumulates until ELSE or THEN
|
||||||
- `ControlEntry::Do { body }` → pushed by DO, body accumulates until LOOP/+LOOP
|
- `ControlEntry::Do { body }` → pushed by DO, body accumulates until LOOP/+LOOP
|
||||||
- `ControlEntry::Begin { body }` → pushed by BEGIN, resolved by UNTIL/AGAIN/WHILE
|
- `ControlEntry::Begin { body }` → pushed by BEGIN, resolved by UNTIL/AGAIN/WHILE
|
||||||
@@ -133,10 +158,12 @@ Key patterns to understand:
|
|||||||
## Phase 5: Self-Hosting
|
## Phase 5: Self-Hosting
|
||||||
|
|
||||||
### 13. `crates/core/boot.fth` (307 lines)
|
### 13. `crates/core/boot.fth` (307 lines)
|
||||||
|
|
||||||
**Forth replaces Rust.** 7 phases of definitions that replace host functions with compiled Forth.
|
**Forth replaces Rust.** 7 phases of definitions that replace host functions with compiled Forth.
|
||||||
|
|
||||||
- Phase 1: Stack/memory (DEPTH, PICK, 2OVER, FILL, MOVE, /STRING, -TRAILING)
|
- Phase 1: Stack/memory (DEPTH, PICK, 2OVER, FILL, MOVE, /STRING, -TRAILING)
|
||||||
- Phase 2: Double-cell arithmetic (D+, DNEGATE, D-, DABS, D0=, D0<, D=, D<, DU<)
|
- Phase 2: Double-cell arithmetic (D+, DNEGATE, D-, DABS, D0=, D0<, D=, D<, DU<)
|
||||||
- Phase 3: Mixed arithmetic (SM/REM, FM/MOD, */, */MOD) — built on M* and UM/MOD host primitives
|
- Phase 3: Mixed arithmetic (SM/REM, FM/MOD, */, _/MOD) — built on M_ and UM/MOD host primitives
|
||||||
- Phase 4: HERE, ALLOT, comma, C-comma, ALIGN — magic numbers for sysvar offsets
|
- Phase 4: HERE, ALLOT, comma, C-comma, ALIGN — magic numbers for sysvar offsets
|
||||||
- Phase 5: I/O and pictured numeric output (TYPE, SPACES, <# HOLD # #S #> . U. .R U.R D. D.R)
|
- Phase 5: I/O and pictured numeric output (TYPE, SPACES, <# HOLD # #S #> . U. .R U.R D. D.R)
|
||||||
- Phase 6: DEFER support (DEFER!, DEFER@)
|
- Phase 6: DEFER support (DEFER!, DEFER@)
|
||||||
@@ -148,31 +175,40 @@ Key patterns to understand:
|
|||||||
## Phase 6: Production Features
|
## Phase 6: Production Features
|
||||||
|
|
||||||
### 14. `crates/core/src/consolidate.rs` (169 lines)
|
### 14. `crates/core/src/consolidate.rs` (169 lines)
|
||||||
|
|
||||||
**Quick read.** Mostly tests. Real logic is in `codegen::compile_consolidated_module()` and `outer::ForthVM::consolidate()`. Understand the concept: merge all JIT modules into one, replacing call_indirect with direct call.
|
**Quick read.** Mostly tests. Real logic is in `codegen::compile_consolidated_module()` and `outer::ForthVM::consolidate()`. Understand the concept: merge all JIT modules into one, replacing call_indirect with direct call.
|
||||||
|
|
||||||
### 15. `crates/core/src/export.rs` (409 lines)
|
### 15. `crates/core/src/export.rs` (409 lines)
|
||||||
|
|
||||||
**wafer build pipeline.** Entry point resolution (--entry > MAIN > top-level), IR collection, memory snapshot, metadata embedding in custom section.
|
**wafer build pipeline.** Entry point resolution (--entry > MAIN > top-level), IR collection, memory snapshot, metadata embedding in custom section.
|
||||||
|
|
||||||
### 16. `crates/core/src/runner.rs` (402 lines)
|
### 16. `crates/core/src/runner.rs` (402 lines)
|
||||||
|
|
||||||
**Standalone execution.** Creates the 6 imports from scratch, registers host function stubs for known words (., TYPE, SPACES, .S, M*, UM*, UM/MOD, DEPTH). Shows the minimal set needed to run exported modules.
|
**Standalone execution.** Creates the 6 imports from scratch, registers host function stubs for known words (., TYPE, SPACES, .S, M*, UM*, UM/MOD, DEPTH). Shows the minimal set needed to run exported modules.
|
||||||
|
|
||||||
### 17. `crates/cli/src/main.rs` (354 lines)
|
### 17. `crates/cli/src/main.rs` (354 lines)
|
||||||
|
|
||||||
**CLI ties it together.** Three modes: REPL (rustyline), file evaluation, subcommands (build, run). Native executable trick: append AOT payload + "WAFEREXE" trailer to binary.
|
**CLI ties it together.** Three modes: REPL (rustyline), file evaluation, subcommands (build, run). Native executable trick: append AOT payload + "WAFEREXE" trailer to binary.
|
||||||
|
|
||||||
### 18. `crates/web/src/lib.rs` (56 lines)
|
### 18. `crates/web/src/lib.rs` (56 lines)
|
||||||
|
|
||||||
**Browser entry point.** `WaferRepl` struct with `#[wasm_bindgen]`:
|
**Browser entry point.** `WaferRepl` struct with `#[wasm_bindgen]`:
|
||||||
|
|
||||||
- `new()` → `ForthVM::<WebRuntime>::new()`
|
- `new()` → `ForthVM::<WebRuntime>::new()`
|
||||||
- `evaluate(input)` → returns output string
|
- `evaluate(input)` → returns output string
|
||||||
- `data_stack()`, `is_compiling()`, `reset()`
|
- `data_stack()`, `is_compiling()`, `reset()`
|
||||||
|
|
||||||
### 19. `crates/web/src/runtime_web.rs` (542 lines)
|
### 19. `crates/web/src/runtime_web.rs` (542 lines)
|
||||||
|
|
||||||
**WebRuntime**: browser implementation of Runtime trait.
|
**WebRuntime**: browser implementation of Runtime trait.
|
||||||
|
|
||||||
- Uses `js_sys::WebAssembly` for module instantiation
|
- Uses `js_sys::WebAssembly` for module instantiation
|
||||||
- `WebHostAccess`: implements HostAccess via `js_sys` typed arrays
|
- `WebHostAccess`: implements HostAccess via `js_sys` typed arrays
|
||||||
- Memory access through `Int32Array`/`Uint8Array` views on `WebAssembly.Memory.buffer`
|
- Memory access through `Int32Array`/`Uint8Array` views on `WebAssembly.Memory.buffer`
|
||||||
- Closures kept alive via `_closures: Vec<JsValue>` to prevent GC
|
- Closures kept alive via `_closures: Vec<JsValue>` to prevent GC
|
||||||
|
|
||||||
### 20. `crates/web/www/` (727 lines)
|
### 20. `crates/web/www/` (727 lines)
|
||||||
|
|
||||||
**Frontend**: app.js (terminal emulation, stack display), index.html, style.css.
|
**Frontend**: app.js (terminal emulation, stack display), index.html, style.css.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -180,10 +216,13 @@ Key patterns to understand:
|
|||||||
## Phase 7: Testing
|
## Phase 7: Testing
|
||||||
|
|
||||||
### 21. Unit tests (embedded in each source file)
|
### 21. Unit tests (embedded in each source file)
|
||||||
|
|
||||||
Re-read each file's `#[cfg(test)] mod tests`. They document edge cases and expected behavior.
|
Re-read each file's `#[cfg(test)] mod tests`. They document edge cases and expected behavior.
|
||||||
|
|
||||||
### 22. `crates/core/tests/compliance.rs`
|
### 22. `crates/core/tests/compliance.rs`
|
||||||
|
|
||||||
Forth 2012 compliance infrastructure: boot_with_prerequisites, run_suite, 11 word set tests.
|
Forth 2012 compliance infrastructure: boot_with_prerequisites, run_suite, 11 word set tests.
|
||||||
|
|
||||||
### 23. `crates/core/tests/comparison.rs`
|
### 23. `crates/core/tests/comparison.rs`
|
||||||
|
|
||||||
Cross-engine benchmarks vs gforth. Performance validation.
|
Cross-engine benchmarks vs gforth. Performance validation.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# WAFER Trace-the-Compilation Exercises
|
# WAFER Trace-the-Compilation Exercises
|
||||||
|
|
||||||
For each exercise, manually trace the Forth code through the full pipeline:
|
For each exercise, manually trace the Forth code through the full pipeline:
|
||||||
|
|
||||||
1. **Outer interpreter** — tokenization, dictionary lookup, compile/interpret dispatch
|
1. **Outer interpreter** — tokenization, dictionary lookup, compile/interpret dispatch
|
||||||
2. **IR generation** — what Vec<IrOp> is produced
|
2. **IR generation** — what Vec<IrOp> is produced
|
||||||
3. **Optimization** — which passes fire, what changes
|
3. **Optimization** — which passes fire, what changes
|
||||||
@@ -12,6 +13,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 1: Simple Arithmetic
|
## Exercise 1: Simple Arithmetic
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: SQUARE DUP * ;
|
: SQUARE DUP * ;
|
||||||
```
|
```
|
||||||
@@ -39,6 +41,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 2: Constant Folding
|
## Exercise 2: Constant Folding
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: TEN 5 5 + ;
|
: TEN 5 5 + ;
|
||||||
```
|
```
|
||||||
@@ -62,6 +65,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 3: Peephole Elimination
|
## Exercise 3: Peephole Elimination
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: NOOP DUP DROP ;
|
: NOOP DUP DROP ;
|
||||||
```
|
```
|
||||||
@@ -80,6 +84,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 4: Strength Reduction
|
## Exercise 4: Strength Reduction
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: DOUBLE 8 * ;
|
: DOUBLE 8 * ;
|
||||||
```
|
```
|
||||||
@@ -99,9 +104,11 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 5: Tail Call Detection
|
## Exercise 5: Tail Call Detection
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: FOO 1 + BAR ;
|
: FOO 1 + BAR ;
|
||||||
```
|
```
|
||||||
|
|
||||||
(Assume BAR is a previously defined word)
|
(Assume BAR is a previously defined word)
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -119,6 +126,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 6: Control Flow — IF/THEN
|
## Exercise 6: Control Flow — IF/THEN
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: ABS DUP 0< IF NEGATE THEN ;
|
: ABS DUP 0< IF NEGATE THEN ;
|
||||||
```
|
```
|
||||||
@@ -142,6 +150,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 7: DO LOOP
|
## Exercise 7: DO LOOP
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: STARS 0 DO 42 EMIT LOOP ;
|
: STARS 0 DO 42 EMIT LOOP ;
|
||||||
```
|
```
|
||||||
@@ -165,6 +174,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 8: BEGIN UNTIL
|
## Exercise 8: BEGIN UNTIL
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: COUNTDOWN BEGIN DUP . 1 - DUP 0= UNTIL DROP ;
|
: COUNTDOWN BEGIN DUP . 1 - DUP 0= UNTIL DROP ;
|
||||||
```
|
```
|
||||||
@@ -185,6 +195,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 9: Dead Code Elimination
|
## Exercise 9: Dead Code Elimination
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: ALWAYS-TRUE TRUE IF 42 ELSE 99 THEN ;
|
: ALWAYS-TRUE TRUE IF 42 ELSE 99 THEN ;
|
||||||
```
|
```
|
||||||
@@ -203,6 +214,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 10: Swap Peephole Patterns
|
## Exercise 10: Swap Peephole Patterns
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: TEST SWAP SWAP DROP DROP ;
|
: TEST SWAP SWAP DROP DROP ;
|
||||||
```
|
```
|
||||||
@@ -221,6 +233,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 11: Nested Control Flow
|
## Exercise 11: Nested Control Flow
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: CLASSIFY DUP 0< IF DROP -1 ELSE 0> IF 1 ELSE 0 THEN THEN ;
|
: CLASSIFY DUP 0< IF DROP -1 ELSE 0> IF 1 ELSE 0 THEN THEN ;
|
||||||
```
|
```
|
||||||
@@ -229,6 +242,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
<summary>Answer</summary>
|
<summary>Answer</summary>
|
||||||
|
|
||||||
1. IR structure (after inlining):
|
1. IR structure (after inlining):
|
||||||
|
|
||||||
```
|
```
|
||||||
[Dup, ZeroLt, If {
|
[Dup, ZeroLt, If {
|
||||||
then: [Drop, PushI32(-1)],
|
then: [Drop, PushI32(-1)],
|
||||||
@@ -238,6 +252,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
}])
|
}])
|
||||||
}]
|
}]
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Optimizer recurses into both If bodies. No constant conditions → no DCE.
|
2. Optimizer recurses into both If bodies. No constant conditions → no DCE.
|
||||||
3. Codegen: nested WASM `if/else/end` blocks.
|
3. Codegen: nested WASM `if/else/end` blocks.
|
||||||
|
|
||||||
@@ -246,6 +261,7 @@ Answers are below each exercise (scroll down or cover with paper).
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 12: DOES> Defining Word
|
## Exercise 12: DOES> Defining Word
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: CONSTANT CREATE , DOES> @ ;
|
: CONSTANT CREATE , DOES> @ ;
|
||||||
5 CONSTANT FIVE
|
5 CONSTANT FIVE
|
||||||
@@ -277,6 +293,7 @@ FIVE .
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 13: Consolidation
|
## Exercise 13: Consolidation
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: A 1 ;
|
: A 1 ;
|
||||||
: B 2 ;
|
: B 2 ;
|
||||||
@@ -301,6 +318,7 @@ CONSOLIDATE
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 14: Host Function Execution
|
## Exercise 14: Host Function Execution
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
5 3 M*
|
5 3 M*
|
||||||
```
|
```
|
||||||
@@ -326,6 +344,7 @@ CONSOLIDATE
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 15: Float Operations
|
## Exercise 15: Float Operations
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: HYPOTENUSE FDUP F* FSWAP FDUP F* F+ FSQRT ;
|
: HYPOTENUSE FDUP F* FSWAP FDUP F* F+ FSQRT ;
|
||||||
```
|
```
|
||||||
@@ -346,6 +365,7 @@ CONSOLIDATE
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 16: BEGIN WHILE REPEAT
|
## Exercise 16: BEGIN WHILE REPEAT
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: COUNTDOWN BEGIN DUP WHILE DUP . 1 - REPEAT DROP ;
|
: COUNTDOWN BEGIN DUP WHILE DUP . 1 - REPEAT DROP ;
|
||||||
```
|
```
|
||||||
@@ -365,6 +385,7 @@ CONSOLIDATE
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 17: Batch Mode Compilation
|
## Exercise 17: Batch Mode Compilation
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
( During ForthVM::new() )
|
( During ForthVM::new() )
|
||||||
```
|
```
|
||||||
@@ -389,10 +410,12 @@ CONSOLIDATE
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 18: wafer build Pipeline
|
## Exercise 18: wafer build Pipeline
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
( file: hello.fth )
|
( file: hello.fth )
|
||||||
: MAIN ." Hello, World!" CR ;
|
: MAIN ." Hello, World!" CR ;
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wafer build hello.fth -o hello.wasm
|
wafer build hello.fth -o hello.wasm
|
||||||
```
|
```
|
||||||
@@ -417,6 +440,7 @@ wafer build hello.fth -o hello.wasm
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 19: Stack-to-Local Promotion
|
## Exercise 19: Stack-to-Local Promotion
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
: ADD3 + + ;
|
: ADD3 + + ;
|
||||||
```
|
```
|
||||||
@@ -437,6 +461,7 @@ wafer build hello.fth -o hello.wasm
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Exercise 20: MARKER and State Restore
|
## Exercise 20: MARKER and State Restore
|
||||||
|
|
||||||
```forth
|
```forth
|
||||||
MARKER CLEAN
|
MARKER CLEAN
|
||||||
: FOO 1 ;
|
: FOO 1 ;
|
||||||
|
|||||||
Reference in New Issue
Block a user