conditionally unwrapping while loops

This commit is contained in:
2026-08-11 18:33:54 +02:00
parent ba6052eef3
commit fa53ca2219
8 changed files with 486 additions and 307 deletions
+26 -15
View File
@@ -2229,19 +2229,7 @@ parse_control_body :: proc(parser: ^Parser, header: ast.Expr_Id, diagnostic: str
return single
}
parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
start := advance(parser) // consume 'if'
skip_newlines(parser)
saved := parser.no_struct_literal
parser.no_struct_literal = true
saved_capture_pipe := parser.capture_pipe
saved_if_condition := parser.if_condition
parser.capture_pipe = true
parser.if_condition = true
condition := parse_expression(parser)
parser.if_condition = saved_if_condition
parser.capture_pipe = saved_capture_pipe
parser.no_struct_literal = saved
parse_conditional_captures :: proc(parser: ^Parser) -> ([]symbol.Id, ast.Expr_Id) {
captures: [dynamic]symbol.Id
captures.allocator = parser.module.allocator
guard := ast.INVALID_EXPR
@@ -2267,9 +2255,9 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
if current(parser).kind == .Pipe {
source.add(parser.diagnostics, current(parser).span, "expected a guard expression after ':'")
} else {
saved = parser.no_struct_literal
saved := parser.no_struct_literal
parser.no_struct_literal = true
saved_capture_pipe = parser.capture_pipe
saved_capture_pipe := parser.capture_pipe
parser.capture_pipe = true
guard = parse_expression(parser)
parser.capture_pipe = saved_capture_pipe
@@ -2280,6 +2268,23 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
source.add(parser.diagnostics, current(parser).span, "expected '|' to close unwrap captures")
}
}
return captures[:], guard
}
parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
start := advance(parser) // consume 'if'
skip_newlines(parser)
saved := parser.no_struct_literal
parser.no_struct_literal = true
saved_capture_pipe := parser.capture_pipe
saved_if_condition := parser.if_condition
parser.capture_pipe = true
parser.if_condition = true
condition := parse_expression(parser)
parser.if_condition = saved_if_condition
parser.capture_pipe = saved_capture_pipe
parser.no_struct_literal = saved
captures, guard := parse_conditional_captures(parser)
then_body := parse_control_body(
parser,
condition,
@@ -2608,8 +2613,12 @@ parse_while :: proc(parser: ^Parser) -> ast.Stmt_Id {
skip_newlines(parser)
saved := parser.no_struct_literal
parser.no_struct_literal = true
saved_capture_pipe := parser.capture_pipe
parser.capture_pipe = true
condition := parse_expression(parser)
parser.capture_pipe = saved_capture_pipe
parser.no_struct_literal = saved
captures, guard := parse_conditional_captures(parser)
skip_newlines(parser)
update := ast.INVALID_STMT
@@ -2631,6 +2640,8 @@ parse_while :: proc(parser: ^Parser) -> ast.Stmt_Id {
span=span_from(start.span, previous(parser).span),
expr=condition,
body=body,
captures=captures,
guard=guard,
label=label,
update=update,
diagnostic=source.INVALID_DIAGNOSTIC,