50 lines
1.7 KiB
Nim
50 lines
1.7 KiB
Nim
# 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(", ") & "}"
|