WIP switch to custom hashtable for globals
This commit is contained in:
parent
2765daa55b
commit
31b0b28dca
|
@ -1,7 +1,7 @@
|
|||
import strformat
|
||||
import strutils
|
||||
|
||||
import value
|
||||
import types/value
|
||||
|
||||
type
|
||||
OpCode* = enum
|
||||
|
|
|
@ -6,7 +6,7 @@ import options
|
|||
|
||||
import scanner
|
||||
import chunk
|
||||
import value
|
||||
import types/value
|
||||
import bitops # needed for value
|
||||
import config
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ type
|
|||
proc free*(ndStr: var NdString) =
|
||||
dealloc(ndStr)
|
||||
|
||||
# for hashtable:
|
||||
# hashes
|
||||
|
||||
proc fnv1a*(ndStr: NdString): int =
|
||||
var hash = 2166136261'u32
|
||||
|
@ -17,5 +17,7 @@ proc fnv1a*(ndStr: NdString): int =
|
|||
hash *= 16777619
|
||||
return hash.int
|
||||
|
||||
# equals
|
||||
|
||||
proc equal*(left, right: NdString): bool =
|
||||
left == right
|
||||
left == right
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import strformat
|
||||
import bitops
|
||||
|
||||
import types/ndstring
|
||||
import types/stringutils
|
||||
import ndstring
|
||||
import stringutils
|
||||
|
||||
type
|
||||
NdValue* = uint
|
||||
|
@ -107,11 +107,6 @@ proc isFalsey*(val: NdValue): bool =
|
|||
template isTruthy*(val: NdValue): bool =
|
||||
not val.isFalsey()
|
||||
|
||||
proc equal*(val, right: NdValue): bool =
|
||||
if val.isFloat() and right.isFloat():
|
||||
val.asFloat() == right.asFloat()
|
||||
else:
|
||||
val == right
|
||||
|
||||
proc friendlyType*(val: NdValue): string =
|
||||
if val == ndNil:
|
||||
|
@ -186,3 +181,20 @@ proc greater*(val: var NdValue, right: NdValue): NatReturn {.inline.} =
|
|||
else:
|
||||
return natError(&"Attempt to compare types {val.friendlyType()} and {right.friendlyType()}.")
|
||||
return natOk
|
||||
|
||||
# for hashtables
|
||||
|
||||
proc fnv1a*(ndval: NdValue): int =
|
||||
var hash = 2166136261'u32
|
||||
var val = ndval
|
||||
for i in countup(0, 7):
|
||||
hash = hash xor val.uint8.uint32
|
||||
hash *= 16777619
|
||||
val = val shr 8
|
||||
return hash.int
|
||||
|
||||
proc equal*(val, right: NdValue): bool =
|
||||
if val.isFloat() and right.isFloat():
|
||||
val.asFloat() == right.asFloat()
|
||||
else:
|
||||
val == right
|
41
vm.nim
41
vm.nim
|
@ -1,8 +1,5 @@
|
|||
import strformat
|
||||
import tables
|
||||
|
||||
import value
|
||||
import bitops # needed for value's templates
|
||||
#import tables
|
||||
|
||||
import chunk
|
||||
import config
|
||||
|
@ -11,6 +8,9 @@ import pointerutils
|
|||
import types/stack
|
||||
import types/ndstring
|
||||
import types/stringutils
|
||||
import bitops # needed for value's templates
|
||||
import types/value
|
||||
import types/hashtable
|
||||
|
||||
|
||||
when profileInstructions:
|
||||
|
@ -37,7 +37,8 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
ip: ptr uint8 = chunk.code[0].unsafeAddr
|
||||
stack: Stack[NdValue] = newStack[NdValue](256)
|
||||
hadError: bool
|
||||
globals: Table[string, NdValue]
|
||||
#globals: Table[string, NdValue]
|
||||
globals: Table[NdValue, NdValue]
|
||||
frames: Stack[Frame] = newStack[Frame](4)
|
||||
|
||||
proc runtimeError(msg: string) =
|
||||
|
@ -48,12 +49,6 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
|
||||
frames.add(Frame(stackBottom: 0))
|
||||
|
||||
#template peek(stack: seq[NdValue]): NdValue =
|
||||
# stack[stack.high]
|
||||
|
||||
#proc popn(stack: var seq[NdValue], amt: int) {.inline.} =
|
||||
# for i in countup(1, amt):
|
||||
# discard stack.pop()
|
||||
template popn(stack: var Stack[NdValue], amt: int) =
|
||||
stack.deleteTopN(amt)
|
||||
|
||||
|
@ -167,25 +162,25 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
of opPrint:
|
||||
echo $stack.peek()
|
||||
of opDefineGlobal:
|
||||
let name = $readConstant().asString()
|
||||
if not globals.hasKey(name):
|
||||
globals[name] = stack.pop()
|
||||
else:
|
||||
let name = readConstant().asString()
|
||||
let existed = globals.tableSet(name.fromNdString(), stack.pop())
|
||||
if existed:
|
||||
runtimeError("Attempt to redefine an existing global variable.")
|
||||
break
|
||||
of opGetGlobal:
|
||||
let name = $readConstant().asString()
|
||||
if globals.hasKey(name):
|
||||
stack.add(globals[name])
|
||||
let name = readConstant().asString()
|
||||
var val: NdValue
|
||||
let existed = globals.tableGet(name, val)
|
||||
if existed:
|
||||
stack.add(val)
|
||||
else:
|
||||
runtimeError(&"Undefined global variable {name}.")
|
||||
break
|
||||
of opSetGlobal:
|
||||
let name = $readConstant().asString()
|
||||
if globals.hasKey(name):
|
||||
globals[name] = stack.peek()
|
||||
else:
|
||||
runtimeError(&"Attempt to set undefined global variable {name}.")
|
||||
let name = readConstant().asString()
|
||||
let existed = globals.tableSet(name, stack.pop())
|
||||
if not existed:
|
||||
runtimeError("Attempt to redefine an existing global variable.")
|
||||
break
|
||||
of opGetLocal:
|
||||
let slot = readDU8()
|
||||
|
|
Loading…
Reference in New Issue