fix: 18 bugs across interpreter, reader, emitter, and runtime

- cljMinMax now handles float and mixed int/float arguments
- cljType* covers ckSet, ckTransient, ckAgent
- cljConj and cljVec return vectors instead of lists
- rem uses truncated division semantics (matches Clojure)
- range with negative step terminates correctly
- reduce of empty collection with no init errors instead of returning nil
- swap! extra args flatten correctly
- remove duplicate not definition (dead code)
- ratio literals (1/5) parse correctly
- scientific notation uses correct variable (numTok not tok)
- readSet returns proper set value instead of (set [...]) form
- TCP REPL catches specific exceptions instead of bare except
- initBuiltinMacros guards against duplicate registration
- doseq :while clause no longer generates dead code or infinite loop
- emitter resets all global state on each emitProgram call
- pushLeaf fills gaps with internal nodes instead of nil children

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 12:25:53 +03:00
parent 7cb8aa1ee0
commit 11fca52282
7 changed files with 91 additions and 42 deletions
+5 -9
View File
@@ -77,17 +77,13 @@ proc pushLeaf[T](node: PVecNode[T], index: int, shift: int, val: seq[T]): PVecNo
# Push a full leaf (seq of up to 32 values) into the tree at position 'index'
result = copyNode(node)
if shift == 0:
# Should not happen — we always push into internal nodes
result = newLeafNode[T](val)
else:
let childIdx = (index shr shift) and BRANCHING_MASK
if childIdx >= result.children.len:
# Need to grow children array
let oldLen = result.children.len
result.children.setLen(childIdx + 1)
for i in oldLen..<childIdx:
result.children[i] = nil
# Grow children array and fill any gaps with empty internal nodes
while result.children.len <= childIdx:
result.children.add(newInternalNode[T]())
var child = result.children[childIdx]
if child.isNil:
if shift == BRANCHING_BITS:
@@ -96,7 +92,7 @@ proc pushLeaf[T](node: PVecNode[T], index: int, shift: int, val: seq[T]): PVecNo
child = pushLeaf(newInternalNode[T](), index, shift - BRANCHING_BITS, val)
else:
child = pushLeaf(child, index, shift - BRANCHING_BITS, val)
result.children[childIdx] = child
proc pvecConj*[T](v: PersistentVector[T], val: T): PersistentVector[T] =