expand natives
This commit is contained in:
parent
9dc429c92d
commit
954d1e6de4
|
@ -1,6 +1,8 @@
|
||||||
import io
|
import io
|
||||||
import typeutils
|
import typeutils
|
||||||
|
import ndmath
|
||||||
|
|
||||||
proc constructStdlib* =
|
proc constructStdlib* =
|
||||||
constructIo()
|
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/native
|
||||||
import ../types/ndstring
|
import ../types/ndstring
|
||||||
import bitops
|
import bitops
|
||||||
|
import strutils
|
||||||
|
|
||||||
proc natChar(args: seq[NdValue], retval: var NdValue): NatReturn =
|
proc natChar(args: seq[NdValue], retval: var NdValue): NatReturn =
|
||||||
if args.len() != 1:
|
if args.len() != 1:
|
||||||
|
@ -29,8 +30,37 @@ proc natByte(args: seq[NdValue], retval: var NdValue): NatReturn =
|
||||||
retval = byt.fromFloat()
|
retval = byt.fromFloat()
|
||||||
return natOk
|
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* =
|
proc constructTypeutils* =
|
||||||
defNative("char", natChar)
|
defNative("char", natChar)
|
||||||
defNative("byte", natByte)
|
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
|
entry[].entryStatus = esTombstone
|
||||||
return true
|
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:
|
if tbl[].count == 0:
|
||||||
return "@{}"
|
return "@{}"
|
||||||
result = "@{ "
|
result = "@{ "
|
||||||
for i in countup(0, tbl.cap.int - 1):
|
for i in countup(0, tbl.cap.int - 1):
|
||||||
let entry = tbl[].entries[i]
|
let entry = tbl[].entries[i]
|
||||||
if entry.entryStatus == esAlive:
|
if entry.entryStatus == esAlive:
|
||||||
mixin `$`
|
|
||||||
result &= $entry.key
|
result &= $entry.key
|
||||||
result &= " = "
|
result &= " = "
|
||||||
result &= $entry.value
|
if entry.value == tagged:
|
||||||
|
result &= "self"
|
||||||
|
else:
|
||||||
|
result &= $entry.value
|
||||||
result &= ", "
|
result &= ", "
|
||||||
result[^2] = ' '
|
result[^2] = ' '
|
||||||
result[^1] = '}'
|
result[^1] = '}'
|
||||||
|
|
||||||
proc getLength*[U, V](tbl: NdTable[U, V]): int =
|
|
||||||
tbl.count.int
|
|
|
@ -162,13 +162,15 @@ proc `$`*(val: NdValue): string =
|
||||||
elif val.isFloat():
|
elif val.isFloat():
|
||||||
return $val.asFloat()
|
return $val.asFloat()
|
||||||
elif val.isFunct():
|
elif val.isFunct():
|
||||||
return &"Function object {(val).uint.toHex()}"
|
return &"Function {(val).uint.toHex()}"
|
||||||
elif val.isClosure():
|
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():
|
elif val.isString():
|
||||||
return $val.asString()
|
return $val.asString()
|
||||||
elif val.isTable():
|
elif val.isTable():
|
||||||
return $val.asTable()
|
return `$`(val.asTable(), val)
|
||||||
elif val.isList():
|
elif val.isList():
|
||||||
return $val.asList()
|
return $val.asList()
|
||||||
|
|
||||||
|
@ -193,6 +195,10 @@ proc friendlyType*(val: NdValue): string =
|
||||||
"table"
|
"table"
|
||||||
elif val.isList():
|
elif val.isList():
|
||||||
"list"
|
"list"
|
||||||
|
elif val.isClosure():
|
||||||
|
"closure"
|
||||||
|
elif val.isNative():
|
||||||
|
"native"
|
||||||
else:
|
else:
|
||||||
"unknown"
|
"unknown"
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,9 @@ proc run*(chunk: Chunk): InterpretResult =
|
||||||
let native = i.uint32.fromNative()
|
let native = i.uint32.fromNative()
|
||||||
let name = nativeNames[i].fromNimString()
|
let name = nativeNames[i].fromNimString()
|
||||||
discard globals.tableSet(name, native)
|
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:
|
while true:
|
||||||
{.computedgoto.} # See https://nim-lang.org/docs/manual.html#pragmas-computedgoto-pragma
|
{.computedgoto.} # See https://nim-lang.org/docs/manual.html#pragmas-computedgoto-pragma
|
||||||
|
|
Loading…
Reference in New Issue