commit eeb39ccb3d73786467b62e514fe3d79f25e934d1
parent bae5737c457a55d25c293cef4412abeb47d03289
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 31 Aug 2021 11:11:23 +0200
all: lay groundwork for yield expressions
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
8 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -213,6 +213,7 @@ struct ast_expression_constant {
struct ast_expression_control {
char *label;
+ struct ast_expression *value; // Only set for yield
};
struct ast_expression_defer {
diff --git a/include/expr.h b/include/expr.h
@@ -37,6 +37,7 @@ enum expr_type {
EXPR_SWITCH,
EXPR_TUPLE,
EXPR_UNARITHM,
+ EXPR_YIELD,
};
enum access_type {
@@ -210,6 +211,7 @@ struct expression_constant {
struct expression_control {
char *label;
const struct scope *scope;
+ struct expression *value; // Only set for yield
};
struct expression_defer {
diff --git a/include/lex.h b/include/lex.h
@@ -67,7 +67,8 @@ enum lexical_token {
T_UNION,
T_USE,
T_VOID,
- T_LAST_KEYWORD = T_VOID,
+ T_YIELD,
+ T_LAST_KEYWORD = T_YIELD,
// Operators
T_BANDEQ,
diff --git a/src/check.c b/src/check.c
@@ -2646,6 +2646,8 @@ check_expression(struct context *ctx,
case EXPR_UNARITHM:
check_expr_unarithm(ctx, aexpr, expr, hint);
break;
+ case EXPR_YIELD:
+ assert(0); // TODO
}
assert(expr->result);
if (hint && hint->storage == STORAGE_VOID) {
@@ -3178,6 +3180,8 @@ expr_is_specified(struct context *ctx, const struct ast_expression *aexpr)
return true;
case EXPR_UNARITHM:
return expr_is_specified(ctx, aexpr->unarithm.operand);
+ case EXPR_YIELD:
+ return expr_is_specified(ctx, aexpr->control.value);
}
assert(0); // Unreachable
}
diff --git a/src/eval.c b/src/eval.c
@@ -731,6 +731,7 @@ eval_expr(struct context *ctx, struct expression *in, struct expression *out)
case EXPR_PROPAGATE:
case EXPR_RETURN:
case EXPR_SWITCH:
+ case EXPR_YIELD:
// Excluded from translation-compatible subset
return EVAL_INVALID;
}
diff --git a/src/gen.c b/src/gen.c
@@ -2556,6 +2556,8 @@ gen_expr(struct gen_context *ctx, const struct expression *expr)
return gen_expr_switch_with(ctx, expr, NULL);
case EXPR_UNARITHM:
return gen_expr_unarithm(ctx, expr);
+ case EXPR_YIELD:
+ assert(0); // TODO
case EXPR_SLICE:
case EXPR_STRUCT:
case EXPR_TUPLE:
diff --git a/src/lex.c b/src/lex.c
@@ -75,6 +75,7 @@ static const char *tokens[] = {
[T_UNION] = "union",
[T_USE] = "use",
[T_VOID] = "void",
+ [T_YIELD] = "yield",
// Operators
[T_BANDEQ] = "&=",
diff --git a/src/parse.c b/src/parse.c
@@ -2018,7 +2018,6 @@ parse_control_statement(struct lexer *lexer)
case T_RETURN:
exp->type = EXPR_RETURN;
exp->_return.value = NULL;
- struct token tok;
switch (lex(lexer, &tok)) {
case T_SEMICOLON:
case T_COMMA:
@@ -2030,8 +2029,33 @@ parse_control_statement(struct lexer *lexer)
break;
}
break;
+ case T_YIELD:
+ exp->type = EXPR_YIELD;
+ exp->control.value = NULL;
+ switch (lex(lexer, &tok)) {
+ case T_SEMICOLON:
+ unlex(lexer, &tok);
+ break;
+ case T_LABEL:
+ exp->control.label = tok.name;
+ switch (lex(lexer, &tok)) {
+ case T_COMMA:
+ exp->control.value = parse_expression(lexer);
+ break;
+ default:
+ unlex(lexer, &tok);
+ break;
+ }
+ break;
+ default:
+ unlex(lexer, &tok);
+ exp->control.value = parse_expression(lexer);
+ break;
+ }
+ break;
default:
- synassert(false, &tok, T_BREAK, T_CONTINUE, T_RETURN, T_EOF);
+ synassert(false, &tok,
+ T_BREAK, T_CONTINUE, T_RETURN, T_YIELD, T_EOF);
}
return exp;
}
@@ -2124,6 +2148,7 @@ parse_expression(struct lexer *lexer)
case T_BREAK:
case T_CONTINUE:
case T_RETURN:
+ case T_YIELD:
case T_DEFER:
case T_FOR:
case T_LABEL:
@@ -2135,6 +2160,7 @@ parse_expression(struct lexer *lexer)
case T_BREAK:
case T_CONTINUE:
case T_RETURN:
+ case T_YIELD:
unlex(lexer, &tok);
value = parse_control_statement(lexer);
break;