From b0af78b88c674cbc552e348bc3703e792650d1d7 Mon Sep 17 00:00:00 2001
From: kugwa <kugwa2000@gmail.com>
Date: Tue, 19 Jan 2016 11:14:46 +0800
Subject: Fix the problem of initializing local variables

---
 src/code-generation.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

(limited to 'src/code-generation.c')

diff --git a/src/code-generation.c b/src/code-generation.c
index 7bc3416..a2d93da 100644
--- a/src/code-generation.c
+++ b/src/code-generation.c
@@ -991,10 +991,6 @@ static uint64_t generate_local_variable(
         CcmmcSymbol *var_sym = ccmmc_symbol_table_retrieve(state->table,
             var_decl->value_id.name);
         switch (var_decl->value_id.kind) {
-            case CCMMC_KIND_ID_NORMAL:
-                current_offset += 4;
-                var_sym->attr.addr = current_offset;
-                break;
             case CCMMC_KIND_ID_ARRAY: {
                 size_t total_elements = 1;
                 assert(var_sym->type.array_dimension > 0);
@@ -1003,15 +999,11 @@ static uint64_t generate_local_variable(
                 current_offset += total_elements * 4;
                 var_sym->attr.addr = current_offset;
                 } break;
-            case CCMMC_KIND_ID_WITH_INIT: {
+            case CCMMC_KIND_ID_NORMAL:
+            case CCMMC_KIND_ID_WITH_INIT:
                 current_offset += 4;
                 var_sym->attr.addr = current_offset;
-                // FIXME: This only works for single constant initializer.
-                // The value of sp is wrong, so evaluating expressions
-                // can overwrite other variables!
-                calc_and_save_expression_result(var_decl, var_decl->child,
-                    state, &current_offset);
-                } break;
+                break;
             default:
                 assert(false);
         }
@@ -1019,6 +1011,17 @@ static uint64_t generate_local_variable(
     return current_offset;
 }
 
+static void init_local_variable(
+    CcmmcAst *local_decl, CcmmcState *state, uint64_t current_offset)
+{
+    for (CcmmcAst *var_decl = local_decl->child->right_sibling;
+         var_decl != NULL; var_decl = var_decl->right_sibling) {
+        if (var_decl->value_id.kind == CCMMC_KIND_ID_WITH_INIT)
+            calc_and_save_expression_result(var_decl, var_decl->child,
+                state, &current_offset);
+    }
+}
+
 static void generate_block(
     CcmmcAst *block, CcmmcState *state, uint64_t current_offset)
 {
@@ -1043,6 +1046,8 @@ static void generate_block(
 #undef REG_TMP
             }
         }
+        for (CcmmcAst *local = child->child; local != NULL; local = local->right_sibling)
+            init_local_variable(local, state, current_offset);
         child = child->right_sibling;
     }
     if (child != NULL && child->type_node == CCMMC_AST_NODE_STMT_LIST) {
-- 
cgit