labeled block statements

This commit is contained in:
2026-06-28 09:07:09 +02:00
parent eaa66511a0
commit 3007910526
5 changed files with 181 additions and 21 deletions
+10 -2
View File
@@ -1058,14 +1058,16 @@ parse_loop_control :: proc(parser: ^Parser, kind: ast.Stmt_Kind) -> ast.Stmt_Id
}
// A bare `{ ... }` introduces a nested scope. Locals declared inside are not
// visible after it, and any `defer`s inside it run at the closing brace.
parse_block_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
// visible after it, and any `defer`s inside it run at the closing brace. A labeled
// `blk: { ... }` can be exited early with `break :blk`.
parse_block_statement :: proc(parser: ^Parser, label := symbol.INVALID) -> ast.Stmt_Id {
start := current(parser).span // the '{'
body := parse_block(parser)
id := ast.stmt_id(len(parser.module.statements))
append(&parser.module.statements, ast.Stmt{
kind=.Block,
span=start,
label=label,
body=body,
expr=ast.INVALID_EXPR,
update=ast.INVALID_STMT,
@@ -1159,6 +1161,12 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
if current(parser).kind == .Left_Brace {
return parse_block_statement(parser)
}
// `blk: { ... }` is a labeled block statement (exitable via `break :blk`). At
// statement start, `Identifier ':'` (a single colon, not `::`) opens one.
if current(parser).kind == .Identifier && peek(parser).kind == .Colon {
label := parse_optional_loop_label(parser)
return parse_block_statement(parser, label)
}
if current(parser).kind == .Identifier || current(parser).kind == .Underscore {
start_cursor := parser.cursor