commit 388150902e42e135401a2af61fe02784d82f0fba
parent f24d7709d5a2c26db8c070ebe7d2fa8203c9e40a
Author: Alexey Yerin <yyp@disroot.org>
Date: Fri, 7 May 2021 11:29:21 +0300
hare::parse: handle pointer types in match cases
Earlier match_expr was assuming that * always means default case, which
is not always true for pointers.
Now we also check for => after *, and only then set as the default match
case. In other cases, parse this as a type and wrap it in a pointer
(because it's not possible to unlex 2+ tokens).
Minimal reproduction of the bug:
match (x) {
nullable *foo => spam,
*bar => eggs,
* => void,
};
Fixes #420
Diffstat:
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -984,11 +984,27 @@ fn match_expr(lexer: *lex::lexer) (ast::expr | error) = {
match (try(lexer, ltok::TIMES)?) {
void => append(cases, match_case(lexer)?),
t: lex::token => {
- want(lexer, ltok::CASE)?;
- if (default != null) {
- return syntaxerr(t.2, "More than one default match case");
+ match (peek(lexer, ltok::NAME)?) {
+ t: lex::token => {
+ let case = match_case(lexer)?;
+ case._type = alloc(ast::_type {
+ loc = case._type.loc,
+ flags = 0,
+ _type = ast::pointer_type {
+ referent = case._type,
+ flags = 0: ast::pointer_flags,
+ },
+ });
+ append(cases, case);
+ },
+ void => {
+ want(lexer, ltok::CASE)?;
+ if (default != null) {
+ return syntaxerr(t.2, "More than one default match case");
+ };
+ default = alloc(expression(lexer)?);
+ },
};
- default = alloc(expression(lexer)?);
},
};