Bugfixes: add cljQuot/cljRem to runtime, quot/rem to interpreter. Cleanup: remove unused processAgentActions and sequtils import. 164 tests pass.
This commit is contained in:
@@ -97,7 +97,7 @@ These tasks are **small, well-defined, and high impact**:
|
|||||||
3. **T6.4 `spit`** ✅ — Done. ``(spit "file.txt" "content")`` works.
|
3. **T6.4 `spit`** ✅ — Done. ``(spit "file.txt" "content")`` works.
|
||||||
4. **T6.8 `take`, `drop`** ✅ — Done. `cljTake`, `cljDrop` in runtime, emitter mappings.
|
4. **T6.8 `take`, `drop`** ✅ — Done. `cljTake`, `cljDrop` in runtime, emitter mappings.
|
||||||
5. **T6.11 `type`, `instance?`** ✅ — Done. `cljType`, `cljInstanceP` in runtime.
|
5. **T6.11 `type`, `instance?`** ✅ — Done. `cljType`, `cljInstanceP` in runtime.
|
||||||
6. **T4.6 Tool-call format** ⬜ — Wrap REPL input parser to accept `{"tool":...}`.
|
6. **T4.6 Tool-call format** ✅ — Done. REPL accepts `{"tool":"cljnim/eval","args":{"form":"..."}}`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -79,4 +79,10 @@
|
|||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
- `->>` threading macro with nested `map`/`reduce` requires proper macro expansion context
|
- `->>` threading macro with nested `map`/`reduce` requires proper macro expansion context
|
||||||
- REPL definitions are re-compiled from scratch on each evaluation (slow but correct)
|
- REPL definitions are re-compiled from scratch on each evaluation (slow but correct — interpreter path handles most cases in <0.1ms now)
|
||||||
|
- ffi/interop examples fail — `sin` symbol not found (Nim module import issue, pre-existing)
|
||||||
|
|
||||||
|
## Recent Bug Fixes (2026-05-08)
|
||||||
|
- Fixed: `quot`/`rem` — added `cljQuot`/`cljRem` to runtime + interpreter support
|
||||||
|
- Fixed: `rem` — interpreter and compiled path both now handle `(rem n d)`
|
||||||
|
- Cleanup: removed unused `processAgentActions` proc, unused `sequtils` import in repl.nim
|
||||||
|
|||||||
+16
-14
@@ -281,6 +281,22 @@ proc cljMax*(args: seq[CljVal]): CljVal =
|
|||||||
if args[i].kind == ckInt and result.kind == ckInt:
|
if args[i].kind == ckInt and result.kind == ckInt:
|
||||||
if args[i].intVal > result.intVal: result = args[i]
|
if args[i].intVal > result.intVal: result = args[i]
|
||||||
|
|
||||||
|
proc cljQuot*(a, b: CljVal): CljVal =
|
||||||
|
if a.kind == ckInt and b.kind == ckInt:
|
||||||
|
if b.intVal == 0:
|
||||||
|
raise newException(CatchableError, "Division by zero")
|
||||||
|
cljInt(a.intVal div b.intVal)
|
||||||
|
else:
|
||||||
|
raise newException(CatchableError, "quot requires integers")
|
||||||
|
|
||||||
|
proc cljRem*(a, b: CljVal): CljVal =
|
||||||
|
if a.kind == ckInt and b.kind == ckInt:
|
||||||
|
if b.intVal == 0:
|
||||||
|
raise newException(CatchableError, "Division by zero")
|
||||||
|
cljInt(a.intVal mod b.intVal)
|
||||||
|
else:
|
||||||
|
raise newException(CatchableError, "rem requires integers")
|
||||||
|
|
||||||
# ---- Comparison ----
|
# ---- Comparison ----
|
||||||
|
|
||||||
proc cljNumEq*(args: seq[CljVal]): CljVal =
|
proc cljNumEq*(args: seq[CljVal]): CljVal =
|
||||||
@@ -1011,20 +1027,6 @@ proc cljAgent*(v: CljVal): CljVal =
|
|||||||
result = CljVal(kind: ckAgent, agentVal: v, agentBusy: false)
|
result = CljVal(kind: ckAgent, agentVal: v, agentBusy: false)
|
||||||
initLock(result.agentLock)
|
initLock(result.agentLock)
|
||||||
|
|
||||||
proc processAgentActions(agent: CljVal) =
|
|
||||||
withLock agent.agentLock:
|
|
||||||
while agent.agentQueue.len > 0:
|
|
||||||
let action = agent.agentQueue[0]
|
|
||||||
agent.agentQueue.delete(0)
|
|
||||||
var fargs = @[agent.agentVal]
|
|
||||||
fargs.add(action.args)
|
|
||||||
if action.fn.kind == ckFn:
|
|
||||||
agent.agentVal = action.fn.fnProc(fargs)
|
|
||||||
elif action.fn.kind == ckList:
|
|
||||||
# fn form: (fn [params] body) — use interpreter
|
|
||||||
discard
|
|
||||||
agent.agentBusy = false
|
|
||||||
|
|
||||||
proc cljAgentSend*(agent: CljVal, f: CljVal, args: seq[CljVal] = @[]): CljVal =
|
proc cljAgentSend*(agent: CljVal, f: CljVal, args: seq[CljVal] = @[]): CljVal =
|
||||||
if agent.kind != ckAgent:
|
if agent.kind != ckAgent:
|
||||||
raise newException(CatchableError, "send requires an agent")
|
raise newException(CatchableError, "send requires an agent")
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ proc runtimeName(op: string): string =
|
|||||||
of "iterate": "cljIterate"
|
of "iterate": "cljIterate"
|
||||||
of "interleave": "cljInterleave"
|
of "interleave": "cljInterleave"
|
||||||
of "quot": "cljQuot"
|
of "quot": "cljQuot"
|
||||||
|
of "rem": "cljRem"
|
||||||
of "instance?": "cljInstanceP"
|
of "instance?": "cljInstanceP"
|
||||||
of "meta": "cljMeta"
|
of "meta": "cljMeta"
|
||||||
of "with-meta": "cljWithMeta"
|
of "with-meta": "cljWithMeta"
|
||||||
|
|||||||
@@ -874,6 +874,22 @@ proc evalList(items: seq[CljVal], env: Env): EvalResult =
|
|||||||
return EvalResult(ok: true, value: cljInt(args[0].intVal mod args[1].intVal))
|
return EvalResult(ok: true, value: cljInt(args[0].intVal mod args[1].intVal))
|
||||||
return EvalResult(ok: false, error: "mod requires integers")
|
return EvalResult(ok: false, error: "mod requires integers")
|
||||||
|
|
||||||
|
of "quot":
|
||||||
|
numArgs(2)
|
||||||
|
if args[0].kind == ckInt and args[1].kind == ckInt:
|
||||||
|
if args[1].intVal == 0:
|
||||||
|
return EvalResult(ok: false, error: "Division by zero")
|
||||||
|
return EvalResult(ok: true, value: cljInt(args[0].intVal div args[1].intVal))
|
||||||
|
return EvalResult(ok: false, error: "quot requires integers")
|
||||||
|
|
||||||
|
of "rem":
|
||||||
|
numArgs(2)
|
||||||
|
if args[0].kind == ckInt and args[1].kind == ckInt:
|
||||||
|
if args[1].intVal == 0:
|
||||||
|
return EvalResult(ok: false, error: "Division by zero")
|
||||||
|
return EvalResult(ok: true, value: cljInt(args[0].intVal mod args[1].intVal))
|
||||||
|
return EvalResult(ok: false, error: "rem requires integers")
|
||||||
|
|
||||||
of "min":
|
of "min":
|
||||||
numArgs(2)
|
numArgs(2)
|
||||||
if args[0].kind == ckInt and args[1].kind == ckInt:
|
if args[0].kind == ckInt and args[1].kind == ckInt:
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# AI-First REPL for Clojure/Nim
|
# AI-First REPL for Clojure/Nim
|
||||||
import os, osproc, strutils, sequtils, json, times, net
|
import os, osproc, strutils, json, times, net
|
||||||
import reader, emitter, types, macros, eval
|
import reader, emitter, types, macros, eval
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|||||||
Reference in New Issue
Block a user