Added some docs, LoadVar to the VM and readInt32
This commit is contained in:
parent
9c14bfae91
commit
396f40d3d6
|
@ -28,6 +28,7 @@ type
|
|||
cache: array[6, PeonObject] # Singletons cache
|
||||
chunk: Chunk # Piece of bytecode to execute
|
||||
frames: seq[int] # Stores the initial index of stack frames
|
||||
heapVars: seq[PeonObject] # Stores variables that do not have stack semantics (i.e. "static")
|
||||
|
||||
|
||||
proc initCache*(self: PeonVM) =
|
||||
|
@ -67,7 +68,10 @@ proc getInf*(self: PeonVM, positive: bool): PeonObject =
|
|||
|
||||
proc getNan*(self: PeonVM): PeonObject = self.cache[5]
|
||||
|
||||
## Stack primitives
|
||||
## Stack primitives. Note: all stack accessing that goes
|
||||
## through the get/set wrappers is frame-relative, meaning
|
||||
## that the index is added to the current stack frame's
|
||||
## bottom to obtain an absolute stack index.
|
||||
|
||||
proc push(self: PeonVM, obj: PeonObject) =
|
||||
## Pushes a Peon object onto the
|
||||
|
@ -83,7 +87,7 @@ proc pop(self: PeonVM): PeonObject =
|
|||
|
||||
|
||||
proc peek(self: PeonVM): PeonObject =
|
||||
## Returns the element at the top
|
||||
## Returns the Peon object at the top
|
||||
## of the stack without consuming
|
||||
## it
|
||||
return self.stack[^1]
|
||||
|
@ -168,6 +172,17 @@ proc readUInt32(self: PeonVM, idx: int): PeonObject =
|
|||
copyMem(result.uInt.addr, arr.addr, sizeof(arr))
|
||||
|
||||
|
||||
proc readInt32(self: PeonVM, idx: int): PeonObject =
|
||||
## Reads a constant from the
|
||||
## chunk's constant table and
|
||||
## returns a Peon object. Assumes
|
||||
## the constant is an Int32
|
||||
var arr = [self.chunk.consts[idx], self.chunk.consts[idx + 1],
|
||||
self.chunk.consts[idx + 2], self.chunk.consts[idx + 3]]
|
||||
result = PeonObject(kind: Int32)
|
||||
copyMem(result.`int`.addr, arr.addr, sizeof(arr))
|
||||
|
||||
|
||||
proc dispatch*(self: PeonVM) =
|
||||
## Main bytecode dispatch loop
|
||||
var instruction: OpCode
|
||||
|
@ -180,6 +195,7 @@ proc dispatch*(self: PeonVM) =
|
|||
echo &"Instruction: {instruction}"
|
||||
discard readLine stdin
|
||||
case instruction:
|
||||
# Constant loading
|
||||
of LoadTrue:
|
||||
self.push(self.getBool(true))
|
||||
of LoadFalse:
|
||||
|
@ -197,14 +213,20 @@ proc dispatch*(self: PeonVM) =
|
|||
of LoadUInt32:
|
||||
self.push(self.readUInt32(int(self.readLong())))
|
||||
of Call:
|
||||
# Calls a function. The calling convention for peon
|
||||
# functions is pretty simple: the return address sits
|
||||
# at the bottom of the stack frame, then follow the
|
||||
# arguments and all temporaries/local variables
|
||||
let newIp = self.readLong()
|
||||
# We do this because if we immediately changed
|
||||
# the instruction pointer, we'd read the wrong
|
||||
# value for the argument count. Storing it and
|
||||
# changing it later fixes this issue
|
||||
let newIp = self.readLong()
|
||||
self.frames.add(int(self.readLong()))
|
||||
self.ip = int(newIp)
|
||||
of OpCode.Return:
|
||||
# Returns from a void function or terminates the
|
||||
# program entirely if we're at the topmost frame
|
||||
if self.frames.len() > 1:
|
||||
let frame = self.frames.pop()
|
||||
for i in countdown(self.stack.high(), frame):
|
||||
|
@ -213,15 +235,23 @@ proc dispatch*(self: PeonVM) =
|
|||
else:
|
||||
return
|
||||
of ReturnValue:
|
||||
# Returns from a function which has a return value,
|
||||
# pushing it on the stack
|
||||
let retVal = self.pop()
|
||||
let frame = self.frames.pop()
|
||||
for i in countdown(self.stack.high(), frame):
|
||||
discard self.pop()
|
||||
self.ip = int(self.pop().uInt)
|
||||
self.push(retVal)
|
||||
of OpCode.StoreVar:
|
||||
of StoreVar:
|
||||
# Stores the value at the top of the stack
|
||||
# into the given stack index
|
||||
self.set(int(self.readLong()), self.pop())
|
||||
of OpCode.LoadVar:
|
||||
of StoreHeap:
|
||||
self.heapVars.add(self.pop())
|
||||
of LoadHeap:
|
||||
self.push(self.heapVars[self.readLong()])
|
||||
of LoadVar:
|
||||
self.push(self.get(int(self.readLong())))
|
||||
of NoOp:
|
||||
continue
|
||||
|
|
Loading…
Reference in New Issue