commit 8a0455a900ac5ba1e67c136cd4fae883056e074e
parent e81307e4dc2f4eea650499cdc6a635c0b04aaf54
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 20 Dec 2020 15:23:01 -0500
check: implement return
Diffstat:
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: