docs: update plan — 230/233 (98.7%), roadmap to 100%
- Documented 3 remaining failures with root causes - Roadmap: Phase A (closure scoping), Phase B (multi-file), Phase C (symbol emit)
This commit is contained in:
@@ -8,19 +8,56 @@
|
||||
| clojure.core | 222 | 225 | 98.7% |
|
||||
| **Total** | **230** | **233** | **98.7%** |
|
||||
|
||||
## Unit Tests: 78/80 pass (97.5%)
|
||||
## Unit Tests: 78/80 (97.5%)
|
||||
|
||||
- `emit symbol` — returns `cljSymbol(...)` instead of raw name
|
||||
- `emit mangled symbol` — same issue
|
||||
| Status | Test | Issue |
|
||||
|---|---|---|
|
||||
| ✅ | 78 tests | All passing |
|
||||
| ❌ | `emit symbol` | Returns `cljSymbol("x")` instead of raw `"x"` |
|
||||
| ❌ | `emit mangled symbol` | Same — symbol emit returns data instead of name |
|
||||
|
||||
## 3 Remaining Compliance Failures
|
||||
|
||||
| # | Test | Error | Root Cause |
|
||||
|---|---|---|---|
|
||||
| 1 | `not_eq` | `undeclared 'eq_SLASH_tests'` | Cross-namespace: `eq/tests` fn from `clojure.core-test.eq` not loaded |
|
||||
| 2 | `add_watch` | `undeclared 'testvar_a'` | `(def testvar-a 0)` inside deftest body — Nim requires var decl before use in closures |
|
||||
| 3 | `remove_watch` | `undeclared 'watchable'` | Same — `(def watchable 0)` inside deftest body, referenced in closures |
|
||||
### 1. `not_eq` — Cross-namespace dependency
|
||||
- **Error**: `undeclared identifier: 'eq_SLASH_tests'`
|
||||
- **Cause**: Test calls `(eq/tests (complement not=))` where `eq/tests` is a function defined in `clojure.core-test.eq` namespace (separate file). Our compiler processes each test file independently — it doesn't load required namespaces.
|
||||
- **Fix needed**: Multi-file compilation — `ns :require` should inline/compile required files and make their functions available.
|
||||
|
||||
All 3 require deeper architectural changes:
|
||||
- Multi-file compilation or inline required namespaces
|
||||
- Top-level def hoisting across closure boundaries
|
||||
### 2. `add_watch` — Closure scoping with fn params
|
||||
- **Error**: `undeclared identifier: 'ref1'`
|
||||
- **Cause**: The test defines functions like `(fn [key ref old new] ...)` where `ref` gets mangled to `ref1`. These fn params are used inside deeply nested closures (try/catch inside fn inside testing block). The IIFE wrapping by `emitBlock` creates scope boundaries that prevent fn params from being visible in inner closures.
|
||||
- **Fix needed**: IIFE-wrapped closures must capture enclosing scope variables. Either stop wrapping non-last forms in IIFEs, or use Nim closures that properly capture outer variables.
|
||||
|
||||
### 3. `remove_watch` — Same closure scoping issue
|
||||
- **Error**: `undeclared identifier: 'ref1'`
|
||||
- **Cause**: Same as `add_watch` — fn params not visible across IIFE boundaries.
|
||||
- **Fix needed**: Same as `add_watch`.
|
||||
|
||||
## Roadmap to 100%
|
||||
|
||||
### Phase A: Closure Scoping Fix (fixes add_watch + remove_watch)
|
||||
- **Approach**: Instead of wrapping non-last forms in `discard ((proc(): CljVal = ...)())`, emit them as direct statements. The IIFE wrapping was added to handle multi-line expressions as non-last forms, but it breaks variable scoping.
|
||||
- **Alternative**: Use Nim's `{.inline.}` procs or `block:` labels instead of IIFEs for scope isolation.
|
||||
- **Impact**: +2 tests (232/233)
|
||||
|
||||
### Phase B: Multi-file Compilation (fixes not_eq)
|
||||
- **Approach**: When `ns :require` encounters a namespace, find and compile the corresponding `.cljc`/`.clj` file, inline its top-level defs into the current compilation unit.
|
||||
- **Key files**: `src/cljnim.nim` (file resolution), `src/emitter.nim` (ns handler)
|
||||
- **Impact**: +1 test (233/233)
|
||||
|
||||
### Phase C: Symbol Emit Fix (fixes 2 unit tests)
|
||||
- **Approach**: When emitting a bare symbol that's not a local var and not a runtime function, check if it was defined as a `def`/`defn` in the current compilation unit. If so, emit the mangled name directly instead of `cljSymbol(...)`.
|
||||
- **Impact**: +2 unit tests (80/80)
|
||||
|
||||
## Session Log
|
||||
|
||||
### 2026-05-11 (late session) — Bulk fixes
|
||||
- Reader: prefer `:default` over `:clj` in conditionals
|
||||
- Emitter: `cond`, `definterface`, `new` special forms
|
||||
- Emitter: `ns` alias registration, `when` discard, `try/catch` scope + type mapping
|
||||
- Emitter: `emitBlock` var hoisting out of IIFEs
|
||||
- Emitter: removed all DEBUG stderr output
|
||||
- Runtime: `random-uuid`, `System/getProperty`, `vreset!`, `restart-agent`, `require`/`eval`/`resolve` stubs
|
||||
- Runtime: `Boolean`/`Object`/`Integer` constructors
|
||||
- Runtime: seq overloads for `cljAssoc`, `cljDissoc`, `cljGet`, `cljExInfo`, `cljTransduce`
|
||||
- Result: 220/233 → 230/233 compliance, 77/80 → 78/80 unit tests
|
||||
|
||||
Reference in New Issue
Block a user