commit 8bc045be450b1a4f5fd0b8da11315a26fee8fd4b
parent 234202dfb456dc7498852a9699a8b14eac6b8541
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 2 Feb 2021 16:55:37 -0500
gen: simplify match generation
Diffstat:
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) {