braceless one-statement for-loops
This commit is contained in:
+19
-13
@@ -1993,20 +1993,18 @@ parse_block :: proc(parser: ^Parser) -> []ast.Stmt_Id {
|
||||
return body[:]
|
||||
}
|
||||
|
||||
// parse_branch_body parses an `if` then/else body: a braced block (possibly on
|
||||
// a following line) or a single brace-less statement (milestone 16). For the
|
||||
// then-branch (`validate_condition`), a brace-less body requires the condition
|
||||
// to be parenthesized unless it is a function call; the `else` keyword and the
|
||||
// unwrap `|...|` already delimit, so those positions skip the check.
|
||||
parse_branch_body :: proc(parser: ^Parser, validate_condition: bool, condition: ast.Expr_Id, has_captures: bool) -> []ast.Stmt_Id {
|
||||
// parse_control_body parses a braced block (possibly on a following line) or a
|
||||
// single brace-less statement. A non-empty diagnostic enforces the shared
|
||||
// parenthesized-or-call rule for the preceding condition or iterable.
|
||||
parse_control_body :: proc(parser: ^Parser, header: ast.Expr_Id, diagnostic: string) -> []ast.Stmt_Id {
|
||||
skip_newlines(parser)
|
||||
if current(parser).kind == .Left_Brace {
|
||||
return parse_block(parser)
|
||||
}
|
||||
if validate_condition && !has_captures && condition != ast.INVALID_EXPR && int(condition) < len(parser.module.exprs) {
|
||||
expr := parser.module.exprs[condition]
|
||||
if len(diagnostic) > 0 && header != ast.INVALID_EXPR && int(header) < len(parser.module.exprs) {
|
||||
expr := parser.module.exprs[header]
|
||||
if !expr.parenthesized && expr.kind != .Call {
|
||||
source.add(parser.diagnostics, expr.span, "a brace-less 'if' body requires the condition to be parenthesized unless it is a function call")
|
||||
source.add(parser.diagnostics, expr.span, diagnostic)
|
||||
}
|
||||
}
|
||||
single := make([]ast.Stmt_Id, 1, parser.module.allocator)
|
||||
@@ -2056,7 +2054,11 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
source.add(parser.diagnostics, current(parser).span, "expected '|' to close unwrap captures")
|
||||
}
|
||||
}
|
||||
then_body := parse_branch_body(parser, true, condition, len(captures) > 0)
|
||||
then_body := parse_control_body(
|
||||
parser,
|
||||
condition,
|
||||
"a brace-less 'if' body requires the condition to be parenthesized unless it is a function call",
|
||||
)
|
||||
else_body: []ast.Stmt_Id = nil
|
||||
saved_cursor := parser.cursor
|
||||
skip_newlines(parser)
|
||||
@@ -2069,7 +2071,7 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
single[0] = nested
|
||||
else_body = single
|
||||
} else {
|
||||
else_body = parse_branch_body(parser, false, ast.INVALID_EXPR, false)
|
||||
else_body = parse_control_body(parser, ast.INVALID_EXPR, "")
|
||||
}
|
||||
} else {
|
||||
parser.cursor = saved_cursor
|
||||
@@ -2089,7 +2091,7 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
}
|
||||
|
||||
// parse_arm_body parses a match arm's body after the `:`: a braced block (whose
|
||||
// inner statements are returned unwrapped, like `parse_branch_body`) or a single
|
||||
// inner statements are returned unwrapped, like `parse_control_body`) or a single
|
||||
// brace-less statement. For value-match a brace-less body is a single expression
|
||||
// that the checker yields implicitly.
|
||||
parse_arm_body :: proc(parser: ^Parser) -> []ast.Stmt_Id {
|
||||
@@ -2306,7 +2308,11 @@ parse_for :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
}
|
||||
skip_newlines(parser)
|
||||
label := parse_optional_loop_label(parser)
|
||||
body := parse_block(parser)
|
||||
body := parse_control_body(
|
||||
parser,
|
||||
iterable,
|
||||
"a brace-less 'for' body requires the iterable to be parenthesized unless it is a function call",
|
||||
)
|
||||
|
||||
id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
|
||||
Reference in New Issue
Block a user