harec

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

commit 0334cdb175e881bdb56bf2b151d7ab92e2e7651a
parent ebe5d7e418e12e025a2c062141949634e2778d1e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu,  5 Aug 2021 11:08:20 +0200

gen: implement measurements

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

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

diff --git a/src/gen.c b/src/gen.c @@ -710,6 +710,52 @@ gen_expr_list_with(struct gen_context *ctx, } static struct gen_value +gen_expr_measure(struct gen_context *ctx, const struct expression *expr) +{ + size_t len; + struct gen_value gv, temp; + const struct expression *value = expr->measure.value; + switch (expr->measure.op) { + case M_LEN: + switch (type_dealias(value->result)->storage) { + case STORAGE_ARRAY: + len = type_dealias(value->result)->array.length; + assert(len != SIZE_UNDEFINED); + return (struct gen_value){ + .kind = GV_CONST, + .type = &builtin_type_size, + .lval = len, + }; + case STORAGE_SLICE: + case STORAGE_STRING: + gv = gen_expr(ctx, value); + gv = gen_autoderef(ctx, gv); + temp = mktemp(ctx, &builtin_type_size, ".%d"); + struct qbe_value qv = mkqval(ctx, &gv), + qtemp = mkqval(ctx, &temp), + offs = constl(builtin_type_size.size); + enum qbe_instr load = load_for_type(ctx, + &builtin_type_size); + pushi(ctx->current, &qtemp, Q_ADD, &qv, &offs, NULL); + pushi(ctx->current, &qtemp, load, &qtemp, NULL); + return temp; + default: + abort(); // Invariant + } + break; + case M_SIZE: + return (struct gen_value){ + .kind = GV_CONST, + .type = &builtin_type_size, + .lval = expr->measure.type->size, + }; + case M_OFFSET: + assert(0); // TODO + } + abort(); // Invariant +} + +static struct gen_value gen_expr_return(struct gen_context *ctx, const struct expression *expr) { // TODO: Run defers @@ -838,8 +884,9 @@ gen_expr(struct gen_context *ctx, const struct expression *expr) case EXPR_LIST: return gen_expr_list_with(ctx, expr, NULL); case EXPR_MATCH: - case EXPR_MEASURE: assert(0); // TODO + case EXPR_MEASURE: + return gen_expr_measure(ctx, expr); case EXPR_PROPAGATE: assert(0); // Lowered in check (for now?) case EXPR_RETURN: