# Clojure Value Types (Nim Runtime) import sequtils, strutils type CljKind* = enum ckNil, ckBool, ckInt, ckFloat, ckString, ckKeyword, ckSymbol, ckList, ckVector, ckMap CljVal* = ref object case kind*: CljKind of ckNil: discard of ckBool: boolVal*: bool of ckInt: intVal*: int64 of ckFloat: floatVal*: float64 of ckString: strVal*: string of ckKeyword: kwName*: string of ckSymbol: symName*: string of ckList, ckVector: items*: seq[CljVal] of ckMap: pairs*: seq[(CljVal, CljVal)] # Constructors proc cljNil*(): CljVal = CljVal(kind: ckNil) proc cljBool*(v: bool): CljVal = CljVal(kind: ckBool, boolVal: v) proc cljInt*(v: int64): CljVal = CljVal(kind: ckInt, intVal: v) proc cljFloat*(v: float64): CljVal = CljVal(kind: ckFloat, floatVal: v) proc cljString*(v: string): CljVal = CljVal(kind: ckString, strVal: v) proc cljKeyword*(v: string): CljVal = CljVal(kind: ckKeyword, kwName: v) proc cljSymbol*(v: string): CljVal = CljVal(kind: ckSymbol, symName: v) proc cljList*(items: seq[CljVal]): CljVal = CljVal(kind: ckList, items: items) proc cljVector*(items: seq[CljVal]): CljVal = CljVal(kind: ckVector, items: items) proc cljMap*(pairs: seq[(CljVal, CljVal)]): CljVal = CljVal(kind: ckMap, pairs: pairs) # String representation (for debugging) proc `$`*(v: CljVal): string = case v.kind of ckNil: "nil" of ckBool: $v.boolVal of ckInt: $v.intVal of ckFloat: $v.floatVal of ckString: "\"" & v.strVal & "\"" of ckKeyword: ":" & v.kwName of ckSymbol: v.symName of ckList: "(" & v.items.mapIt($it).join(" ") & ")" of ckVector: "[" & v.items.mapIt($it).join(" ") & "]" of ckMap: var parts: seq[string] = @[] for (k, v2) in v.pairs: parts.add($k & " " & $v2) "{" & parts.join(", ") & "}"