[vala/staging] codegen: Add valid support for const multi-dimensional arrays



commit dff67ff218644f5d99ae7709046609dacf30f263
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Wed Jan 12 16:47:17 2011 +0100

    codegen: Add valid support for const multi-dimensional arrays
    
    For example this
      const int[,,] tri_numbers = {{{1, 2, 3}, {5, 5, 6}}, {{6, 7}}};
    correctly transfoms to
      const gint tri_numbers[2][2][3] = {{{1, 2, 3}, {5, 5, 6}}, {{6, 7}}};
    
    https://bugzilla.gnome.org/show_bug.cgi?id=604371

 codegen/valaccodebasemodule.vala         |   27 +++++++++++++++++++++++++--
 codegen/valaccodememberaccessmodule.vala |   10 +++++++---
 tests/Makefile.am                        |    1 +
 tests/basic-types/bug604371.vala         |   26 ++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 5 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 19174d1..d93db9c 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -902,6 +902,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                }
        }
 
+       private void constant_array_ranks_sizes (InitializerList initializer_list, int[] sizes, int rank = 0) 
{
+               sizes[rank] = int.max (sizes[rank], initializer_list.size);
+               rank++;
+               foreach (var expr in initializer_list.get_initializers()) {
+                       if (expr is InitializerList && ((InitializerList) expr).target_type is ArrayType) {
+                               constant_array_ranks_sizes ((InitializerList) expr, sizes, rank);
+                       }
+               }
+       }
+
        public void generate_constant_declaration (Constant c, CCodeFile decl_space, bool definition = false) 
{
                if (c.parent_symbol is Block) {
                        // local constant
@@ -922,7 +932,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                var cdecl = new CCodeDeclaration (get_ccode_const_name (c.type_reference));
                                var arr = "";
                                if (c.type_reference is ArrayType) {
-                                       arr = "[%d]".printf (initializer_list.size);
+                                       var array = (ArrayType) c.type_reference;
+                                       int[] sizes = new int[array.rank];
+                                       constant_array_ranks_sizes (initializer_list, sizes);
+                                       for (int i = 0; i < array.rank; i++) {
+                                               arr += "[%d]".printf (sizes[i]);
+                                       }
                                }
 
                                var cinitializer = get_cvalue (c.value);
@@ -960,7 +975,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        string type_name = get_ccode_const_name (c.type_reference);
                        string arr = "";
                        if (c.type_reference is ArrayType) {
-                               arr = "[]";
+                               var array = (ArrayType) c.type_reference;
+                               var initializer_list = c.value as InitializerList;
+                               if (initializer_list != null) {
+                                       int[] sizes = new int[array.rank];
+                                       constant_array_ranks_sizes (initializer_list, sizes);
+                                       for (int i = 0; i < array.rank; i++) {
+                                               arr += "[%d]".printf (sizes[i]);
+                                       }
+                               }
                        }
 
                        if (c.type_reference.compatible (string_type)) {
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 13d9d4a..f4eae3c 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -147,9 +147,13 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                        }
 
                        if (array_type != null) {
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_N_ELEMENTS"));
-                               ccall.add_argument (new CCodeIdentifier (get_ccode_name (c)));
-                               append_array_length (expr, ccall);
+                               string sub = "";
+                               for (int i = 0; i < array_type.rank; i++) {
+                                       var ccall = new CCodeFunctionCall (new CCodeIdentifier 
("G_N_ELEMENTS"));
+                                       ccall.add_argument (new CCodeIdentifier (get_ccode_name (c) + sub));
+                                       append_array_length (expr, ccall);
+                                       sub += "[0]";
+                               }
                        }
                } else if (expr.symbol_reference is Property) {
                        var prop = (Property) expr.symbol_reference;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f7ddab6..91769ab 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -28,6 +28,7 @@ TESTS = \
        basic-types/bug595751.vala \
        basic-types/bug596637.vala \
        basic-types/bug596785.vala \
+       basic-types/bug604371.vala \
        basic-types/bug622178.vala \
        basic-types/bug632322.vala \
        basic-types/bug643612.vala \
diff --git a/tests/basic-types/bug604371.vala b/tests/basic-types/bug604371.vala
new file mode 100644
index 0000000..d29b21a
--- /dev/null
+++ b/tests/basic-types/bug604371.vala
@@ -0,0 +1,26 @@
+const int[,] FOO = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 6, 7, 8 }, { 9 }};
+const string[,] BAR = { { "a", "b" }, { "c", "d" }, { "e", "f" }, { "g", "h", "i" }, { "j" }};
+
+void main () {
+       assert (FOO.length[0] == 5);
+       assert (FOO.length[1] == 3);
+       assert (FOO[0,1] == 2);
+       assert (FOO[3,2] == 8);
+
+       int[,] foo = FOO;
+       assert (foo.length[0] == 5);
+       assert (foo.length[1] == 3);
+       assert (foo[0,1] == 2);
+       assert (foo[3,2] == 8);
+
+       assert (BAR.length[0] == 5);
+       assert (BAR.length[1] == 3);
+       assert (BAR[0,1] == "b");
+       assert (BAR[3,2] == "i");
+
+       string[,] bar = BAR;
+       assert (bar.length[0] == 5);
+       assert (bar.length[1] == 3);
+       assert (bar[0,1] == "b");
+       assert (bar[3,2] == "i");
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]