harec

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

commit 2b8fb8ff4ad2aea6bd6df8616a1a259d739f3d83
parent 83effe96530902378e457ffd20335865bb93d552
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun,  4 Jul 2021 18:36:31 -0400

gen: implement assertion expressions

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Msrc/gen.c | 52+++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/gen.c b/src/gen.c @@ -265,6 +265,54 @@ gen_expr_access(struct gen_context *ctx, } static void +gen_expr_assert(struct gen_context *ctx, + const struct expression *expr, + const struct gen_temp *out) +{ + assert(expr->assert.message); // Invariant + if (expr->assert.is_static) { + return; + } + + struct qbe_statement failedl = {0}, passedl = {0}; + struct qbe_value bfailed = {0}, bpassed = {0}; + struct qbe_value rtfunc = {0}; + rtfunc.kind = QV_GLOBAL; + rtfunc.name = strdup("rt.abort"); + rtfunc.type = &qbe_long; + + struct gen_temp msg = {0}; + alloc_temp(ctx, &msg, &builtin_type_str, "abortstr.%d"); + + if (expr->assert.cond) { + bfailed.kind = QV_LABEL; + bfailed.name = strdup(genl(&failedl, &ctx->id, "failed.%d")); + bpassed.kind = QV_LABEL; + bpassed.name = strdup(genl(&passedl, &ctx->id, "passed.%d")); + + struct gen_temp cond = {0}; + gen_direct(ctx, &cond, &builtin_type_bool, "cond.%d"); + gen_expr(ctx, expr->assert.cond, &cond); + + struct qbe_value qcond = {0}; + qval_temp(ctx, &qcond, &cond); + pushi(ctx->current, NULL, Q_JNZ, &qcond, &bpassed, &bfailed, NULL); + push(&ctx->current->body, &failedl); + gen_expr(ctx, expr->assert.message, &msg); + } else { + gen_expr(ctx, expr->assert.message, &msg); + } + + struct qbe_value qmsg = {0}; + qval_temp(ctx, &qmsg, &msg); + pushi(ctx->current, NULL, Q_CALL, &rtfunc, &qmsg, NULL); + + if (expr->assert.cond) { + push(&ctx->current->body, &passedl); + } +} + +static void gen_expr_assign(struct gen_context *ctx, const struct expression *expr, const struct gen_temp *out) @@ -587,8 +635,10 @@ gen_expr(struct gen_context *ctx, break; case EXPR_ALLOC: case EXPR_APPEND: - case EXPR_ASSERT: assert(0); // TODO + case EXPR_ASSERT: + gen_expr_assert(ctx, expr, out); + break; case EXPR_ASSIGN: gen_expr_assign(ctx, expr, out); break;