harec

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

commit 4ae764e204cb7d63f5653583c4823b7fd265032b
parent 000a268c4c1e348e613dec9545bb52cb64c9ab67
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 20 Jan 2021 09:46:49 -0500

check: implement defer

Diffstat:
Minclude/ast.h | 2+-
Minclude/check.h | 1+
Minclude/expr.h | 5+++++
Msrc/check.c | 19++++++++++++++++++-
Msrc/parse.c | 2+-
5 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -210,7 +210,7 @@ struct ast_expression_control { }; struct ast_expression_defer { - struct ast_expression *expression; + struct ast_expression *deferred; }; struct ast_expression_for { diff --git a/include/check.h b/include/check.h @@ -14,6 +14,7 @@ struct context { struct identifier *ns; struct scope *unit; struct scope *scope; + bool deferring; int id; }; diff --git a/include/expr.h b/include/expr.h @@ -144,6 +144,10 @@ struct expression_control { char *label; }; +struct expression_defer { + struct expression *deferred; +}; + struct expression_for { char *label; struct scope *scope; @@ -241,6 +245,7 @@ struct expression { struct expression_call call; struct expression_cast cast; union expression_constant constant; + struct expression_defer defer; struct expression_control control; struct expression_for _for; struct expression_if _if; diff --git a/src/check.c b/src/check.c @@ -607,6 +607,22 @@ check_expr_constant(struct context *ctx, } static void +check_expr_defer(struct context *ctx, + const struct ast_expression *aexpr, + struct expression *expr, + const struct type *hint) +{ + expect(&aexpr->loc, !ctx->deferring, + "Cannot defer within another defer expression."); + expr->type = EXPR_DEFER; + expr->result = &builtin_type_void; + expr->defer.deferred = xcalloc(1, sizeof(struct expression)); + ctx->deferring = true; + check_expression(ctx, aexpr->defer.deferred, expr->defer.deferred, NULL); + ctx->deferring = false; +} + +static void check_expr_control(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr, @@ -1123,7 +1139,8 @@ check_expression(struct context *ctx, check_expr_constant(ctx, aexpr, expr, hint); break; case EXPR_DEFER: - assert(0); + check_expr_defer(ctx, aexpr, expr, hint); + break; case EXPR_FOR: check_expr_for(ctx, aexpr, expr, hint); break; diff --git a/src/parse.c b/src/parse.c @@ -1045,7 +1045,7 @@ parse_defer_expression(struct lexer *lexer) struct ast_expression *exp = mkexpr(&lexer->loc); want(lexer, T_DEFER, NULL); exp->type = EXPR_DEFER; - exp->defer.expression = parse_scope_expression(lexer); + exp->defer.deferred = parse_scope_expression(lexer); return exp; }