harec

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

commit dc6f41925e1f731357817ad326920a9b670c7e39
parent 72c8d715590c95f06060b2c237c1c18052b60389
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed,  4 Aug 2021 10:44:12 +0200

gen: implement assert

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

Diffstat:
Msrc/gen.c | 43+++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+), 0 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -193,6 +193,8 @@ gen_access_index(struct gen_context *ctx, const struct expression *expr) pushi(ctx->current, &qival, Q_MUL, &qindex, &itemsz, NULL); pushi(ctx->current, &qival, Q_ADD, &qlval, &qival, NULL); + // TODO: Check bounds + return (struct gen_value){ .kind = GV_TEMP, .type = expr->result, @@ -263,6 +265,44 @@ gen_expr_access(struct gen_context *ctx, const struct expression *expr) } static struct gen_value +gen_expr_assert(struct gen_context *ctx, const struct expression *expr) +{ + assert(expr->assert.message); // Invariant + if (expr->assert.is_static) { + return gv_void; + } + + struct qbe_statement failedl = {0}, passedl = {0}; + struct qbe_value bfailed = {0}, bpassed = {0}; + struct qbe_value rtfunc = mkrtfunc(ctx, "rt.abort"); + struct gen_value msg; + + 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_value cond = gen_expr(ctx, expr->assert.cond); + struct qbe_value qcond = mkqval(ctx, &cond); + pushi(ctx->current, NULL, Q_JNZ, &qcond, &bpassed, &bfailed, NULL); + push(&ctx->current->body, &failedl); + msg = gen_expr(ctx, expr->assert.message); + } else { + msg = gen_expr(ctx, expr->assert.message); + } + + struct qbe_value qmsg = mkqval(ctx, &msg); + pushi(ctx->current, NULL, Q_CALL, &rtfunc, &qmsg, NULL); + + if (expr->assert.cond) { + push(&ctx->current->body, &passedl); + } + + return gv_void; +} + +static struct gen_value gen_expr_binarithm(struct gen_context *ctx, const struct expression *expr) { struct gen_value lvalue = gen_expr(ctx, expr->binarithm.lvalue); @@ -365,6 +405,7 @@ gen_const_string_at(struct gen_context *ctx, const char *val = constexpr->string.value; size_t len = constexpr->string.len; + // TODO: Generate string data structure as global also? struct qbe_value global = mkqtmp(ctx, ctx->arch.ptr, "strdata.%d"); global.kind = QV_GLOBAL; @@ -588,7 +629,9 @@ gen_expr(struct gen_context *ctx, const struct expression *expr) return gen_expr_access(ctx, expr); case EXPR_ALLOC: case EXPR_APPEND: + assert(0); // TODO case EXPR_ASSERT: + return gen_expr_assert(ctx, expr); case EXPR_ASSIGN: assert(0); // TODO case EXPR_BINARITHM: