harec

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

commit 9aa447a7047b249c7649abfc339841e28525c765
parent 87f934c68d3cb6a24aaa6cdc0f9cf1a5a5981992
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri,  5 Feb 2021 12:16:59 -0500

check: implement if with tagged union result

Diffstat:
Msrc/check.c | 16+++++++++++++---
Msrc/gen.c | 2+-
2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -941,11 +941,21 @@ check_expr_if(struct context *ctx, expr->result = false_branch->result; } else if (false_branch->terminates) { expr->result = true_branch->result; - } else { - // TODO: Tagged unions - assert(true_branch->result == false_branch->result); + } else if (true_branch->result == false_branch->result) { expr->result = true_branch->result; + } else { + struct type_tagged_union _tags = { + .type = false_branch->result, + .next = NULL, + }, tags = { + .type = true_branch->result, + .next = &_tags, + }; + expr->result = + type_store_lookup_tagged(ctx->store, &tags); } + true_branch = lower_implicit_cast(expr->result, true_branch); + false_branch = lower_implicit_cast(expr->result, false_branch); } else { expr->result = &builtin_type_void; expr->terminates = true_branch->terminates; diff --git a/src/gen.c b/src/gen.c @@ -1082,7 +1082,7 @@ gen_expr_type_assertion(struct gen_context *ctx, *tagged = type_dealias(expr->cast.value->result); struct qbe_value tag = {0}, in = {0}, id = {0}, result = {0}; gen_temp(ctx, &tag, &qbe_word, "tag.%d"); - gen_temp(ctx, &in, qtype_for_type(ctx, tagged, false), "cast.in.%d"); + alloc_temp(ctx, &in, tagged, "cast.in.%d"); qval_address(&in); gen_expression(ctx, expr->cast.value, &in); pushi(ctx->current, &tag, Q_LOADUW, &in, NULL);