121 lines
2.4 KiB
Nim
121 lines
2.4 KiB
Nim
import std/sequtils, std/strutils, std/tables
|
|
|
|
type
|
|
ValueKind* = enum
|
|
tInt,
|
|
tBool,
|
|
tString,
|
|
tPath,
|
|
tNull,
|
|
tAttrs,
|
|
tList,
|
|
tThunk,
|
|
tApp,
|
|
tLambda,
|
|
tBlackhole,
|
|
tPrimOp,
|
|
tPrimOpApp,
|
|
tExternal,
|
|
tFloat
|
|
Value* = ref object
|
|
case kind: ValueKind
|
|
of tInt:
|
|
num*: BiggestInt
|
|
of tBool:
|
|
boolean*: bool
|
|
of tString:
|
|
str*: string
|
|
of tPath:
|
|
path*: string
|
|
of tNull:
|
|
discard
|
|
of tAttrs:
|
|
attrs*: Table[string, Value]
|
|
of tList:
|
|
list*: seq[Value]
|
|
of tThunk: discard
|
|
of tApp: discard
|
|
of tLambda: discard
|
|
of tBlackhole: discard
|
|
of tPrimOp: discard
|
|
of tPrimOpApp: discard
|
|
of tExternal: discard
|
|
of tFloat:
|
|
fnum*: float
|
|
|
|
func `$`*(v: Value): string =
|
|
case v.kind:
|
|
of tInt:
|
|
result = $v.num
|
|
of tBool:
|
|
result = if v.boolean: "True" else: "False"
|
|
of tString:
|
|
result = "\"$1\"" % (v.str.replace("\"", "\\\""))
|
|
of tPath:
|
|
result = v.path
|
|
of tNull:
|
|
result = "null"
|
|
of tAttrs:
|
|
result = "{"
|
|
for key, val in v.attrs.pairs:
|
|
let key = if key.validIdentifier: key else: key.escape
|
|
result.add("$1=$2;" % [key, $val])
|
|
result.add "}"
|
|
of tList:
|
|
result = "[ "
|
|
for e in v.list:
|
|
result.add $e
|
|
result.add " "
|
|
result.add "]"
|
|
of tFloat:
|
|
result = $v.fnum
|
|
else:
|
|
result = $v.kind
|
|
|
|
func toNix*(x: Value): Value = x
|
|
|
|
func toNix*(x: SomeInteger): Value =
|
|
Value(kind: tInt, num: x)
|
|
|
|
func toNix*(x: bool): Value =
|
|
Value(kind: tBool, boolean: x)
|
|
|
|
func toNix*(x: string): Value =
|
|
Value(kind: tString, str: x)
|
|
|
|
func toPath*(x: string): Value =
|
|
Value(kind: tPath, path: x)
|
|
|
|
template toNix*(pairs: openArray[(string, Value)]): Value =
|
|
Value(kind: tAttrs, attrs: toTable pairs)
|
|
|
|
func toNix*(x: seq[Value]): Value =
|
|
Value(kind: tList, list: x)
|
|
|
|
template toNix*(x: seq[untyped]): Value =
|
|
map(x, toNix).toNix
|
|
|
|
func toNix*(x: openarray[Value]): Value =
|
|
Value(kind: tList, list: x[x.low .. x.high])
|
|
|
|
func toNix*(x: float): Value =
|
|
Value(kind: tFloat, fnum: x)
|
|
|
|
template `[]=`*(result: Value; key: string; val: untyped) =
|
|
result.attrs[key] = val.toNix
|
|
|
|
proc `[]`*(attrs: Value; key: string): Value =
|
|
attrs.attrs[key]
|
|
|
|
proc newNull*(): Value =
|
|
Value(kind: tNull)
|
|
|
|
proc newAttrs*(): Value =
|
|
Value(kind: tAttrs, attrs: initTable[string, Value]())
|
|
|
|
func newList*(): Value =
|
|
Value(kind: tList)
|
|
|
|
proc add*(x, y: Value) =
|
|
x.list.add y
|