harec

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

commit f30c0be4ab4de8202fdc3e6f4e1bd117f85f5bc9
parent 3fdebb5635f4d7e58a11ad7797dc56cae2700cb6
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri,  2 Jul 2021 12:33:26 -0400

gen: implement basic assignments

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

Diffstat:
Msrc/gen.c | 65++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/qtype.c | 1-
2 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -156,37 +156,61 @@ gen_copy(struct gen_context *ctx, } static void gen_expr(struct gen_context *ctx, - const struct expression *expr, struct gen_temp *out); + const struct expression *expr, const struct gen_temp *out); -static void -gen_access_object(struct gen_context *ctx, - const struct scope_object *obj, - struct gen_temp *out) +static const struct gen_temp * +gen_address_object(struct gen_context *ctx, + const struct scope_object *obj) { const struct gen_binding *binding = binding_lookup(ctx, obj); - gen_copy(ctx, out, &binding->temp); + return &binding->temp; } -static void -gen_expr_access(struct gen_context *ctx, - const struct expression *expr, - struct gen_temp *out) +static const struct gen_temp * +gen_access_address(struct gen_context *ctx, + const struct expression *expr) { switch (expr->access.type) { case ACCESS_IDENTIFIER: - gen_access_object(ctx, expr->access.object, out); - break; + return gen_address_object(ctx, expr->access.object); case ACCESS_INDEX: case ACCESS_FIELD: case ACCESS_TUPLE: assert(0); // TODO } + abort(); // Invariant +} + +static void +gen_expr_access(struct gen_context *ctx, + const struct expression *expr, + const struct gen_temp *out) +{ + const struct gen_temp *src = gen_access_address(ctx, expr); + gen_copy(ctx, out, src); +} + +static void +gen_expr_assign(struct gen_context *ctx, + const struct expression *expr, + const struct gen_temp *out) +{ + const struct expression *object = expr->assign.object; + const struct expression *value = expr->assign.value; + if (object->type == EXPR_SLICE) { + assert(0); // TODO + } + assert(!expr->assign.indirect); // TODO + + assert(object->type == EXPR_ACCESS); // Invariant + const struct gen_temp *obj = gen_access_address(ctx, object); + gen_expr(ctx, value, obj); } static void gen_expr_binding(struct gen_context *ctx, const struct expression *expr, - struct gen_temp *out) + const struct gen_temp *out) { for (const struct expression_binding *binding = &expr->binding; binding; binding = binding->next) { @@ -206,7 +230,7 @@ gen_expr_binding(struct gen_context *ctx, static void gen_expr_constant(struct gen_context *ctx, const struct expression *expr, - struct gen_temp *out) + const struct gen_temp *out) { if (out == NULL) { pushc(ctx->current, "Useless constant expression dropped"); @@ -283,7 +307,7 @@ gen_expr_constant(struct gen_context *ctx, static void gen_expr_list(struct gen_context *ctx, const struct expression *expr, - struct gen_temp *out) + const struct gen_temp *out) { for (const struct expressions *item = &expr->list.exprs; item; item = item->next) { @@ -298,7 +322,7 @@ gen_expr_list(struct gen_context *ctx, static void gen_expr_return(struct gen_context *ctx, const struct expression *expr, - struct gen_temp *out) + const struct gen_temp *out) { struct qbe_value label = { .kind = QV_LABEL, @@ -313,7 +337,7 @@ gen_expr_return(struct gen_context *ctx, static void gen_expr_struct(struct gen_context *ctx, const struct expression *expr, - struct gen_temp *out) + const struct gen_temp *out) { if (!out) { pushc(ctx->current, "Useless struct expression dropped"); @@ -357,7 +381,7 @@ gen_expr_struct(struct gen_context *ctx, static void gen_expr(struct gen_context *ctx, const struct expression *expr, - struct gen_temp *out) + const struct gen_temp *out) { switch (expr->type) { case EXPR_ACCESS: @@ -366,7 +390,10 @@ gen_expr(struct gen_context *ctx, case EXPR_ALLOC: case EXPR_APPEND: case EXPR_ASSERT: + assert(0); // TODO case EXPR_ASSIGN: + gen_expr_assign(ctx, expr, out); + break; case EXPR_BINARITHM: assert(0); // TODO case EXPR_BINDING: @@ -437,7 +464,7 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) if (type_dealias(fntype->func.result)->storage != STORAGE_VOID) { ctx->rval = xcalloc(1, sizeof(struct gen_temp)); alloc_temp(ctx, ctx->rval, fntype->func.result, "rval.%d"); - qdef->func.returns = qtype_lookup(ctx, fntype->func.result, true); + qdef->func.returns = qtype_lookup(ctx, fntype->func.result, false); } else { qdef->func.returns = &qbe_void; } diff --git a/src/qtype.c b/src/qtype.c @@ -149,7 +149,6 @@ const struct qbe_type *qtype_lookup( case STORAGE_TAGGED: case STORAGE_TUPLE: case STORAGE_UNION: - assert(xtype); return aggregate_lookup(ctx, type); case STORAGE_VOID: case STORAGE_FUNCTION: