nondescript/value.nim

142 lines
4.0 KiB
Nim
Raw Normal View History

2022-01-20 21:54:11 +01:00
import strformat
2022-01-28 04:17:11 +01:00
import types/ndstring
2022-01-20 21:54:11 +01:00
type
2022-01-27 05:37:10 +01:00
NdType* = enum
2022-01-28 04:17:11 +01:00
ntNil, ntBool, ntFloat, ntString,
ntFunct,
2022-01-20 21:54:11 +01:00
type
2022-01-27 05:37:10 +01:00
NdValue* = object
case ndType*: NdType:
2022-01-28 04:17:11 +01:00
of ntNil:
2022-01-20 21:54:11 +01:00
discard
2022-01-28 04:17:11 +01:00
of ntBool:
2022-01-20 21:54:11 +01:00
boolValue*: bool
2022-01-28 04:17:11 +01:00
of ntFloat:
2022-01-20 21:54:11 +01:00
floatValue*: float64
2022-01-28 04:17:11 +01:00
of ntString:
stringValue*: NdString
of ntFunct:
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:
2022-01-28 04:17:11 +01:00
of ntFloat:
2022-01-20 21:54:11 +01:00
return $val.floatValue
2022-01-28 04:17:11 +01:00
of ntBool:
2022-01-20 21:54:11 +01:00
return $val.boolValue
2022-01-28 04:17:11 +01:00
of ntNil:
2022-01-20 21:54:11 +01:00
return "nil"
2022-01-28 04:17:11 +01:00
of ntString:
return $val.stringValue
of ntFunct:
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 =
2022-01-28 04:17:11 +01:00
val.ndType in {ntNil} or (val.ndType == ntBool 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:
2022-01-28 04:17:11 +01:00
of ntFloat:
2022-01-20 21:54:11 +01:00
val.floatValue == right.floatValue
2022-01-28 04:17:11 +01:00
of ntBool:
2022-01-20 21:54:11 +01:00
val.boolValue == right.boolValue
2022-01-28 04:17:11 +01:00
of ntNil:
2022-01-20 21:54:11 +01:00
true
2022-01-28 04:17:11 +01:00
of ntString:
2022-01-28 22:00:21 +01:00
# TODO this was meant for nim strings, not ndStrings, FIXME!
2022-01-20 21:54:11 +01:00
val.stringValue == right.stringValue
2022-01-28 04:17:11 +01:00
of ntFunct:
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 =
2022-01-28 04:17:11 +01:00
NdValue(ndType: ntFloat, floatValue: val)
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc toNdValue*(val: bool): NdValue =
2022-01-28 04:17:11 +01:00
NdValue(ndType: ntBool, boolValue: val)
2022-01-20 21:54:11 +01:00
2022-01-27 05:37:10 +01:00
proc toNdValue*(val: string): NdValue =
2022-01-28 04:17:11 +01:00
NdValue(ndType: ntString, stringValue: val.newString())
2022-01-20 21:54:11 +01:00
2022-01-27 05:56:09 +01:00
proc newNdFunction*(ii: int): NdValue =
2022-01-28 04:17:11 +01:00
NdValue(ndType: ntFunct, entryII: ii)
2022-01-21 01:51:55 +01:00
2022-01-27 05:37:10 +01:00
proc toNdValue*: NdValue =
2022-01-28 04:17:11 +01:00
NdValue(ndType: ntNil)
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.} =
2022-01-28 04:17:11 +01:00
if (val.ndType != ntFloat):
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.} =
2022-01-28 04:17:11 +01:00
if val.ndType == ntFloat and right.ndType == ntFloat:
val.floatValue += right.floatValue
2022-01-28 04:17:11 +01:00
elif val.ndType == ntString and right.ndType == ntString:
val.stringValue = 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.} =
2022-01-28 04:17:11 +01:00
if val.ndType == ntFloat and right.ndType == ntFloat:
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.} =
2022-01-28 04:17:11 +01:00
if val.ndType == ntFloat and right.ndType == ntFloat:
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.} =
2022-01-28 04:17:11 +01:00
if val.ndType == ntFloat and right.ndType == ntFloat:
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-28 04:17:11 +01:00
if val.ndType == ntFloat and right.ndType == ntFloat:
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-28 04:17:11 +01:00
if val.ndType == ntFloat and right.ndType == ntFloat:
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