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:
+90
-1
@@ -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
|
||||
|
||||
+12
-1
@@ -272,6 +272,12 @@ proc runtimeName(op: string): string =
|
||||
of "binding": "cljBinding"
|
||||
of "aset": "cljAset"
|
||||
of "vector": "cljVectorFn"
|
||||
of "compare": "cljCompare"
|
||||
of "subvec": "cljSubvec"
|
||||
of "rand": "cljRand"
|
||||
of "rand-int": "cljRandInt"
|
||||
of "rand-nth": "cljRandNth"
|
||||
of "random-sample": "cljRandomSample"
|
||||
# ---- Type conversion ----
|
||||
of "float": "cljToFloat"
|
||||
of "int": "cljToInt"
|
||||
@@ -1219,7 +1225,12 @@ proc emitSpecialForm(items: seq[CljVal], indent: int): string =
|
||||
"zipmap", "hash-map", "hash-set", "sorted-map", "sorted-set",
|
||||
"array-map", "inf", "nan",
|
||||
"float", "int", "double", "long", "short", "byte",
|
||||
"boolean", "num", "number"]
|
||||
"boolean", "num", "number",
|
||||
"drop-last", "shuffle", "repeatedly", "fnil", "intern",
|
||||
"println-str", "prn-str", "binding", "aset",
|
||||
"volatile!", "deliver", "doall", "dorun",
|
||||
"to-array", "vector", "rand", "rand-int",
|
||||
"rand-nth", "random-sample"]
|
||||
var call: string
|
||||
if variadic:
|
||||
call = rn & "(@[" & argParts.join(", ") & "])"
|
||||
|
||||
Reference in New Issue
Block a user