harec

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

commit 8bc045be450b1a4f5fd0b8da11315a26fee8fd4b
parent 234202dfb456dc7498852a9699a8b14eac6b8541
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue,  2 Feb 2021 16:55:37 -0500

gen: simplify match generation

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

diff --git a/src/check.c b/src/check.c @@ -1004,12 +1004,8 @@ check_expr_match(struct context *ctx, } else { // TODO: Assign a score to tagged compatibility // and choose the branch with the highest score. - const struct type *intermediate; expect(&acase->type->loc, type_is_assignable(type, ctype), "Invalid type for match case (match is not assignable to this type)"); - intermediate = tagged_select_subtype(type, ctype); - expect(&acase->type->loc, intermediate->id == ctype->id, - "TODO: Compare with transitive tagged type"); } } diff --git a/src/gen.c b/src/gen.c @@ -1515,29 +1515,15 @@ gen_match_tagged(struct gen_context *ctx, fbranch.kind = QV_LABEL; fbranch.name = strdup(genl(&flabel, &ctx->id, "next.case.%d")); - const struct type_tagged_union *tu; - struct type_tagged_union synthetic = {0}; - if (_case->type->storage != TYPE_STORAGE_TAGGED) { - synthetic.type = _case->type; - tu = &synthetic; - } else { - tu = &_case->type->tagged; - } - - for (; tu; tu = tu->next) { - struct qbe_statement nlabel = {0}; - struct qbe_value nbranch = {0}; - nbranch.kind = QV_LABEL; - nbranch.name = strdup(genl(&nlabel, &ctx->id, "next.opt.%d")); - - constw(&match, tu->type->id); - pushi(ctx->current, &temp, Q_CEQW, &match, &tag, NULL); - pushi(ctx->current, NULL, Q_JNZ, - &temp, &tbranch, &nbranch, NULL); - push(&ctx->current->body, &nlabel); + const struct type *intermediate = + tagged_select_subtype(mtype, _case->type); + if (intermediate->id != _case->type->id) { + assert(0); // TODO } - pushi(ctx->current, NULL, Q_JMP, &fbranch, NULL); + constw(&match, _case->type->id); + pushi(ctx->current, &temp, Q_CEQW, &match, &tag, NULL); + pushi(ctx->current, NULL, Q_JNZ, &temp, &tbranch, &fbranch, NULL); push(&ctx->current->body, &tlabel); if (_case->object) {