expand natives

This commit is contained in:
prod2 2022-02-07 06:03:47 +01:00
parent 9dc429c92d
commit 954d1e6de4
6 changed files with 108 additions and 12 deletions

View File

@ -1,6 +1,8 @@
import io
import typeutils
import ndmath
proc constructStdlib* =
constructIo()
constructTypeutils()
constructTypeutils()
constructMath()

53
src/ndspkg/lib/ndmath.nim Normal file
View File

@ -0,0 +1,53 @@
import ../types/value
import ../types/native
import ../types/ndstring
import bitops
import math
import strformat
# vararg math funcs:
# 2 arg math funcs:
proc natPow(args: seq[NdValue], retval: var NdValue): NatReturn =
if args.len() != 2:
return natError(&"Power expects 2 arguments, got {args.len()}.")
let base = args[0]
let exp = args[1]
if base.isFloat() and exp.isFloat():
retval = base.asFloat().pow(exp.asFloat()).fromFloat();
return natOk
return natError(&"Power expects 2 numbers, however got {base.friendlyType()} and {exp.friendlyType()}.")
proc natMod(args: seq[NdValue], retval: var NdValue): NatReturn =
if args.len() != 2:
return natError(&"Mod expects 2 arguments, got {args.len()}.")
let base = args[0]
let exp = args[1]
if base.isFloat() and exp.isFloat():
let modulo = base.asFloat().int() mod exp.asFloat().int()
retval = modulo.float().fromFloat()
return natOk
return natError(&"Mod expects 2 numbers, however got {base.friendlyType()} and {exp.friendlyType()}.")
proc constructMath* =
# vararg funcs:
#defNative("min", natMin)
#defNative("max", natMax)
# 2 arg funcs:
defNative("pow", natPow)
defNative("mod", natMod)
# 1 arg funcs:
#defNative("ln", natLn)
#defNative("floor", natFloor)
#defNative("sin", natSin)
#defNative("cos", natCos)
#defNative("tan", natTan)
# 0 arg funcs:
#defNative("e", natE)
#defNative("pi", natPI)

View File

@ -2,6 +2,7 @@ import ../types/value
import ../types/native
import ../types/ndstring
import bitops
import strutils
proc natChar(args: seq[NdValue], retval: var NdValue): NatReturn =
if args.len() != 1:
@ -29,8 +30,37 @@ proc natByte(args: seq[NdValue], retval: var NdValue): NatReturn =
retval = byt.fromFloat()
return natOk
proc natType(args: seq[NdValue], retval: var NdValue): NatReturn =
if args.len() != 1:
return natError("Type expects 1 argument.")
let arg = args[0]
retval = arg.friendlyType().fromNimString()
return natOk
proc natToString(args: seq[NdValue], retval: var NdValue): NatReturn =
if args.len() != 1:
return natError("Type expects 1 argument.")
let arg = args[0]
retval = ($arg).fromNimString()
return natOk
proc natToNumber(args: seq[NdValue], retval: var NdValue): NatReturn =
if args.len() != 1:
return natError("Type expects 1 argument.")
let arg = args[0]
if not arg.isString():
return natError("Only strings can be converted to numbers.")
try:
retval = parseFloat($arg).fromFloat()
return natOk
except:
return natError("tonumber unsuccessful.")
proc constructTypeutils* =
defNative("char", natChar)
defNative("byte", natByte)
defNative("type", natType)
defNative("tostring", natToString)
defNative("tonumber", natToNumber)

View File

@ -137,21 +137,23 @@ proc tableDelete*[U, V](tbl: Table[U, V], key: U): bool =
entry[].entryStatus = esTombstone
return true
proc `$`*[U, V](tbl: NdTable[U, V]): string =
proc getLength*[U, V](tbl: NdTable[U, V]): int =
tbl.count.int
proc `$`*[U, V](tbl: NdTable[U, V], tagged: V): string =
if tbl[].count == 0:
return "@{}"
result = "@{ "
for i in countup(0, tbl.cap.int - 1):
let entry = tbl[].entries[i]
if entry.entryStatus == esAlive:
mixin `$`
result &= $entry.key
result &= " = "
result &= $entry.value
if entry.value == tagged:
result &= "self"
else:
result &= $entry.value
result &= ", "
result[^2] = ' '
result[^1] = '}'
proc getLength*[U, V](tbl: NdTable[U, V]): int =
tbl.count.int
result[^1] = '}'

View File

@ -162,13 +162,15 @@ proc `$`*(val: NdValue): string =
elif val.isFloat():
return $val.asFloat()
elif val.isFunct():
return &"Function object {(val).uint.toHex()}"
return &"Function {(val).uint.toHex()}"
elif val.isClosure():
return &"Closure object {(val).uint.toHex()}"
return &"Closure {(val).uint.toHex()}"
elif val.isNative():
return &"Native function {(val).uint.toHex()}"
elif val.isString():
return $val.asString()
elif val.isTable():
return $val.asTable()
return `$`(val.asTable(), val)
elif val.isList():
return $val.asList()
@ -193,6 +195,10 @@ proc friendlyType*(val: NdValue): string =
"table"
elif val.isList():
"list"
elif val.isClosure():
"closure"
elif val.isNative():
"native"
else:
"unknown"

View File

@ -135,6 +135,9 @@ proc run*(chunk: Chunk): InterpretResult =
let native = i.uint32.fromNative()
let name = nativeNames[i].fromNimString()
discard globals.tableSet(name, native)
let globalsKey = "_G".fromNimString()
let globalsVal = cast[NdTable[NdValue, NdValue]](globals.addr)
discard globals.tableSet(globalsKey, globalsVal.fromTable())
while true:
{.computedgoto.} # See https://nim-lang.org/docs/manual.html#pragmas-computedgoto-pragma