nondescript/value.nim

141 lines
3.9 KiB
Nim
Raw Normal View History

2022-01-20 21:54:11 +01:00
import strformat
type
2022-01-27 05:37:10 +01:00
NdType* = enum
ndNil, ndBool, ndFloat, ndString,
ndFunct,
2022-01-20 21:54:11 +01:00
type
2022-01-27 05:37:10 +01:00
NdValue* = object
case ndType*: NdType:
of ndNil:
2022-01-20 21:54:11 +01:00
discard
2022-01-27 05:37:10 +01:00
of ndBool:
2022-01-20 21:54:11 +01:00
boolValue*: bool
2022-01-27 05:37:10 +01:00
of ndFloat:
2022-01-20 21:54:11 +01:00
floatValue*: float64
2022-01-27 05:37:10 +01:00
of ndString:
2022-01-20 21:54:11 +01:00
stringValue*: string
2022-01-27 05:37:10 +01:00
of ndFunct:
2022-01-27 05:56:09 +01:00
placeholder*: string
2022-01-21 00:18:58 +01:00
entryII*: int # entry instruction index
NatReturn* = object
ok*: bool
msg*: string
2022-01-20 21:54:11 +01:00
# KON VALUE HELPERS, MUST BE DEFINED FOR EVERY KONVALUE
2022-01-27 05:37:10 +01:00
proc `$`*(val: NdValue): string =
case val.ndType:
of ndFloat:
2022-01-20 21:54:11 +01:00
return $val.floatValue
2022-01-27 05:37:10 +01:00
of ndBool:
2022-01-20 21:54:11 +01:00
return $val.boolValue
2022-01-27 05:37:10 +01:00
of ndNil:
2022-01-20 21:54:11 +01:00
return "nil"
2022-01-27 05:37:10 +01:00
of ndString:
2022-01-20 21:54:11 +01:00
return val.stringValue
2022-01-27 05:37:10 +01:00
of ndFunct:
2022-01-22 17:28:53 +01:00
return &"Function object: {val.entryII}"
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc isFalsey*(val: NdValue): bool =
val.ndType in {ndNil} or (val.ndType == ndBool and not val.boolValue)
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
template isTruthy*(val: NdValue): bool =
2022-01-20 21:54:11 +01:00
not isFalsey(val)
2022-01-27 05:37:10 +01:00
proc equal*(val, right: NdValue): bool =
if val.ndType != right.ndType:
2022-01-20 21:54:11 +01:00
false
else:
2022-01-27 05:37:10 +01:00
case val.ndType:
of ndFloat:
2022-01-20 21:54:11 +01:00
val.floatValue == right.floatValue
2022-01-27 05:37:10 +01:00
of ndBool:
2022-01-20 21:54:11 +01:00
val.boolValue == right.boolValue
2022-01-27 05:37:10 +01:00
of ndNil:
2022-01-20 21:54:11 +01:00
true
2022-01-27 05:37:10 +01:00
of ndString:
2022-01-20 21:54:11 +01:00
val.stringValue == right.stringValue
2022-01-27 05:37:10 +01:00
of ndFunct:
2022-01-22 17:28:53 +01:00
val.entryII == right.entryII
2022-01-20 21:54:11 +01:00
# NIM VALUE TO KON VALUE WRAPPERS
2022-01-27 05:37:10 +01:00
proc toNdValue*(val: float): NdValue =
NdValue(ndType: ndFloat, floatValue: val)
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc toNdValue*(val: bool): NdValue =
NdValue(ndType: ndBool, boolValue: val)
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc toNdValue*(val: string): NdValue =
NdValue(ndType: ndString, stringValue: val)
2022-01-20 21:54:11 +01:00
2022-01-27 05:56:09 +01:00
proc newNdFunction*(ii: int): NdValue =
NdValue(ndType: ndFunct, entryII: ii)
2022-01-21 01:51:55 +01:00
2022-01-27 05:37:10 +01:00
proc toNdValue*: NdValue =
NdValue(ndType: ndNil)
2022-01-20 21:54:11 +01:00
# NatReturn misc
proc natError*(msg: string): NatReturn {.inline.} =
NatReturn(ok: false, msg: msg)
const natOk* = NatReturn(ok: true)
2022-01-20 21:54:11 +01:00
# OPERATIONS
# NOTE: these operations can return ktTypeError with a message if types are invalid
2022-01-27 05:37:10 +01:00
proc negate*(val: var NdValue): NatReturn {.inline.} =
if (val.ndType != ndFloat):
return natError("Operand must be a number.")
2022-01-20 21:54:11 +01:00
else:
val.floatValue = -val.floatValue
return natOk
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc add*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
if val.ndType == ndFloat and right.ndType == ndFloat:
val.floatValue += right.floatValue
2022-01-27 05:37:10 +01:00
elif val.ndType == ndString and right.ndType == ndString:
val.stringValue &= right.stringValue
2022-01-20 21:54:11 +01:00
else:
2022-01-27 05:37:10 +01:00
return natError(&"Attempt to add types {val.ndType} and {right.ndType}.")
return natOk
2022-01-27 05:37:10 +01:00
proc subtract*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
if val.ndType == ndFloat and right.ndType == ndFloat:
val.floatValue -= right.floatValue
2022-01-20 21:54:11 +01:00
else:
2022-01-27 05:37:10 +01:00
return natError(&"Attempt to subtract types {val.ndType} and {right.ndType}.")
return natOk
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc multiply*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
if val.ndType == ndFloat and right.ndType == ndFloat:
val.floatValue *= right.floatValue
2022-01-20 21:54:11 +01:00
else:
2022-01-27 05:37:10 +01:00
return natError(&"Attempt to multiply types {val.ndType} and {right.ndType}.")
return natOk
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc divide*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
if val.ndType == ndFloat and right.ndType == ndFloat:
val.floatValue /= right.floatValue
2022-01-20 21:54:11 +01:00
else:
2022-01-27 05:37:10 +01:00
return natError(&"Attempt to divide types {val.ndType} and {right.ndType}.")
return natOk
2022-01-20 21:54:11 +01:00
proc less*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
2022-01-27 05:37:10 +01:00
if val.ndType == ndFloat and right.ndType == ndFloat:
val = toNdValue(val.floatValue < right.floatValue)
2022-01-20 21:54:11 +01:00
else:
return natError(&"Attempt to compare types {val.ndType} and {right.ndType}.")
return natOk
2022-01-20 21:54:11 +01:00
proc greater*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
2022-01-27 05:37:10 +01:00
if val.ndType == ndFloat and right.ndType == ndFloat:
val = toNdValue(val.floatValue > right.floatValue)
2022-01-20 21:54:11 +01:00
else:
return natError(&"Attempt to compare types {val.ndType} and {right.ndType}.")
return natOk