harec

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

commit 8b00f7222527f071a7f4b00b07c884acf7285107
parent 56853be54d30eded69604d2d6efd3cefd6e1e805
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 23 Dec 2020 13:44:24 -0500

gen: implement assignment

Not 100% positive about this, we need to expand this for pointers and
aggregate types ASAP to be confident that we've covered all of our
bases.

Diffstat:
Msrc/check.c | 1+
Msrc/gen.c | 26++++++++++++++++++++++++--
Mtodo.txt | 5++---
3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -59,6 +59,7 @@ check_expr_assign(struct context *ctx, { trace(TR_CHECK, "assign"); expr->type = EXPR_ASSIGN; + expr->result = &builtin_type_void; expr->assign.indirect = aexpr->assign.indirect; expr->assign.object = calloc(1, sizeof(struct expression)); expr->assign.value = calloc(1, sizeof(struct expression)); diff --git a/src/gen.c b/src/gen.c @@ -110,7 +110,6 @@ gen_store(struct gen_context *ctx, if (dest->indirect) { assert(!src->indirect); // XXX: Correct? - assert(dest->type == &qbe_long); // XXX: ARCH pushi(ctx->current, NULL, store_for_type(qtype->stype), src, dest, NULL); } else { pushi(ctx->current, dest, Q_COPY, src, NULL); @@ -165,6 +164,27 @@ gen_access(struct gen_context *ctx, } static void +gen_assign(struct gen_context *ctx, + const struct expression *expr, + const struct qbe_value *out) +{ + assert(out == NULL); // Invariant + assert(!expr->assign.indirect); // TODO + + const struct expression *object = expr->assign.object; + const struct expression *value = expr->assign.value; + assert(object->type == EXPR_ACCESS); // Invariant + + // TODO: When this grows to support e.g. indexing expressions, we need + // to ensure that the side-effects of the lvalue occur before the + // side-effects of the rvalue. + const struct scope_object *obj = object->access.object; + struct qbe_value src; + qval_for_object(ctx, &src, obj); + gen_expression(ctx, value, &src); +} + +static void gen_binding(struct gen_context *ctx, const struct expression *expr, const struct qbe_value *out) @@ -285,8 +305,10 @@ gen_expression(struct gen_context *ctx, gen_access(ctx, expr, out); break; case EXPR_ASSERT: - case EXPR_ASSIGN: assert(0); // TODO + case EXPR_ASSIGN: + gen_assign(ctx, expr, out); + break; case EXPR_BINARITHM: gen_binarithm(ctx, expr, out); break; diff --git a/todo.txt b/todo.txt @@ -1,7 +1,7 @@ highest priorities, unordered except where there are obvious dependencies: -- variable assignment -- simple binary and unary arithmetic +- simple unary arithmetic +- pointers - aggregate types - in parameters - in variables @@ -9,7 +9,6 @@ highest priorities, unordered except where there are obvious dependencies: - field access, indexing - function calls - static let -- pointers This subset of features should allow us to address most of the problems with gen that v1 suffered from, and end up with a solid basis from which we can