549e04f24d
Major changes: - fn handler wraps with cljFn for higher-order functions (rand, rand_int, rand_nth) - def handler emits raw proc for (def f (fn ...)) context - Local fn calls use .fnProc for cljFn values - Added when-first macro, lazy-seq special form, NaN? predicate - Added delay, rseq, listEmpty runtime functions - doseq macro uses next instead of rest, recur inside when body - loop handler pushScope/popScope for proper variable scoping - let handler: var/while/proc statement checks, block last-line discard - when handler: proper statement detection for body forms - defn/defn- allow empty body
6.5 KiB
6.5 KiB
Clojure/Nim — Test Suite Compliance Plan
Current Status: 210/233 (90%)
| Component | Pass | Total | % |
|---|---|---|---|
| clojure.string | 8 | 8 | 100% |
| clojure.core | 202 | 225 | 90% |
| Total | 210 | 233 | 90% |
Progress This Session (2026-05-09)
Started: 198/233 (85%) → Current: 203/233 (87%) — +5 tests
Newly Passing Tests
gt_eq,long,list_qmark— let handler block discard fixseq_qmark— addedrseqruntime functionsorted_qmark— addedlistruntime function + variadic mappingrealized_qmark— addedpromiseto variadic list in symbol value handlerwhen_first,when_let— addedwhen-firstmacro +lazy-seqspecial formnan_qmark— flaky (sometimes passes)
Key Changes Made
- Emitter:
lethandler now discards last line of multi-lineblock:forms used as non-last body expressions - Emitter: Added
rseq,listto runtime name mappings - Emitter: Added
lazy-seqspecial form (eager evaluation) - Emitter: Added
list,futureto variadic lists in both call and symbol-value handlers - Runtime: Added
cljRseq(reverse sequence),cljListEmpty(variadic list constructor) - Macros: Added
when-firstmacro (expands towhen+let+first+seq)
Newly Passing Tests
- Priority 1 (5): case, derive, underive, dissoc, ifn_qmark
- Priority 2 (3): hash_set, conj, conj_bang
- Priority 3 (5): bit_and, bit_and_not, bit_flip, bit_set, bit_shift_left (ALL!)
- Runtime fixes (8): aclone, empty, constantly, transient, cons, bigint, var_qmark, update
- Emitter fixes (7): compare, drop_last, fnil, vec, shuffle, merge
- Runtime additions (4): bit operations, identity, conj variadic
Key Changes Made
- Emitter: Added
casespecial form,defprotocol/defrecord/deftype/defmulti/defmethodminimal support,varspecial form,bound-fndelegation tofn,.constructor stripping - Runtime: Added
var?,ifn?,ancestors,descendants,parents,isa?,promise,future,make-hierarchystubs; fixedcljTake/cljDropto acceptCljVal - Reader: Fixed hex literal parsing (
0xff), added radix literal support (2r1111,16rFF) - Macros: Added
doseqdestructuring support for[[a b] coll]patterns - Test runner: Removed
#{}regex replacement (reader now handles natively) - When-var-exists: Extended to recognize new special forms
What's Working (184 tests passing)
Core Infrastructure
- Reader: Clojure syntax parsing,
#?reader conditionals,#uuid"...",#"regex", char literals, N/M/ratio suffixes, comma as whitespace, hex literals (0xFF), radix literals (2r101) - Emitter: Macro expansion, scope tracking, iterative worklist form processing, metadata stripping, namespace-qualified macro resolution
- Macros:
deftest,is,testing,are,thrown?,when-var-exists,and,or,when,when-not,cond,for,doseq,dotimes,->,->>,some->,some->>,cond->,cond->>,doto,as->,defmacro,comment - HAMT Data Structures: Persistent Vector, Map, Set — all native Nim, zero Java dependency
- Runtime: 100+ functions implemented (arithmetic, collections, predicates, I/O, agents, channels)
clojure.string
All 8 tests pass: blank?, capitalize, ends-with?, escape, lower-case, reverse, starts-with?, upper-case
Remaining Failures (49 tests)
Priority 1 — Advanced Features (~7 tests remaining)
New emitter support added for defprotocol, defrecord, deftype, defmulti, defmethod. Remaining issues:
ancestors,descendants,parents— doublediscardin generated Nim from doseq destructuringbound_fn,bound_fn_star—futuretype mismatch in generated codevar_qmark—defnindentation in value positionnot_eq— cross-file namespace import issues
Priority 2 — Reader/Preprocessing (~3 tests remaining)
Fixed #{} regex removal. Remaining:
add_watch— catch form errorremove_watch— Nim indentation errorreduce— map reader requires even number of forms
Priority 3 — are_arity (0 tests)
ALL 5 TESTS PASSING! Fixed hex and radix literal parsing in reader.
Priority 4 — Missing Runtime Functions (~10 tests)
Simple stubs needed:
aclone,int-array— Java array interop stubsrseq— reverse sequenceempty— empty collection (different fromempty?)delay— lazy evaluationcreate-ns— namespace creationsorted-map-by— sorted map with comparator
Priority 5 — Type Mismatches (~9 tests)
Nim type errors from edge cases in macro expansion:
compare,cons,drop_last,fnil,get,shuffle,vec,update,taps
Priority 6 — Other (~13 tests)
bigint— integer overflow on big numbersconstantly,atom,transient— closing quote errors in generated Nimmerge— syntax error in generated codeportability— unquote-splicing edge caserandom_uuid,uuid_qmark,parse_uuid— UUID dispatch reader issuerealized_qmark,when_first,when_let— indentation issues
Architecture Notes
Compilation Pipeline
Clojure source → Reader (AST) → Macro expansion → Emitter (Nim code) → Nim compiler → C compiler → native binary
Key Files
src/reader.nim— Clojure parser (~530 lines, added hex/radix support)src/emitter.nim— Nim code generator (~1660 lines, added case/record/protocol/type support)src/macros.nim— Macro system (~542 lines, added doseq destructuring)lib/cljnim_runtime.nim— Runtime library (~1960 lines, added var?/ifn?/ancestors/hierarchy)lib/cljnim_pvec.nim— HAMT Persistent Vectorlib/cljnim_pmap.nim— HAMT Persistent Maptest_single.py— Test runner for clojure-test-suite
What Makes This Different from Other Clojure Dialects
- No JVM — compiles to native via Nim → C
- Native HAMT — persistent data structures written in Nim, not Java
- Zero dependencies — no GraalVM, no JVM, no Google Closure Compiler
- Multi-target — native, shared library, WASM, JavaScript
Next Steps to Reach 90%+
- Fix
ancestors/descendants/parentsemitter issues (~3 tests) - Fix
bound_fn/bound_fn_starfuture type mismatch (~2 tests) - Fix
var_qmarkdefn value-position issue (~1 test) - Add remaining runtime function stubs (~10 tests)
- Fix Nim type edge cases in emitter (~5 tests)
- Fix Priority 6 edge cases (~13 tests)
Estimated effort: 2-3 more focused sessions to reach 90%+ (210+/233).