diff options
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 18 |
1 files changed, 15 insertions, 3 deletions
@@ -331,6 +331,7 @@ typedef enum { EXPR_CAN_END_WITH_COLON = 0x04, EXPR_CAN_END_WITH_DOTDOT = 0x08, EXPR_CAN_END_WITH_EQ = 0x10, + EXPR_CAN_END_WITH_WHERE = 0x20 /* note that parse_type uses -1 for this */ } ExprEndFlags; @@ -395,6 +396,10 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { if (all_levels_0 && (flags & EXPR_CAN_END_WITH_EQ)) return token; break; + case KW_WHERE: + if (all_levels_0 && (flags & EXPR_CAN_END_WITH_WHERE)) + return token; + break; case KW_COLON: if ((flags & EXPR_CAN_END_WITH_COLON) && all_levels_0) return token; @@ -802,7 +807,7 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { --paren_level; if (paren_level == 0) { ++t->token; - if (token_is_kw(t->token, KW_LBRACE)) goto end; /* void fn expr */ + if (token_is_kw(t->token, KW_LBRACE) || token_is_kw(t->token, KW_WHERE)) goto end; /* void fn expr */ if (is_decl(t)) /* has return declaration */ goto end; @@ -954,6 +959,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { f->instance_id = 0; f->ret_decls = NULL; f->instances = NULL; + f->condition = NULL; /* only called when token is fn */ assert(token_is_kw(t->token, KW_FN)); ++t->token; @@ -984,7 +990,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { success = false; goto ret; } - if (token_is_kw(t->token, KW_LBRACE)) { + if (token_is_kw(t->token, KW_LBRACE) || token_is_kw(t->token, KW_WHERE)) { /* void function */ f->ret_type.kind = TYPE_VOID; f->ret_type.flags = 0; @@ -1011,6 +1017,13 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { goto ret; } } + if (token_is_kw(t->token, KW_WHERE)) { + ++t->token; + f->condition = parser_new_expr(p); + if (!parse_expr(p, f->condition, expr_find_end(p, EXPR_CAN_END_WITH_LBRACE))) { + return false; + } + } p->block = prev_block; /* be nice to parse_block */ if (!parse_block(p, &f->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) success = false; @@ -2194,7 +2207,6 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { return false; goto success; } - tokr_err(t, "Unrecognized expression."); return false; } |