fix: 230/233 (98.7%) — reader :default preference, cond/new/definterface, runtime stubs, seq overloads
- Reader: prefer :default over :clj in reader conditionals
- Emitter: add cond, definterface, new special forms
- Emitter: ns handler registers namespace aliases from :require
- Emitter: when body always discarded (fixes type mismatch with else)
- Emitter: try/catch maps clojure.lang.ExceptionInfo → ExInfo, scope catch vars
- Emitter: def inside proc uses var (not {.global.}), removed debug output
- Runtime: cljRandomUuid, cljSystemGetProperty, cljVresetB, cljRestartAgent
- Runtime: cljRequire, cljEvalStub, cljResolve no-op stubs
- Runtime: Boolean/Object/Integer/Long/Float/Double constructors
- Runtime: seq overloads for cljAssoc, cljDissoc, cljGet, cljExInfo, cljTransduce
- Unit tests: 78/80 (was 77/80)
- 3 remaining: not_eq (cross-namespace), add_watch/remove_watch (def hoisting)
This commit is contained in:
@@ -1338,6 +1338,10 @@ proc cljGet*(m: CljVal, key: CljVal): CljVal =
|
||||
else: cljNil()
|
||||
else: cljNil()
|
||||
|
||||
proc cljGet*(args: seq[CljVal]): CljVal =
|
||||
if args.len < 2: return cljNil()
|
||||
cljGet(args[0], args[1])
|
||||
|
||||
proc cljGetDefault*(m: CljVal, key: CljVal, default: CljVal): CljVal =
|
||||
if m.isNil: return default
|
||||
case m.kind
|
||||
@@ -1352,6 +1356,13 @@ proc cljExInfo*(msg: CljVal, data: CljVal): CljVal =
|
||||
ex.exData = data
|
||||
raise ex
|
||||
|
||||
proc cljExInfo*(args: seq[CljVal]): CljVal =
|
||||
var msg = if args.len > 0: args[0] else: cljString("")
|
||||
var data = if args.len > 1: args[1] else: cljNil()
|
||||
var ex = newException(ExInfo, cljStr(msg))
|
||||
ex.exData = data
|
||||
raise ex
|
||||
|
||||
proc cljExData*(ex: CljVal): CljVal =
|
||||
if ex.isNil: return cljNil()
|
||||
case ex.kind
|
||||
@@ -1403,10 +1414,18 @@ proc cljAssoc*(m: CljVal, key: CljVal, val: CljVal): CljVal =
|
||||
else:
|
||||
raise newException(CatchableError, "assoc expects a map or vector")
|
||||
|
||||
proc cljAssoc*(args: seq[CljVal]): CljVal =
|
||||
if args.len < 3: raise newException(CatchableError, "assoc requires 3 arguments")
|
||||
cljAssoc(args[0], args[1], args[2])
|
||||
|
||||
proc cljDissoc*(m: CljVal, key: CljVal): CljVal =
|
||||
if m.isNil or m.kind != ckMap: return cljMap(@[], @[])
|
||||
CljVal(kind: ckMap, mapData: pmapDissoc(m.mapData, key, hash(key), cljEq))
|
||||
|
||||
proc cljDissoc*(args: seq[CljVal]): CljVal =
|
||||
if args.len < 2: return cljMap(@[], @[])
|
||||
cljDissoc(args[0], args[1])
|
||||
|
||||
proc cljContains*(m: CljVal, key: CljVal): CljVal =
|
||||
if m.isNil: return cljBool(false)
|
||||
case m.kind
|
||||
@@ -1523,6 +1542,10 @@ proc cljTransduce*(xform: CljVal, f: CljVal, init: CljVal, coll: CljVal): CljVal
|
||||
# Fallback: just return init
|
||||
return init
|
||||
|
||||
proc cljTransduce*(args: seq[CljVal]): CljVal =
|
||||
if args.len < 4: return cljNil()
|
||||
cljTransduce(args[0], args[1], args[2], args[3])
|
||||
|
||||
proc cljMapv*(f: proc(args: seq[CljVal]): CljVal, coll: CljVal): CljVal =
|
||||
if coll.isNil: return cljVector(@[])
|
||||
case coll.kind
|
||||
@@ -2246,3 +2269,90 @@ proc cljZipmap*(args: seq[CljVal]): CljVal =
|
||||
mk.add(kitems[i])
|
||||
mv.add(vitems[i])
|
||||
return cljMap(mk, mv)
|
||||
|
||||
# ---- Missing stubs ----
|
||||
|
||||
proc cljRandomUuid*(args: seq[CljVal]): CljVal =
|
||||
randomize()
|
||||
var uuid = ""
|
||||
for i in 0..<32:
|
||||
uuid.add("0123456789abcdef"[rand(15)])
|
||||
if i in {7, 11, 15, 19}: uuid.add('-')
|
||||
cljString(uuid)
|
||||
|
||||
proc cljSystemGetProperty*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljNil()
|
||||
let key = if args[0].kind == ckString: args[0].strVal else: ""
|
||||
case key
|
||||
of "line.separator": cljString("\n")
|
||||
of "file.separator": cljString("/")
|
||||
of "path.separator": cljString(":")
|
||||
of "os.name": cljString("linux")
|
||||
of "os.arch": cljString("x86_64")
|
||||
of "java.version": cljString("0")
|
||||
else: cljString("")
|
||||
|
||||
proc cljVresetB*(args: seq[CljVal]): CljVal =
|
||||
if args.len < 2: return cljNil()
|
||||
if args[0].kind == ckAtom:
|
||||
args[0].atomVal = args[1]
|
||||
args[1]
|
||||
else:
|
||||
raise newException(CatchableError, "vreset! requires a volatile")
|
||||
|
||||
proc cljRestartAgent*(args: seq[CljVal]): CljVal =
|
||||
if args.len < 2: return cljNil()
|
||||
if args[0].kind == ckAgent:
|
||||
args[0].agentVal = args[1]
|
||||
args[0].agentBusy = false
|
||||
args[0]
|
||||
else:
|
||||
raise newException(CatchableError, "restart-agent requires an agent")
|
||||
|
||||
proc cljRequire*(args: seq[CljVal]): CljVal =
|
||||
cljNil()
|
||||
|
||||
proc cljEvalStub*(args: seq[CljVal]): CljVal =
|
||||
cljNil()
|
||||
|
||||
proc cljResolve*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljNil()
|
||||
cljNil()
|
||||
|
||||
proc Boolean*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljBool(false)
|
||||
let v = args[0]
|
||||
if v.kind == ckBool: v
|
||||
elif v.kind == ckString: cljBool(v.strVal.toLowerAscii() == "true")
|
||||
elif v.kind == ckInt: cljBool(v.intVal != 0)
|
||||
elif v.kind == ckFloat: cljBool(v.floatVal != 0.0)
|
||||
else: cljBool(cljIsTruthy(v))
|
||||
|
||||
proc Boolean*(v: CljVal): CljVal =
|
||||
Boolean(@[v])
|
||||
|
||||
proc Object*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: cljKeyword("Object")
|
||||
else: args[0]
|
||||
|
||||
proc Object*(): CljVal =
|
||||
cljKeyword("Object")
|
||||
|
||||
proc Integer*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljInt(0)
|
||||
cljToInt(args)
|
||||
|
||||
proc Integer*(v: CljVal): CljVal =
|
||||
cljToInt(@[v])
|
||||
|
||||
proc Long*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljInt(0)
|
||||
cljToInt(args)
|
||||
|
||||
proc Float*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljFloat(0.0)
|
||||
cljToFloat(args)
|
||||
|
||||
proc Double*(args: seq[CljVal]): CljVal =
|
||||
if args.len == 0: return cljFloat(0.0)
|
||||
cljToFloat(args)
|
||||
|
||||
Reference in New Issue
Block a user