Skip to content

Commit

Permalink
Allow parentheses in match cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Jan 15, 2025
1 parent dd88edc commit 6c6a262
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
9 changes: 8 additions & 1 deletion bootstrap_compiler/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -722,13 +722,20 @@ static AstMatchStatement parse_match_statement(ParserState *ps)
ps->tokens++;
result.case_underscore = parse_body(ps);
} else {
bool parens = is_operator(ps->tokens, "(");
if (parens)
ps->tokens++;
List(AstExpression) case_objs = {0};
while(1){
Append(&case_objs, parse_expression(ps));
if (is_operator(ps->tokens, "|"))
ps->tokens++;
else if (is_operator(ps->tokens, ":"))
else if (!parens && is_operator(ps->tokens, ":"))
break;
else if (parens && is_operator(ps->tokens, ")") && is_operator(&ps->tokens[1], ":")) {
ps->tokens++;
break;
}
else
fail_with_parse_error(ps->tokens, "'|' or ':'");
}
Expand Down
13 changes: 11 additions & 2 deletions compiler/parser.jou
Original file line number Diff line number Diff line change
Expand Up @@ -884,17 +884,26 @@ class Parser:
assert result.case_underscore != NULL
*result.case_underscore = self->parse_body()
else:
parens = self->tokens->is_operator("(")
if parens:
self->tokens++
case_objs: AstExpression* = NULL
n_case_objs = 0
while True:
case_objs = realloc(case_objs, sizeof(case_objs[0]) * (n_case_objs + 1))
case_objs[n_case_objs++] = self->parse_expression()
if self->tokens->is_operator("|"):
self->tokens++
elif self->tokens->is_operator(":"):
elif (not parens) and self->tokens->is_operator(":"):
break
elif parens and self->tokens->is_operator(")") and self->tokens[1].is_operator(":"):
self->tokens++ # skip ')'
break
else:
self->tokens->fail_expected_got("'|' or ':'")
if parens:
self->tokens->fail_expected_got("'|' or '):'")
else:
self->tokens->fail_expected_got("'|' or ':'")
result.cases = realloc(result.cases, sizeof result.cases[0] * (result.ncases + 1))
result.cases[result.ncases++] = AstCase{
case_objs = case_objs,
Expand Down
10 changes: 10 additions & 0 deletions tests/should_succeed/match.jou
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ def main() -> int:
case _:
printf("nope\n")

match Foo.Baz:
# This syntax is useful if you have many values in the same case.
case (
Foo.Bar
| Foo.Baz
):
printf("yay\n") # Output: yay
case _:
printf("nope\n")

f = 69 as Foo
match f:
case Foo.Bar:
Expand Down
9 changes: 9 additions & 0 deletions tests/syntax_error/match_bad_case_parens.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
enum Foo:
One
Two
Three

def blah(f: Foo) -> None:
match f:
case (Foo.One Foo.Two): # Error: expected '|' or '):', got a variable name 'Foo'
printf("hi\n")

0 comments on commit 6c6a262

Please sign in to comment.