fix: expand variadic list + add runtime stubs — 174/233 (74%)

Runtime: cljCompare, cljSubvec, cljRand, cljRandInt, cljRandNth,
cljRandomSample with native Nim implementations
Emitter: expanded variadic function list for correct seq[CljVal] calling

Results: 174/233 passed (74%)
  clojure.string: 8/8 (100%)
  clojure.core: 166/225 (74%)
This commit is contained in:
2026-05-09 18:21:14 +03:00
parent cb69df4ee2
commit f79a2591d4
2 changed files with 102 additions and 2 deletions
+90 -1
View File
@@ -1,6 +1,6 @@
import cljnim_pvec
import cljnim_pmap
import strutils, sequtils, hashes, algorithm, os, osproc, locks, math
import strutils, sequtils, hashes, algorithm, os, osproc, locks, math, random
type
CljKind* = enum
@@ -890,6 +890,95 @@ proc cljAset*(args: seq[CljVal]): CljVal =
proc cljVectorFn*(args: seq[CljVal]): CljVal =
cljVector(args)
proc cljCompare*(args: seq[CljVal]): CljVal =
if args.len < 2: return cljInt(0)
let a = args[0]; let b = args[1]
if a.isNil and b.isNil: return cljInt(0)
if a.isNil: return cljInt(-1)
if b.isNil: return cljInt(1)
case a.kind
of ckInt:
if b.kind == ckInt:
if a.intVal < b.intVal: return cljInt(-1)
elif a.intVal > b.intVal: return cljInt(1)
else: return cljInt(0)
elif b.kind == ckFloat:
if a.intVal.float < b.floatVal: return cljInt(-1)
elif a.intVal.float > b.floatVal: return cljInt(1)
else: return cljInt(0)
of ckFloat:
if b.kind == ckFloat:
if a.floatVal < b.floatVal: return cljInt(-1)
elif a.floatVal > b.floatVal: return cljInt(1)
else: return cljInt(0)
elif b.kind == ckInt:
if a.floatVal < b.intVal.float: return cljInt(-1)
elif a.floatVal > b.intVal.float: return cljInt(1)
else: return cljInt(0)
of ckString:
if b.kind == ckString:
if a.strVal < b.strVal: return cljInt(-1)
elif a.strVal > b.strVal: return cljInt(1)
else: return cljInt(0)
of ckKeyword:
if b.kind == ckKeyword:
if a.kwName < b.kwName: return cljInt(-1)
elif a.kwName > b.kwName: return cljInt(1)
else: return cljInt(0)
else: discard
cljInt(0)
proc cljSubvec*(args: seq[CljVal]): CljVal =
if args.len < 2: return cljVector(@[])
let v = args[0]
let start = args[1].intVal.int
let stop = if args.len >= 3: args[2].intVal.int else: (if v.kind == ckVector: v.vecData.count else: 0)
if v.kind != ckVector: return cljVector(@[])
var items: seq[CljVal] = @[]
for i in start..<min(stop, v.vecData.count):
items.add(v.vecData[i])
cljVector(items)
proc cljRand*(args: seq[CljVal]): CljVal =
if args.len == 0: return cljFloat(rand(1.0))
let n = args[0]
case n.kind
of ckInt: return cljInt(rand(n.intVal.int).int64)
of ckFloat: return cljFloat(rand(n.floatVal))
else: return cljFloat(rand(1.0))
proc cljRandInt*(args: seq[CljVal]): CljVal =
if args.len == 0: return cljInt(0)
let n = args[0].intVal.int
if n <= 0: return cljInt(0)
cljInt(rand(n).int64)
proc cljRandNth*(args: seq[CljVal]): CljVal =
if args.len == 0: return cljNil()
let coll = args[0]
case coll.kind
of ckVector:
if coll.vecData.count == 0: return cljNil()
return coll.vecData[rand(coll.vecData.count)]
of ckList:
let items = coll.listItems
if items.len == 0: return cljNil()
return items[rand(items.len)]
else: return cljNil()
proc cljRandomSample*(args: seq[CljVal]): CljVal =
if args.len < 2: return cljList(@[])
let coll = args[1]
var items: seq[CljVal] = @[]
let collItems = case coll.kind
of ckList: coll.listItems
of ckVector: toSeq(coll.vecData)
else: @[]
for item in collItems:
if rand(1.0) < 0.5:
items.add(item)
cljList(items)
proc cljTake*(n: int, coll: CljVal): CljVal =
if coll.isNil: return cljList(@[])
case coll.kind