harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Minclude/ast.h | 1+
Minclude/expr.h | 2++
Minclude/lex.h | 3++-
Msrc/check.c | 4++++
Msrc/eval.c | 1+
Msrc/gen.c | 2++
Msrc/lex.c | 1+
Msrc/parse.c | 30++++++++++++++++++++++++++++--
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;