summaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/parse.c b/parse.c
index 583f637..704d867 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
}