From 448e805293989b06e07878a4a87fdd378f7c6e02 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 6 Apr 2025 15:09:44 -0400 Subject: Re-implement multiple patterns for `when` blocks --- src/parse.c | 14 ++++++++++---- test/enums.tm | 12 ++++++++++++ test/when.tm | 19 ++++++++++++------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/parse.c b/src/parse.c index a11fc971..0f76243d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -996,11 +996,17 @@ PARSER(parse_when) { spaces(&pos); ast_t *pattern = expect(ctx, start, &pos, parse_expr, "I expected a pattern to match here"); spaces(&pos); - tmp = pos; - if (!match(&tmp, ":")) - parser_err(ctx, tmp, tmp, "I expected a colon ':' after this clause"); + when_clause_t *new_clauses = new(when_clause_t, .pattern=pattern, .next=clauses); + while (match(&pos, ",")) { + pattern = expect(ctx, start, &pos, parse_expr, "I expected a pattern to match here"); + new_clauses = new(when_clause_t, .pattern=pattern, .next=new_clauses); + spaces(&pos); + } ast_t *body = expect(ctx, start, &pos, parse_block, "I expected a body for this 'when' clause"); - clauses = new(when_clause_t, .pattern=pattern, .body=body, .next=clauses); + for (when_clause_t *c = new_clauses; c && c != clauses; c = c->next) { + c->body = body; + } + clauses = new_clauses; tmp = pos; whitespace(&tmp); } diff --git a/test/enums.tm b/test/enums.tm index 19590353..a11f95f9 100644 --- a/test/enums.tm +++ b/test/enums.tm @@ -66,6 +66,18 @@ func main(): while when cases[i] is One(x): >> x i += 1 + + >> [ + ( + when x is One(y), Two(y,_): + "Small $y" + is Zero: + "Zero" + else: + "Other" + ) for x in [Foo.Zero, Foo.One(1), Foo.Two(2,2), Foo.Three(3,"",no)] + ] + = ["Zero", "Small 1", "Small 2", "Other"] >> expr := when cases[1] is One(y): y + 1 diff --git a/test/when.tm b/test/when.tm index 77c97af5..d93745dd 100644 --- a/test/when.tm +++ b/test/when.tm @@ -1,13 +1,18 @@ # Tests for the 'when' block func main(): - str := "B" - when str is "A": - fail("First") - is "B": - say("Success") - is "C": - fail("Third") + answers := [ + ( + when x is "A","B": + "A or B" + is "C": + "C" + else: + "Other" + ) for x in ["A", "B", "C", "D"] + ] + >> answers + = ["A or B", "A or B", "C", "Other"] n := 23 >> when n is 1: Int64(1) -- cgit v1.2.3