]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
ast_store_codegen and its l/rvalue handling
authorWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 2 May 2012 18:36:11 +0000 (20:36 +0200)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 2 May 2012 18:36:11 +0000 (20:36 +0200)
ast.c

diff --git a/ast.c b/ast.c
index 25e742858562a1f8ef6748b8f8b8654f839c3fc8..7fa27f5b3c4188a6897749987de79456b5fc14d2 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -487,8 +487,32 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu
 
 bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_value **out)
 {
-    /* NOTE: remember: destination codegen needs to have lvalue=true */
-    return false;
+    ast_expression_codegen *cgen;
+    ir_value *left, *right;
+
+    cgen = self->dest->expression.codegen;
+    /* lvalue! */
+    if (!(*cgen)((ast_expression*)(self->dest), func, true, &left))
+        return false;
+
+    cgen = self->source->expression.codegen;
+    /* rvalue! */
+    if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
+        return false;
+
+    if (!ir_block_create_store_op(func->curblock, self->op, left, right))
+        return false;
+
+    /* Theoretically, an assinment returns its left side as an
+     * lvalue, if we don't need an lvalue though, we return
+     * the right side as an rvalue, otherwise we have to
+     * somehow know whether or not we need to dereference the pointer
+     * on the left side - that is: OP_LOAD if it was an address.
+     * Also: in original QC we cannot OP_LOADP *anyway*.
+     */
+    *out = (lvalue ? left : right);
+
+    return true;
 }
 
 bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_value **out)