Fixed bugs with blocks
This commit is contained in:
parent
4b6d86ad8e
commit
c0f358e956
|
@ -175,6 +175,7 @@ type
|
||||||
depth: int
|
depth: int
|
||||||
breakJumps: seq[int]
|
breakJumps: seq[int]
|
||||||
name: string
|
name: string
|
||||||
|
broken: bool
|
||||||
|
|
||||||
Compiler* = ref object
|
Compiler* = ref object
|
||||||
## A wrapper around the Peon compiler's state
|
## A wrapper around the Peon compiler's state
|
||||||
|
@ -2445,28 +2446,6 @@ proc continueStmt(self: Compiler, node: ContinueStmt) =
|
||||||
self.emitBytes(blocks[^1].start.toTriple(), node.token.line)
|
self.emitBytes(blocks[^1].start.toTriple(), node.token.line)
|
||||||
|
|
||||||
|
|
||||||
proc breakStmt(self: Compiler, node: BreakStmt) =
|
|
||||||
## Compiles break statements. A break statement
|
|
||||||
## jumps to the end of the loop
|
|
||||||
if node.label.isNil():
|
|
||||||
self.currentLoop.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
|
|
||||||
if self.currentLoop.depth > self.depth:
|
|
||||||
# Breaking out of a loop closes its scope
|
|
||||||
self.endScope()
|
|
||||||
else:
|
|
||||||
var blocks: seq[NamedBlock] = @[]
|
|
||||||
var found: bool = false
|
|
||||||
for blk in reversed(self.namedBlocks):
|
|
||||||
blocks.add(blk)
|
|
||||||
if blk.name == node.label.token.lexeme:
|
|
||||||
for blk in blocks:
|
|
||||||
blk.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
if not found:
|
|
||||||
self.error(&"unknown block name '{node.label.token.lexeme}'", node.label)
|
|
||||||
|
|
||||||
|
|
||||||
proc importStmt(self: Compiler, node: ImportStmt) =
|
proc importStmt(self: Compiler, node: ImportStmt) =
|
||||||
## Imports a module at compile time
|
## Imports a module at compile time
|
||||||
self.declare(node)
|
self.declare(node)
|
||||||
|
@ -2505,9 +2484,32 @@ proc exportStmt(self: Compiler, node: ExportStmt) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
|
||||||
|
proc breakStmt(self: Compiler, node: BreakStmt) =
|
||||||
|
## Compiles break statements. A break statement
|
||||||
|
## jumps to the end of the loop
|
||||||
|
if node.label.isNil():
|
||||||
|
self.currentLoop.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
|
||||||
|
if self.currentLoop.depth > self.depth:
|
||||||
|
# Breaking out of a loop closes its scope
|
||||||
|
self.endScope()
|
||||||
|
else:
|
||||||
|
var blocks: seq[NamedBlock] = @[]
|
||||||
|
var found: bool = false
|
||||||
|
for blk in reversed(self.namedBlocks):
|
||||||
|
blocks.add(blk)
|
||||||
|
if blk.name == node.label.token.lexeme:
|
||||||
|
for blk in blocks:
|
||||||
|
blk.broken = true
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
|
self.error(&"unknown block name '{node.label.token.lexeme}'", node.label)
|
||||||
|
|
||||||
|
|
||||||
proc namedBlock(self: Compiler, node: NamedBlockStmt) =
|
proc namedBlock(self: Compiler, node: NamedBlockStmt) =
|
||||||
## Compiles named blocks
|
## Compiles named blocks
|
||||||
self.beginScope()
|
self.beginScope()
|
||||||
|
var blk = self.namedBlocks[^1]
|
||||||
var last: Declaration
|
var last: Declaration
|
||||||
for decl in node.code:
|
for decl in node.code:
|
||||||
if not last.isNil():
|
if not last.isNil():
|
||||||
|
@ -2516,6 +2518,8 @@ proc namedBlock(self: Compiler, node: NamedBlockStmt) =
|
||||||
self.warning(UnreachableCode, &"code after '{last.token.lexeme}' statement is unreachable", nil, last)
|
self.warning(UnreachableCode, &"code after '{last.token.lexeme}' statement is unreachable", nil, last)
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
if blk.broken:
|
||||||
|
blk.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
|
||||||
self.declaration(decl)
|
self.declaration(decl)
|
||||||
last = decl
|
last = decl
|
||||||
self.patchBreaks()
|
self.patchBreaks()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
fn foo {return;}
|
||||||
|
|
||||||
|
|
||||||
block outer {
|
block outer {
|
||||||
var x = 1;
|
var x = 1;
|
||||||
|
@ -10,11 +12,11 @@ block outer {
|
||||||
break outer;
|
break outer;
|
||||||
print("nope");
|
print("nope");
|
||||||
}
|
}
|
||||||
|
print("nope again");
|
||||||
}
|
}
|
||||||
var x = 3;
|
var x = 3;
|
||||||
print(x == 3);
|
print(x == 3);
|
||||||
|
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
block loop {
|
block loop {
|
||||||
if count < 5 {
|
if count < 5 {
|
||||||
|
|
Loading…
Reference in New Issue