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_pvec
|
||||||
import cljnim_pmap
|
import cljnim_pmap
|
||||||
import strutils, sequtils, hashes, algorithm, os, osproc, locks, math
|
import strutils, sequtils, hashes, algorithm, os, osproc, locks, math, random
|
||||||
|
|
||||||
type
|
type
|
||||||
CljKind* = enum
|
CljKind* = enum
|
||||||
@@ -890,6 +890,95 @@ proc cljAset*(args: seq[CljVal]): CljVal =
|
|||||||
proc cljVectorFn*(args: seq[CljVal]): CljVal =
|
proc cljVectorFn*(args: seq[CljVal]): CljVal =
|
||||||
cljVector(args)
|
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 =
|
proc cljTake*(n: int, coll: CljVal): CljVal =
|
||||||
if coll.isNil: return cljList(@[])
|
if coll.isNil: return cljList(@[])
|
||||||
case coll.kind
|
case coll.kind
|
||||||
|
|||||||
+12
-1
@@ -272,6 +272,12 @@ proc runtimeName(op: string): string =
|
|||||||
of "binding": "cljBinding"
|
of "binding": "cljBinding"
|
||||||
of "aset": "cljAset"
|
of "aset": "cljAset"
|
||||||
of "vector": "cljVectorFn"
|
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 ----
|
# ---- Type conversion ----
|
||||||
of "float": "cljToFloat"
|
of "float": "cljToFloat"
|
||||||
of "int": "cljToInt"
|
of "int": "cljToInt"
|
||||||
@@ -1219,7 +1225,12 @@ proc emitSpecialForm(items: seq[CljVal], indent: int): string =
|
|||||||
"zipmap", "hash-map", "hash-set", "sorted-map", "sorted-set",
|
"zipmap", "hash-map", "hash-set", "sorted-map", "sorted-set",
|
||||||
"array-map", "inf", "nan",
|
"array-map", "inf", "nan",
|
||||||
"float", "int", "double", "long", "short", "byte",
|
"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
|
var call: string
|
||||||
if variadic:
|
if variadic:
|
||||||
call = rn & "(@[" & argParts.join(", ") & "])"
|
call = rn & "(@[" & argParts.join(", ") & "])"
|
||||||
|
|||||||
Reference in New Issue
Block a user