expand natives
This commit is contained in:
parent
9dc429c92d
commit
954d1e6de4
|
@ -1,6 +1,8 @@
|
|||
import io
|
||||
import typeutils
|
||||
import ndmath
|
||||
|
||||
proc constructStdlib* =
|
||||
constructIo()
|
||||
constructTypeutils()
|
||||
constructTypeutils()
|
||||
constructMath()
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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] = '}'
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue