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