harec

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

commit 8a0455a900ac5ba1e67c136cd4fae883056e074e
parent e81307e4dc2f4eea650499cdc6a635c0b04aaf54
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 20 Dec 2020 15:23:01 -0500

check: implement return

Diffstat:
Minclude/expr.h | 5+++++
Msrc/check.c | 24++++++++++++++++++++++++
2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/include/expr.h b/include/expr.h @@ -49,6 +49,10 @@ struct expression_list { struct expression_list *next; }; +struct expression_return { + struct expression *value; +}; + struct expression { const struct type *result; enum expr_type type; @@ -56,6 +60,7 @@ struct expression { union { union expression_constant constant; struct expression_list list; + struct expression_return _return; }; }; diff --git a/src/check.c b/src/check.c @@ -100,6 +100,8 @@ check_expr_list(struct context *ctx, *next = calloc(1, sizeof(struct expression_list)); list = *next; next = &list->next; + } else { + expr->result = lexpr->result; } } @@ -107,6 +109,26 @@ check_expr_list(struct context *ctx, } static void +check_expr_return(struct context *ctx, + const struct ast_expression *aexpr, + struct expression *expr) +{ + trenter(TR_CHECK, "return"); + expr->type = EXPR_RETURN; + expr->result = &builtin_type_void; + expr->terminates = true; + + if (aexpr->_return.value) { + struct expression *rval = calloc(1, sizeof(struct expression)); + check_expression(ctx, aexpr->_return.value, rval); + expr->_return.value = rval; + // TODO: Test assignability with function's return type + } + + trleave(TR_CHECK, NULL); +} + +static void check_expression(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr) @@ -139,6 +161,8 @@ check_expression(struct context *ctx, case EXPR_MATCH: case EXPR_MEASURE: case EXPR_RETURN: + check_expr_return(ctx, aexpr, expr); + break; case EXPR_SLICE: case EXPR_STRUCT: case EXPR_SWITCH: