feat: +12 tests (210/233, 90%) — fn wrapping, doseq, when-first, NaN?, delay, loop scope
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
This commit is contained in:
@@ -81,6 +81,10 @@ proc cljInt*(v: int): CljVal = CljVal(kind: ckInt, intVal: v.int64)
|
||||
proc cljFloat*(v: float64): CljVal = CljVal(kind: ckFloat, floatVal: v)
|
||||
proc cljInf*(args: seq[CljVal]): CljVal = CljVal(kind: ckFloat, floatVal: Inf)
|
||||
proc cljNaN*(args: seq[CljVal]): CljVal = CljVal(kind: ckFloat, floatVal: NaN)
|
||||
|
||||
proc cljNaNQ*(v: CljVal): CljVal =
|
||||
if v.kind == ckFloat: cljBool(v.floatVal.isNaN)
|
||||
else: cljBool(false)
|
||||
proc cljString*(v: string): CljVal = CljVal(kind: ckString, strVal: v)
|
||||
proc cljKeyword*(v: string): CljVal = CljVal(kind: ckKeyword, kwName: v)
|
||||
proc cljSymbol*(v: string): CljVal = CljVal(kind: ckSymbol, symName: v)
|
||||
@@ -779,6 +783,23 @@ proc cljArrayMap*(args: seq[CljVal]): CljVal =
|
||||
proc cljSortedQ*(v: CljVal): CljVal =
|
||||
cljBool(false)
|
||||
|
||||
proc cljRseq*(v: CljVal): CljVal =
|
||||
case v.kind
|
||||
of ckVector:
|
||||
var items: seq[CljVal] = @[]
|
||||
for i in countdown(v.vecData.count - 1, 0):
|
||||
items.add(v.vecData[i])
|
||||
cljList(items)
|
||||
of ckList:
|
||||
var items: seq[CljVal] = @[]
|
||||
for i in countdown(v.listItems.len - 1, 0):
|
||||
items.add(v.listItems[i])
|
||||
cljList(items)
|
||||
else: cljNil()
|
||||
|
||||
proc cljListEmpty*(args: seq[CljVal]): CljVal =
|
||||
cljList(args)
|
||||
|
||||
# Missing function stubs for test suite compatibility
|
||||
proc cljToFloat*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljFloat(0.0)
|
||||
@@ -1580,6 +1601,14 @@ proc cljFuture*(args: seq[CljVal]): CljVal =
|
||||
else:
|
||||
cljAtom(cljNil())
|
||||
|
||||
proc cljDelay*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljAtom(cljNil())
|
||||
let f = args[0]
|
||||
if f.kind == ckFn:
|
||||
cljAtom(f.fnProc(@[]))
|
||||
else:
|
||||
cljAtom(f)
|
||||
|
||||
proc cljDeref*(a: CljVal): CljVal =
|
||||
if a.kind == ckAtom: a.atomVal
|
||||
elif a.kind == ckAgent: a.agentVal
|
||||
|
||||
Reference in New Issue
Block a user