Fixed some issued with scoping and globals

This commit is contained in:
Mattia Giambirtone 2022-07-09 13:36:21 +02:00
parent cc0aab850e
commit 3f5f514259
4 changed files with 20 additions and 26 deletions

View File

@ -27,7 +27,7 @@ when len(PEON_COMMIT_HASH) != 40:
const PEON_BRANCH* = "master"
when len(PEON_BRANCH) > 255:
{.fatal: "The git branch name's length must be less than or equal to 255 characters".}
const DEBUG_TRACE_VM* = true # Traces VM execution
const DEBUG_TRACE_VM* = false # Traces VM execution
const DEBUG_TRACE_GC* = false # Traces the garbage collector (TODO)
const DEBUG_TRACE_ALLOCATION* = false # Traces memory allocation/deallocation
const DEBUG_TRACE_COMPILER* = false # Traces the compiler

View File

@ -385,8 +385,7 @@ proc getStackPos(self: Compiler, name: IdentExpr, depth: int = self.scopeDepth):
if name.name.lexeme == variable.name.name.lexeme:
if variable.isPrivate and variable.owner != self.currentModule:
continue
elif variable.depth == depth or variable.depth == 0:
# variable.depth == 0 for globals!
elif variable.depth == depth:
found = true
dec(result)
break
@ -1317,6 +1316,7 @@ proc callExpr(self: Compiler, node: CallExpr) =
while node.kind == callExpr:
self.callExpr(CallExpr(node))
node = CallExpr(node).callee
# funct = self.matchImpl(IdentExpr(node.callee).name.lexeme, Type(kind: Function, returnType: Type(kind: Any), args: args))
# TODO: Calling lambdas
else:
let typ = self.inferType(node)
@ -1472,23 +1472,19 @@ proc continueStmt(self: Compiler, node: ContinueStmt) =
proc breakStmt(self: Compiler, node: BreakStmt) =
## Compiles break statements. A continue statement
## jumps to the next iteration in a loop
# Emits dummy jump offset, this is
# patched later
self.currentLoop.breakPos.add(self.emitJump(OpCode.Jump))
self.currentLoop.breakPos.add(self.emitJump(OpCode.JumpForwards))
if self.currentLoop.depth > self.scopeDepth:
# Breaking out of a loop closes its scope
self.endScope()
proc patchBreaks(self: Compiler) =
## Patches "break" opcodes with
## actual jumps. This is needed
## Patches the jumps emitted by
## breakStmt. This is needed
## because the size of code
## to skip is not known before
## the loop is fully compiled
for brk in self.currentLoop.breakPos:
self.chunk.code[brk] = JumpForwards.uint8()
self.patchJump(brk)
@ -1512,7 +1508,7 @@ proc importStmt(self: Compiler, node: ImportStmt) =
var parser = newParser()
var compiler = newCompiler()
# TODO: Find module
var result = compiler.compile(parser.parse(lexer.lex("", node.moduleName.name.lexeme), node.moduleName.name.lexeme), node.moduleName.name.lexeme)
var result {.used.} = compiler.compile(parser.parse(lexer.lex("", node.moduleName.name.lexeme), node.moduleName.name.lexeme), node.moduleName.name.lexeme)
proc statement(self: Compiler, node: Statement) =
@ -1544,9 +1540,9 @@ proc statement(self: Compiler, node: Statement) =
self.returnStmt(ReturnStmt(node))
of NodeKind.importStmt:
self.importStmt(ImportStmt(node))
of NodeKind.whileStmt, NodeKind.forStmt:
## Our parser already desugars for loops to
## while loops!
of NodeKind.whileStmt:
# Note: Our parser already desugars
# for loops to while loops!
let loop = self.currentLoop
self.currentLoop = Loop(start: self.chunk.code.len(),
depth: self.scopeDepth, breakPos: @[])
@ -1604,7 +1600,7 @@ proc handleMagicPragma(self: Compiler, pragma: Pragma, node: ASTNode) =
if pragma.args.len() != 1:
self.error("'magic' pragma: wrong number of arguments")
elif pragma.args[0].kind != strExpr:
self.error("'magic' pragma: wrong type of argument (string expected)")
self.error("'magic' pragma: wrong type of argument (constant string expected)")
elif node.kind != NodeKind.funDecl:
self.error("'magic' pragma is not valid in this context")
var node = FunDecl(node)
@ -1623,7 +1619,7 @@ proc handlePurePragma(self: Compiler, pragma: Pragma, node: ASTNode) =
of lambdaExpr:
LambdaExpr(node).isPure = true
else:
self.error("'pure' pragma: invalid usage")
self.error("'pure' pragma is not valid in this context")
proc dispatchPragmas(self: Compiler, node: ASTnode) =
@ -1676,12 +1672,11 @@ proc funDecl(self: Compiler, node: FunDecl, fn: Name = nil, args: seq[Expression
else:
var function = self.currentFunction
var jmp: int
# Builtin functions map to a single
# bytecode instruction to avoid
# unnecessary overhead from peon's
# calling convention. This also means
# that peon's fast builtins can only
# be relatively simple
# Builtin functions (usually) map to a single
# bytecode instruction to avoid unnecessary
# overhead from peon's calling convention
# This also means that peon's fast builtins
# can only be relatively simple
self.frames.add(self.names.high())
# A function's code is just compiled linearly
# and then jumped over
@ -1834,7 +1829,6 @@ proc compile*(self: Compiler, ast: seq[Declaration], file: string): Chunk =
self.names.add(main)
self.emitByte(LoadFunction)
self.emitBytes(main.codePos.toTriple())
self.emitByte(LoadReturnAddress)
let pos = self.chunk.code.len()
self.emitBytes(0.toQuad())

View File

@ -34,7 +34,6 @@ type
funDecl,
varDecl,
# Statements
forStmt, # Unused for now (for loops are compiled to while loops)
ifStmt,
returnStmt,
breakStmt,
@ -62,7 +61,7 @@ type
sliceExpr,
callExpr,
getItemExpr, # Get expressions like a.b
# Primary expressions
# Primary expressions
groupingExpr, # Parenthesized expressions such as (true) and (3 + 4)
trueExpr,
falseExpr,

View File

@ -6,4 +6,5 @@ fn makeClosure(n: int): fn: int {
}
makeClosure(1)();
var closure = makeClosure(1);
closure();