Fixed issues with stack frames when returning from functions
This commit is contained in:
parent
e15b6a4915
commit
0f0a442578
|
@ -239,7 +239,7 @@ proc dispatch*(self: PeonVM) =
|
||||||
# pushing it on the stack
|
# pushing it on the stack
|
||||||
let retVal = self.pop()
|
let retVal = self.pop()
|
||||||
let frame = self.frames.pop()
|
let frame = self.frames.pop()
|
||||||
for i in countdown(0, frame):
|
for i in countdown(frame, 1):
|
||||||
discard self.pop()
|
discard self.pop()
|
||||||
self.ip = int(self.pop().uInt)
|
self.ip = int(self.pop().uInt)
|
||||||
self.push(retVal)
|
self.push(retVal)
|
||||||
|
|
|
@ -27,7 +27,7 @@ when len(PEON_COMMIT_HASH) != 40:
|
||||||
const PEON_BRANCH* = "master"
|
const PEON_BRANCH* = "master"
|
||||||
when len(PEON_BRANCH) > 255:
|
when len(PEON_BRANCH) > 255:
|
||||||
{.fatal: "The git branch name's length must be less than or equal to 255 characters".}
|
{.fatal: "The git branch name's length must be less than or equal to 255 characters".}
|
||||||
const DEBUG_TRACE_VM* = false # Traces VM execution
|
const DEBUG_TRACE_VM* = true # Traces VM execution
|
||||||
const DEBUG_TRACE_GC* = false # Traces the garbage collector (TODO)
|
const DEBUG_TRACE_GC* = false # Traces the garbage collector (TODO)
|
||||||
const DEBUG_TRACE_ALLOCATION* = false # Traces memory allocation/deallocation
|
const DEBUG_TRACE_ALLOCATION* = false # Traces memory allocation/deallocation
|
||||||
const DEBUG_TRACE_COMPILER* = false # Traces the compiler
|
const DEBUG_TRACE_COMPILER* = false # Traces the compiler
|
||||||
|
|
|
@ -940,12 +940,14 @@ proc identifier(self: Compiler, node: IdentExpr) =
|
||||||
else:
|
else:
|
||||||
self.detectClosureVariable(s.name)
|
self.detectClosureVariable(s.name)
|
||||||
let t = self.getStackPos(node)
|
let t = self.getStackPos(node)
|
||||||
let index = t.pos
|
var index = t.pos
|
||||||
# We don't check if index is -1 because if it
|
# We don't check if index is -1 because if it
|
||||||
# were, self.resolve() would have returned nil
|
# were, self.resolve() would have returned nil
|
||||||
if not t.closedOver:
|
if not t.closedOver:
|
||||||
# Static name resolution, loads value at index in the stack. Very fast. Much wow.
|
# Static name resolution, loads value at index in the stack. Very fast. Much wow.
|
||||||
self.emitByte(LoadVar)
|
self.emitByte(LoadVar)
|
||||||
|
if self.scopeDepth > 0:
|
||||||
|
inc(index) # Skip the return address!
|
||||||
self.emitBytes((index - self.frames[self.scopeDepth]).toTriple())
|
self.emitBytes((index - self.frames[self.scopeDepth]).toTriple())
|
||||||
else:
|
else:
|
||||||
if self.closedOver.len() == 0:
|
if self.closedOver.len() == 0:
|
||||||
|
|
26
src/main.nim
26
src/main.nim
|
@ -3,6 +3,8 @@ import strformat
|
||||||
import strutils
|
import strutils
|
||||||
import terminal
|
import terminal
|
||||||
import parseopt
|
import parseopt
|
||||||
|
import nimSHA2
|
||||||
|
import times
|
||||||
import os
|
import os
|
||||||
|
|
||||||
# Thanks art <3
|
# Thanks art <3
|
||||||
|
@ -20,6 +22,7 @@ import frontend/parser as p
|
||||||
import frontend/compiler as c
|
import frontend/compiler as c
|
||||||
import backend/vm as v
|
import backend/vm as v
|
||||||
import util/serializer as s
|
import util/serializer as s
|
||||||
|
import util/debugger
|
||||||
import config
|
import config
|
||||||
|
|
||||||
# Forward declarations
|
# Forward declarations
|
||||||
|
@ -29,17 +32,10 @@ proc getLineEditor: LineEditor
|
||||||
# Handy dandy compile-time constants
|
# Handy dandy compile-time constants
|
||||||
const debugLexer = false
|
const debugLexer = false
|
||||||
const debugParser = false
|
const debugParser = false
|
||||||
const debugCompiler = true
|
const debugCompiler = false
|
||||||
const debugSerializer = true
|
const debugSerializer = false
|
||||||
const debugRuntime = false
|
const debugRuntime = false
|
||||||
|
|
||||||
when debugSerializer:
|
|
||||||
import nimSHA2
|
|
||||||
import times
|
|
||||||
|
|
||||||
when debugCompiler:
|
|
||||||
import util/debugger
|
|
||||||
|
|
||||||
|
|
||||||
proc repl =
|
proc repl =
|
||||||
styledEcho fgMagenta, "Welcome into the peon REPL!"
|
styledEcho fgMagenta, "Welcome into the peon REPL!"
|
||||||
|
@ -123,6 +119,11 @@ proc repl =
|
||||||
styledEcho fgGreen, "OK"
|
styledEcho fgGreen, "OK"
|
||||||
else:
|
else:
|
||||||
styledEcho fgRed, "Corrupted"
|
styledEcho fgRed, "Corrupted"
|
||||||
|
stdout.styledWrite(fgBlue, "\t- CFI segment: ")
|
||||||
|
if serialized.chunk.cfi == compiled.cfi:
|
||||||
|
styledEcho fgGreen, "OK"
|
||||||
|
else:
|
||||||
|
styledEcho fgRed, "Corrupted"
|
||||||
when debugRuntime:
|
when debugRuntime:
|
||||||
styledEcho fgCyan, "\n\nExecution step: "
|
styledEcho fgCyan, "\n\nExecution step: "
|
||||||
vm.run(serialized.chunk)
|
vm.run(serialized.chunk)
|
||||||
|
@ -240,6 +241,11 @@ proc runFile(f: string) =
|
||||||
styledEcho fgGreen, "OK"
|
styledEcho fgGreen, "OK"
|
||||||
else:
|
else:
|
||||||
styledEcho fgRed, "Corrupted"
|
styledEcho fgRed, "Corrupted"
|
||||||
|
stdout.styledWrite(fgBlue, "\t- CFI segment: ")
|
||||||
|
if serialized.chunk.cfi == compiled.cfi:
|
||||||
|
styledEcho fgGreen, "OK"
|
||||||
|
else:
|
||||||
|
styledEcho fgRed, "Corrupted"
|
||||||
when debugRuntime:
|
when debugRuntime:
|
||||||
styledEcho fgCyan, "\n\nExecution step: "
|
styledEcho fgCyan, "\n\nExecution step: "
|
||||||
vm.run(serialized.chunk)
|
vm.run(serialized.chunk)
|
||||||
|
|
|
@ -6,11 +6,11 @@ operator `+`(a: int32): int32 {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn `+`(a, b: int): int {
|
fn `+`(a, b: int): int32 {
|
||||||
return a + b;
|
return 0'i32; # Just to test error messages
|
||||||
}
|
}
|
||||||
|
|
||||||
var `+`: int = 1; # hehehehe
|
var `+`: int = 1; # Can't call a value!
|
||||||
|
|
||||||
+1; # Works: defined for int64
|
+1; # Works: defined for int64
|
||||||
# +1'u8; # Nope!
|
+1'u8; # No implementation for uint8, error!
|
||||||
|
|
Loading…
Reference in New Issue