break and continue in loops

This commit is contained in:
2026-06-26 23:43:57 +02:00
parent f926bbc605
commit 81ae939bf0
11 changed files with 314 additions and 12 deletions
+22 -1
View File
@@ -986,6 +986,21 @@ parse_return :: proc(parser: ^Parser) -> ast.Stmt_Id {
return id
}
// `break` / `continue` carry no value and target the innermost loop; the
// checker rejects them outside a loop.
parse_loop_control :: proc(parser: ^Parser, kind: ast.Stmt_Kind) -> ast.Stmt_Id {
marker := advance(parser) // consume 'break' / 'continue'
id := ast.stmt_id(len(parser.module.statements))
append(&parser.module.statements, ast.Stmt{
kind=kind,
span=marker.span,
expr=ast.INVALID_EXPR,
update=ast.INVALID_STMT,
diagnostic=source.INVALID_DIAGNOSTIC,
})
return id
}
starts_declared_type :: proc(parser: ^Parser) -> bool {
if current(parser).kind != .Left_Bracket {
return is_type_token(current(parser).kind)
@@ -1024,6 +1039,12 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
if current(parser).kind == .Keyword_For {
return parse_for(parser)
}
if current(parser).kind == .Keyword_Break {
return parse_loop_control(parser, .Break)
}
if current(parser).kind == .Keyword_Continue {
return parse_loop_control(parser, .Continue)
}
if current(parser).kind == .Identifier || current(parser).kind == .Underscore {
start_cursor := parser.cursor
@@ -1312,7 +1333,7 @@ parse_while_update :: proc(parser: ^Parser) -> ast.Stmt_Id {
statement := &parser.module.statements[update]
switch statement.kind {
case .Assignment, .Expression:
case .Invalid, .Declaration, .Return, .If, .While, .For:
case .Invalid, .Declaration, .Return, .If, .While, .For, .Break, .Continue:
diagnostic := source.add(
parser.diagnostics,
statement.span,