Fixed bug with globals and hoisted global declarations

This commit is contained in:
Mattia Giambirtone 2023-03-27 19:08:58 +02:00
parent 3e9b84fb4f
commit a7899e8473
Signed by: nocturn9x
GPG Key ID: 8270F9F467971E59
3 changed files with 25 additions and 9 deletions

View File

@ -822,9 +822,13 @@ proc dispatch*(self: var PeonVM) =
# not a great idea)
self.pushc(self.pop())
of LoadVar:
# Pushes a variable from the call stack
# Pushes a local variable from the call stack
# onto the operand stack
self.push(self.getc(self.readLong().int))
of LoadGlobal:
# Pushes a global variable from the call stack
# onto the operand stack
self.push(self.calls[self.readLong().int])
of NoOp:
# Does nothing
continue

View File

@ -189,7 +189,8 @@ type
SysClock64, # Pushes the output of a monotonic clock on the stack
LoadTOS, # Pushes the top of the call stack onto the operand stack
DupTop, # Duplicates the top of the operand stack onto the operand stack
ReplExit # Exits the VM immediately, leaving its state intact. Used in the REPL
ReplExit, # Exits the VM immediately, leaving its state intact. Used in the REPL
LoadGlobal # Loads a global variable
# We group instructions by their operation/operand types for easier handling when debugging
@ -282,7 +283,7 @@ const constantInstructions* = {LoadInt64, LoadUInt64,
# Stack triple instructions operate on the stack at arbitrary offsets and pop arguments off of it in the form
# of 24 bit integers
const stackTripleInstructions* = {StoreVar, LoadVar, }
const stackTripleInstructions* = {StoreVar, LoadVar, LoadGlobal}
# Stack double instructions operate on the stack at arbitrary offsets and pop arguments off of it in the form
# of 16 bit integers

View File

@ -95,7 +95,7 @@ proc compile*(self: BytecodeCompiler, ast: seq[Declaration], file: string, lines
mode: CompileMode = Debug): Chunk
proc statement(self: BytecodeCompiler, node: Statement)
proc declaration(self: BytecodeCompiler, node: Declaration)
proc varDecl(self: BytecodeCompiler, node: VarDecl)
proc varDecl(self: BytecodeCompiler, node: VarDecl, hoist: bool = false)
proc specialize(self: BytecodeCompiler, typ: Type, args: seq[Expression]): Type {.discardable.}
proc patchReturnAddress(self: BytecodeCompiler, pos: int)
proc handleMagicPragma(self: BytecodeCompiler, pragma: Pragma, name: Name)
@ -1233,10 +1233,14 @@ method identifier(self: BytecodeCompiler, node: IdentExpr, name: Name = nil, com
if not s.belongsTo.isNil() and s.belongsTo.valueType.fun.kind == funDecl and FunDecl(s.belongsTo.valueType.fun).isTemplate:
discard
else:
# Loads a regular variable from the current frame
self.emitByte(LoadVar, s.ident.token.line)
# No need to check for -1 here: we already did a nil check above!
self.emitBytes(s.position.toTriple(), s.ident.token.line)
if s.depth > 0:
# Loads a regular variable from the current frame
self.emitByte(LoadVar, s.ident.token.line)
# No need to check for -1 here: we already did a nil check above!
self.emitBytes(s.position.toTriple(), s.ident.token.line)
else:
self.emitByte(LoadGlobal, s.ident.token.line)
self.emitBytes(s.position.toTriple(), s.ident.token.line)
method assignment(self: BytecodeCompiler, node: ASTNode, compile: bool = true): Type {.discardable.} =
@ -1860,8 +1864,10 @@ proc statement(self: BytecodeCompiler, node: Statement) =
self.expression(Expression(node))
proc varDecl(self: BytecodeCompiler, node: VarDecl) =
proc varDecl(self: BytecodeCompiler, node: VarDecl, hoist: bool = false) =
## Compiles variable declarations
if node.name.depth == 0 and not hoist:
return
var typ: Type
# Our parser guarantees that the variable declaration
# will have a type declaration or a value (or both)
@ -2071,6 +2077,11 @@ proc compile*(self: BytecodeCompiler, ast: seq[Declaration], file: string, lines
if not incremental:
self.jumps = @[]
let pos = self.beginProgram()
let idx = self.stackIndex
for node in ast:
if node.kind == varDecl and VarDecl(node).name.depth == 0:
self.varDecl(VarDecl(node), hoist=true)
self.stackIndex = idx
while not self.done():
self.declaration(Declaration(self.step()))
self.terminateProgram(pos)