replaced seq with a custom stack object for performance
This commit is contained in:
parent
01de21e32e
commit
90d04f13f6
|
@ -5,5 +5,8 @@ template padd*[T](x: ptr T, num: int): ptr T =
|
|||
template psub*[T](x: ptr T, num: int): ptr T =
|
||||
cast[ptr T](cast[int](x) - num)
|
||||
|
||||
template pdiff*[T](x: ptr T, y: ptr): int =
|
||||
cast[int](x) - cast[int](y)
|
||||
template pdiff*[T](x: ptr T, y: ptr T): int =
|
||||
cast[int](x) - cast[int](y)
|
||||
|
||||
template pless*[T](x: ptr T, y: ptr T): bool =
|
||||
cast[uint](x) < cast[uint](y)
|
|
@ -178,13 +178,10 @@ proc scanToken*(scanner: Scanner): Token =
|
|||
of '*': return scanner.makeToken(tkStar)
|
||||
of '!':
|
||||
return if scanner.match('='): scanner.makeToken(tkBangEqual) else: scanner.makeToken(tkBang)
|
||||
|
||||
of '=':
|
||||
return if scanner.match('='): scanner.makeToken(tkEqualEqual) else: scanner.makeToken(tkEqual)
|
||||
|
||||
of '<':
|
||||
return if scanner.match('='): scanner.makeToken(tkLessEqual) else: scanner.makeToken(tkLess)
|
||||
|
||||
of '>':
|
||||
return if scanner.match('='): scanner.makeToken(tkGreaterEqual) else: scanner.makeToken(tkGreater)
|
||||
of '\"':
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
import ../pointerutils
|
||||
|
||||
# configure stacks here
|
||||
const boundsChecks = false
|
||||
const growthFactor = 2
|
||||
|
||||
type
|
||||
Stack*[T] = object
|
||||
top: ptr T
|
||||
start: ptr T
|
||||
cap: int
|
||||
|
||||
proc newStack*[T](startingCap: int): Stack[T] =
|
||||
result.start = cast[ptr T](alloc(startingCap * sizeof(T)))
|
||||
result.top = result.start.psub(sizeof(T))
|
||||
result.cap = startingCap
|
||||
|
||||
proc destroyStack*[T](stack: var Stack[T]) =
|
||||
## dealloc's the stack object
|
||||
## if the stack contains pointers, those should be freed before destroying the stack
|
||||
stack.cap = 0
|
||||
stack.start.dealloc()
|
||||
stack.start = nil
|
||||
stack.top = nil
|
||||
|
||||
proc grow[T](stack: var Stack[T], len: int) {.inline.} =
|
||||
## growth the stack's capacity and increments the top's index by one
|
||||
stack.start = cast[ptr T](realloc(stack.start, stack.cap * growthFactor))
|
||||
stack.cap *= growthFactor
|
||||
stack.top = stack.start.padd(len * sizeof(T))
|
||||
|
||||
proc shrink[T](stack: var Stack[T]) {.inline.} =
|
||||
discard
|
||||
|
||||
template high*[T](stack: Stack[T]): int =
|
||||
stack.top.pdiff(stack.start) div sizeof(T)
|
||||
|
||||
template len*[T](stack: Stack[T]): int =
|
||||
stack.high() + 1
|
||||
|
||||
proc push*[T](stack: var Stack[T], item: T) {.inline.} =
|
||||
let len = stack.len()
|
||||
if len == stack.cap:
|
||||
stack.grow(len)
|
||||
else:
|
||||
stack.top = stack.top.padd(sizeof(T))
|
||||
stack.top[]= item
|
||||
|
||||
template add*[T](stack: var Stack[T], item: T) =
|
||||
stack.push(item)
|
||||
|
||||
proc pop*[T](stack: var Stack[T]): T {.inline.} =
|
||||
when boundsChecks:
|
||||
if stack.top == nil or stack.top.pless(stack.start):
|
||||
raise newException(Defect, "Stacktop is nil or smaller than start.")
|
||||
result = stack.top[]
|
||||
stack.top = stack.top.psub(sizeof(T))
|
||||
|
||||
proc peek*[T](stack: Stack[T]): var T {.inline.} =
|
||||
stack.top[]
|
||||
|
||||
proc deleteTopN*[T](stack: var Stack[T], n: Natural) =
|
||||
stack.top = stack.top.psub(sizeof(T) * n)
|
||||
when boundsChecks:
|
||||
if stack.top.pless(stack.start):
|
||||
raise newException(Defect, "Stacktop sunk below the start after a deleteTopN.")
|
||||
|
||||
proc getIndex*[T](stack: Stack[T], index: int): T =
|
||||
when boundsChecks:
|
||||
if index < 0 or index >= stack.len():
|
||||
raise newException(Defect, "Attempt to getIndex with an index out of bounds.")
|
||||
stack.start.padd(index * sizeof(T))[]
|
||||
|
||||
template `[]`*[T](stack: Stack[T], index: int): T =
|
||||
stack.getIndex(index)
|
||||
|
||||
proc setIndex*[T](stack: var Stack[T], index: int, item: T) =
|
||||
when boundsChecks:
|
||||
if index < 0 or index >= stack.len():
|
||||
raise newException(Defect, "Attempt to getIndex with an index out of bounds.")
|
||||
stack.start.padd(index * sizeof(T))[]= item
|
||||
|
||||
template `[]=`*[T](stack: var Stack[T], index: int, item: T) =
|
||||
stack.setIndex(index, item)
|
20
vm.nim
20
vm.nim
|
@ -6,6 +6,8 @@ import chunk
|
|||
import config
|
||||
import pointerutils
|
||||
|
||||
import types/stack
|
||||
|
||||
when profileInstructions:
|
||||
import times
|
||||
import std/monotimes
|
||||
|
@ -28,7 +30,8 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
|
||||
var
|
||||
ip: ptr uint8 = chunk.code[0].unsafeAddr
|
||||
stack: seq[NdValue] = newSeqOfCap[NdValue](256)
|
||||
#stack: seq[NdValue] = newSeqOfCap[NdValue](256)
|
||||
stack: Stack[NdValue] = newStack[NdValue](256)
|
||||
hadError: bool
|
||||
globals: Table[string, NdValue]
|
||||
frames: seq[Frame] = newSeqOfCap[Frame](4)
|
||||
|
@ -39,12 +42,14 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
write stderr, &"[line: {line}] {msg}\n"
|
||||
hadError = true
|
||||
|
||||
template peek(stack: seq[NdValue]): NdValue =
|
||||
stack[stack.high]
|
||||
#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()
|
||||
#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)
|
||||
|
||||
proc readUI8(): int =
|
||||
result = ip[].int
|
||||
|
@ -58,7 +63,6 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
let index = readDU8()
|
||||
chunk.constants[index]
|
||||
|
||||
|
||||
template frameBottom: int = frames[frames.high].stackBottom
|
||||
|
||||
while true:
|
||||
|
@ -72,7 +76,7 @@ proc run*(chunk: Chunk): InterpretResult =
|
|||
let opname = ($ins)
|
||||
var msg = &"[{ii:4}] {opname}"
|
||||
msg &= " Stack: [ "
|
||||
for i in 0 .. stack.high:
|
||||
for i in 0 .. stack.high():
|
||||
let e = stack[i]
|
||||
if i == frameBottom:
|
||||
msg &= &"<{e}> "
|
||||
|
|
Loading…
Reference in New Issue