break and continue in loops
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user