Fixed bugs with blocks

This commit is contained in:
Mattia Giambirtone 2022-12-05 08:47:14 +01:00
parent 4b6d86ad8e
commit c0f358e956
2 changed files with 29 additions and 23 deletions

View File

@ -175,6 +175,7 @@ type
depth: int
breakJumps: seq[int]
name: string
broken: bool
Compiler* = ref object
## 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)
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) =
## Imports a module at compile time
self.declare(node)
@ -2505,9 +2484,32 @@ proc exportStmt(self: Compiler, node: ExportStmt) =
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) =
## Compiles named blocks
self.beginScope()
var blk = self.namedBlocks[^1]
var last: Declaration
for decl in node.code:
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)
else:
discard
if blk.broken:
blk.breakJumps.add(self.emitJump(OpCode.JumpForwards, node.token.line))
self.declaration(decl)
last = decl
self.patchBreaks()

View File

@ -1,5 +1,7 @@
import std;
fn foo {return;}
block outer {
var x = 1;
@ -10,11 +12,11 @@ block outer {
break outer;
print("nope");
}
print("nope again");
}
var x = 3;
print(x == 3);
var count = 0;
block loop {
if count < 5 {