feat: add fullscreen TUI and project updates
- New TUI screens: Main Menu, Compile, Run, REPL, AI Generator, AI Settings, Help - AI configuration persisted in ~/.config/cljnim/config.json - Added illwill dependency for terminal UI - Updated experiments, examples, docs, and core modules
This commit is contained in:
+39
-39
@@ -13,7 +13,7 @@ type
|
||||
|
||||
CljVal* = ref CljValObj
|
||||
CljValObj = object
|
||||
meta*: CljVal # metadata attached to this value
|
||||
meta*: CljVal
|
||||
case kind*: CljKind
|
||||
of ckNil: discard
|
||||
of ckBool: boolVal*: bool
|
||||
@@ -29,9 +29,9 @@ type
|
||||
of ckFn: fnProc*: proc(args: seq[CljVal]): CljVal
|
||||
of ckAtom: atomVal*: CljVal
|
||||
of ckTransient:
|
||||
transKind*: CljKind # ckVector or ckMap — what this transient was created from
|
||||
transVec*: seq[CljVal] # mutable vector builder
|
||||
transPairs*: seq[(CljVal, CljVal)] # mutable map builder
|
||||
transKind*: CljKind
|
||||
transVec*: seq[CljVal]
|
||||
transPairs*: seq[(CljVal, CljVal)]
|
||||
of ckAgent:
|
||||
agentVal*: CljVal
|
||||
agentLock*: Lock
|
||||
@@ -601,7 +601,7 @@ proc cljDistinct*(coll: CljVal): CljVal =
|
||||
|
||||
proc cljFlatten*(coll: CljVal): CljVal =
|
||||
if coll.isNil: return cljList(@[])
|
||||
var result: seq[CljVal] = @[]
|
||||
var flat: seq[CljVal] = @[]
|
||||
proc flattenHelper(v: CljVal) =
|
||||
if v.isNil: return
|
||||
case v.kind
|
||||
@@ -612,9 +612,9 @@ proc cljFlatten*(coll: CljVal): CljVal =
|
||||
for item in v.vecData.items:
|
||||
flattenHelper(item)
|
||||
else:
|
||||
result.add(v)
|
||||
flat.add(v)
|
||||
flattenHelper(coll)
|
||||
cljList(result)
|
||||
cljList(flat)
|
||||
|
||||
proc cljPartition*(n: int, coll: CljVal): CljVal =
|
||||
if coll.isNil: return cljList(@[])
|
||||
@@ -715,20 +715,20 @@ proc cljVals*(m: CljVal): CljVal =
|
||||
|
||||
proc cljSelectKeys*(m: CljVal, keys: seq[CljVal]): CljVal =
|
||||
if m.isNil or m.kind != ckMap: return cljMap(@[], @[])
|
||||
var result = newPersistentMap[CljVal, CljVal]()
|
||||
var res = newPersistentMap[CljVal, CljVal]()
|
||||
for key in keys:
|
||||
let v = pmapGet(m.mapData, key, cljNil(), hash(key), cljEq)
|
||||
if not cljIsNil(v):
|
||||
result = pmapAssoc(result, key, v, hash(key), cljEq)
|
||||
CljVal(kind: ckMap, mapData: result)
|
||||
res = pmapAssoc(res, key, v, hash(key), cljEq)
|
||||
CljVal(kind: ckMap, mapData: res)
|
||||
|
||||
proc cljMerge*(args: seq[CljVal]): CljVal =
|
||||
var result = newPersistentMap[CljVal, CljVal]()
|
||||
var res = newPersistentMap[CljVal, CljVal]()
|
||||
for m in args:
|
||||
if not m.isNil and m.kind == ckMap:
|
||||
for (k, v) in pmapItems(m.mapData):
|
||||
result = pmapAssoc(result, k, v, hash(k), cljEq)
|
||||
CljVal(kind: ckMap, mapData: result)
|
||||
res = pmapAssoc(res, k, v, hash(k), cljEq)
|
||||
CljVal(kind: ckMap, mapData: res)
|
||||
|
||||
# ---- Higher-order functions ----
|
||||
|
||||
@@ -973,25 +973,25 @@ proc cljMeta*(v: CljVal): CljVal =
|
||||
|
||||
proc cljWithMeta*(v: CljVal, m: CljVal): CljVal =
|
||||
if v.isNil: return v
|
||||
var result = v # share ref, but we need a copy
|
||||
result = CljVal(kind: v.kind, meta: m)
|
||||
var copy = v # share ref, but we need a copy
|
||||
copy = CljVal(kind: v.kind, meta: m)
|
||||
case v.kind
|
||||
of ckNil: discard
|
||||
of ckBool: result.boolVal = v.boolVal
|
||||
of ckInt: result.intVal = v.intVal
|
||||
of ckFloat: result.floatVal = v.floatVal
|
||||
of ckString: result.strVal = v.strVal
|
||||
of ckKeyword: result.kwName = v.kwName
|
||||
of ckSymbol: result.symName = v.symName
|
||||
of ckList: result.listItems = v.listItems
|
||||
of ckVector: result.vecData = v.vecData
|
||||
of ckMap: result.mapData = v.mapData
|
||||
of ckSet: result.setData = v.setData
|
||||
of ckFn: result.fnProc = v.fnProc
|
||||
of ckAtom: result.atomVal = v.atomVal
|
||||
of ckTransient: result.transKind = v.transKind; result.transVec = v.transVec; result.transPairs = v.transPairs
|
||||
of ckAgent: result.agentVal = v.agentVal; initLock(result.agentLock)
|
||||
return result
|
||||
of ckBool: copy.boolVal = v.boolVal
|
||||
of ckInt: copy.intVal = v.intVal
|
||||
of ckFloat: copy.floatVal = v.floatVal
|
||||
of ckString: copy.strVal = v.strVal
|
||||
of ckKeyword: copy.kwName = v.kwName
|
||||
of ckSymbol: copy.symName = v.symName
|
||||
of ckList: copy.listItems = v.listItems
|
||||
of ckVector: copy.vecData = v.vecData
|
||||
of ckMap: copy.mapData = v.mapData
|
||||
of ckSet: copy.setData = v.setData
|
||||
of ckFn: copy.fnProc = v.fnProc
|
||||
of ckAtom: copy.atomVal = v.atomVal
|
||||
of ckTransient: copy.transKind = v.transKind; copy.transVec = v.transVec; copy.transPairs = v.transPairs
|
||||
of ckAgent: copy.agentVal = v.agentVal; initLock(copy.agentLock)
|
||||
return copy
|
||||
|
||||
proc cljAtom*(v: CljVal): CljVal =
|
||||
CljVal(kind: ckAtom, atomVal: v)
|
||||
@@ -1173,22 +1173,22 @@ proc cljInto*(to: CljVal, src: CljVal): CljVal =
|
||||
else: to
|
||||
of ckMap:
|
||||
if src.kind == ckMap:
|
||||
var result = to.mapData
|
||||
var res = to.mapData
|
||||
for (k, v) in pmapItems(src.mapData):
|
||||
result = pmapAssoc(result, k, v, hash(k), cljEq)
|
||||
CljVal(kind: ckMap, mapData: result)
|
||||
res = pmapAssoc(res, k, v, hash(k), cljEq)
|
||||
CljVal(kind: ckMap, mapData: res)
|
||||
elif src.kind == ckVector:
|
||||
var result = to.mapData
|
||||
var res = to.mapData
|
||||
for pair in src.vecData.items:
|
||||
if pair.kind == ckVector and pair.vecData.count == 2:
|
||||
result = pmapAssoc(result, pvecNth(pair.vecData, 0), pvecNth(pair.vecData, 1), hash(pvecNth(pair.vecData, 0)), cljEq)
|
||||
CljVal(kind: ckMap, mapData: result)
|
||||
res = pmapAssoc(res, pvecNth(pair.vecData, 0), pvecNth(pair.vecData, 1), hash(pvecNth(pair.vecData, 0)), cljEq)
|
||||
CljVal(kind: ckMap, mapData: res)
|
||||
elif src.kind == ckList:
|
||||
var result = to.mapData
|
||||
var res = to.mapData
|
||||
for pair in src.listItems:
|
||||
if pair.kind == ckVector and pair.vecData.count == 2:
|
||||
result = pmapAssoc(result, pvecNth(pair.vecData, 0), pvecNth(pair.vecData, 1), hash(pvecNth(pair.vecData, 0)), cljEq)
|
||||
CljVal(kind: ckMap, mapData: result)
|
||||
res = pmapAssoc(res, pvecNth(pair.vecData, 0), pvecNth(pair.vecData, 1), hash(pvecNth(pair.vecData, 0)), cljEq)
|
||||
CljVal(kind: ckMap, mapData: res)
|
||||
else: to
|
||||
else: to
|
||||
|
||||
|
||||
Reference in New Issue
Block a user