condtional multi-unwrap and guard clauses

This commit is contained in:
2026-06-22 20:37:37 +02:00
parent 27f42dd253
commit 663f4dc658
9 changed files with 567 additions and 96 deletions
+32 -8
View File
@@ -1129,16 +1129,39 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
parser.no_struct_literal = true
condition := parse_expression(parser)
parser.no_struct_literal = saved
binding := symbol.INVALID
captures: [dynamic]symbol.Id
captures.allocator = parser.module.allocator
guard := ast.INVALID_EXPR
if _, ok := allow(parser, .Pipe); ok {
name_tok, name_ok := allow(parser, .Identifier)
if name_ok {
binding = name_tok.symbol
} else {
source.add(parser.diagnostics, current(parser).span, "expected a binding name after '|'")
for {
name_tok := current(parser)
if name_tok.kind == .Identifier || name_tok.kind == .Underscore {
advance(parser)
append(&captures, name_tok.symbol)
} else {
source.add(parser.diagnostics, current(parser).span, "expected an unwrap capture name")
break
}
if _, comma_ok := allow(parser, .Comma); !comma_ok {
break
}
if current(parser).kind == .Colon || current(parser).kind == .Pipe {
source.add(parser.diagnostics, current(parser).span, "expected an unwrap capture after ','")
break
}
}
if _, guard_ok := allow(parser, .Colon); guard_ok {
if current(parser).kind == .Pipe {
source.add(parser.diagnostics, current(parser).span, "expected a guard expression after ':'")
} else {
saved = parser.no_struct_literal
parser.no_struct_literal = true
guard = parse_expression(parser)
parser.no_struct_literal = saved
}
}
if _, close_ok := allow(parser, .Pipe); !close_ok {
source.add(parser.diagnostics, current(parser).span, "expected '|' to close the unwrap binding")
source.add(parser.diagnostics, current(parser).span, "expected '|' to close unwrap captures")
}
}
skip_newlines(parser)
@@ -1164,8 +1187,9 @@ parse_if :: proc(parser: ^Parser) -> ast.Stmt_Id {
append(&parser.module.statements, ast.Stmt{
kind=.If,
span=span_from(start.span, previous(parser).span),
name=binding,
expr=condition,
captures=captures[:],
guard=guard,
body=then_body,
else_body=else_body,
diagnostic=source.INVALID_DIAGNOSTIC,