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:
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