]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
dova: Convert Array to struct
authorJürg Billeter <j@bitron.ch>
Fri, 8 Apr 2011 19:21:11 +0000 (21:21 +0200)
committerJürg Billeter <j@bitron.ch>
Fri, 8 Apr 2011 19:34:05 +0000 (21:34 +0200)
codegen/valadovaarraymodule.vala
codegen/valadovabasemodule.vala
codegen/valadovamemberaccessmodule.vala
codegen/valadovaobjectmodule.vala
codegen/valadovavaluemodule.vala
vala/valaarraytype.vala
vala/valadeletestatement.vala

index ce249872c456eb19ab1a99e787f3ecbbad200be9..4a3150c6efbfbb58c9a819efcc56ccabbe3aa8eb 100644 (file)
@@ -1,6 +1,6 @@
 /* valadovaarraymodule.vala
  *
- * Copyright (C) 2006-2010  Jürg Billeter
+ * Copyright (C) 2006-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -46,9 +46,9 @@ public class Vala.DovaArrayModule : DovaMethodCallModule {
                        return;
                }
 
-               generate_method_declaration (array_class.default_construction_method, cfile);
+               generate_method_declaration ((Method) array_struct.scope.lookup ("create"), cfile);
 
-               var array_new = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_new"));
+               var array_new = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_create"));
                array_new.add_argument (get_type_id_expression (expr.element_type));
 
                // length of new array
@@ -73,4 +73,18 @@ public class Vala.DovaArrayModule : DovaMethodCallModule {
                // access to element in an array
                set_cvalue (expr, new CCodeElementAccess (ccontainer, cindex));
        }
+
+       public override void visit_slice_expression (SliceExpression expr) {
+               var ccontainer = get_cvalue (expr.container);
+               var cstart = get_cvalue (expr.start);
+               var cstop = get_cvalue (expr.stop);
+
+               var array_type = (ArrayType) expr.container.value_type;
+
+               var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array"));
+               array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (new CCodeMemberAccess (ccontainer, "data"), array_type.element_type.get_cname () + "*"), cstart));
+               array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, cstop, cstart));
+
+               set_cvalue (expr, array);
+       }
 }
index 3ddf0e7195341f1c4873edbd1062957d4c2c2bb5..d92ac98dd7adf826f9a59a64840e760786eaa368 100644 (file)
@@ -1,6 +1,6 @@
 /* valadovabasemodule.vala
  *
- * Copyright (C) 2006-2010  Jürg Billeter
+ * Copyright (C) 2006-2011  Jürg Billeter
  * Copyright (C) 2006-2008  Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
@@ -182,7 +182,7 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
        public Class type_class;
        public Class value_class;
        public Class string_class;
-       public Class array_class;
+       public Struct array_struct;
        public Class delegate_class;
        public Class error_class;
 
@@ -255,7 +255,7 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
                type_class = (Class) dova_ns.scope.lookup ("Type");
                value_class = (Class) dova_ns.scope.lookup ("Value");
                string_class = (Class) root_symbol.scope.lookup ("string");
-               array_class = (Class) dova_ns.scope.lookup ("Array");
+               array_struct = (Struct) dova_ns.scope.lookup ("Array");
                delegate_class = (Class) dova_ns.scope.lookup ("Delegate");
                error_class = (Class) dova_ns.scope.lookup ("Error");
 
@@ -1177,7 +1177,7 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
                        vardecl.init0 = true;
                } else if (!local.variable_type.nullable &&
                           (st != null && st.get_fields ().size > 0) ||
-                          (array_type != null && array_type.fixed_length)) {
+                          array_type != null) {
                        // 0-initialize struct with struct initializer { 0 }
                        // necessary as they will be passed by reference
                        var clist = new CCodeInitializerList ();
@@ -1279,15 +1279,29 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
        }
 
        public override void visit_delete_statement (DeleteStatement stmt) {
-               var pointer_type = (PointerType) stmt.expression.value_type;
-               DataType type = pointer_type;
-               if (pointer_type.base_type.data_type != null && pointer_type.base_type.data_type.is_reference_type ()) {
-                       type = pointer_type.base_type;
+               var pointer_type = stmt.expression.value_type as PointerType;
+               var array_type = stmt.expression.value_type as ArrayType;
+
+               if (pointer_type != null) {
+                       DataType type = pointer_type;
+                       if (pointer_type.base_type.data_type != null && pointer_type.base_type.data_type.is_reference_type ()) {
+                               type = pointer_type.base_type;
+                       }
+
+                       var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
+                       ccall.add_argument (get_cvalue (stmt.expression));
+                       ccode.add_expression (ccall);
+               } else if (array_type != null) {
+                       // TODO free elements
+                       var free_call = new CCodeFunctionCall (new CCodeIdentifier ("free"));
+                       free_call.add_argument (new CCodeMemberAccess (get_cvalue (stmt.expression), "data"));
+                       ccode.add_expression (free_call);
+
+                       ccode.add_assignment (new CCodeMemberAccess (get_cvalue (stmt.expression), "data"), new CCodeConstant ("NULL"));
+                       ccode.add_assignment (new CCodeMemberAccess (get_cvalue (stmt.expression), "length"), new CCodeConstant ("0"));
+               } else {
+                       assert_not_reached ();
                }
-
-               var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
-               ccall.add_argument (get_cvalue (stmt.expression));
-               ccode.add_expression (ccall);
        }
 
        public override void visit_expression (Expression expr) {
@@ -1826,6 +1840,14 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
                        return;
                }
 
+               if (expr.inner.value_type is ArrayType && expr.type_reference is PointerType) {
+                       var array_type = (ArrayType) expr.inner.value_type;
+                       if (!array_type.fixed_length) {
+                               set_cvalue (expr, new CCodeMemberAccess (get_cvalue (expr.inner), "data"));
+                               return;
+                       }
+               }
+
                generate_type_declaration (expr.type_reference, cfile);
 
                if (expr.inner.value_type is GenericType && !(expr.type_reference is GenericType)) {
@@ -2018,10 +2040,41 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
                }
 
                if (expression_type is NullType) {
+                       if (target_type is ArrayType) {
+                               var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array"));
+                               array.add_argument (new CCodeConstant ("NULL"));
+                               array.add_argument (new CCodeConstant ("0"));
+                               return array;
+                       }
+
                        // null literal, no cast required when not converting to generic type pointer
                        return cexpr;
                }
 
+               if (expression_type is ArrayType && target_type is PointerType) {
+                       var array_type = (ArrayType) expression_type;
+                       if (!array_type.inline_allocated) {
+                               return new CCodeMemberAccess (cexpr, "data");
+                       }
+               }
+
+               if (expression_type is ArrayType && target_type is ArrayType) {
+                       var source_array_type = (ArrayType) expression_type;
+                       var target_array_type = (ArrayType) target_type;
+                       if (source_array_type.inline_allocated && !target_array_type.inline_allocated) {
+                               var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array"));
+                               array.add_argument (cexpr);
+
+                               var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+                               csizeof.add_argument (cexpr);
+                               var csizeofelement = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+                               csizeofelement.add_argument (new CCodeElementAccess (cexpr, new CCodeConstant ("0")));
+                               array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.DIV, csizeof, csizeofelement));
+
+                               return array;
+                       }
+               }
+
                generate_type_declaration (target_type, cfile);
 
                if (target_type is DelegateType && expression_type is MethodType) {
@@ -2209,7 +2262,7 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
                        return memset_call;
                } else if (initializer_expression && !type.nullable &&
                    ((st != null && st.get_fields ().size > 0) ||
-                    (array_type != null && array_type.fixed_length))) {
+                    array_type != null)) {
                        // 0-initialize struct with struct initializer { 0 }
                        // only allowed as initializer expression in C
                        var clist = new CCodeInitializerList ();
@@ -2217,8 +2270,7 @@ public abstract class Vala.DovaBaseModule : CodeGenerator {
                        return clist;
                } else if ((type.data_type != null && type.data_type.is_reference_type ())
                           || type.nullable
-                          || type is PointerType || type is DelegateType
-                          || (array_type != null && !array_type.fixed_length)) {
+                          || type is PointerType || type is DelegateType) {
                        return new CCodeConstant ("NULL");
                } else if (type.data_type != null && type.data_type.get_default_value () != null) {
                        return new CCodeConstant (type.data_type.get_default_value ());
index 20629fb88bcd6a0b774f7f8df0b3e3133ac9412a..3a235486d9b717b7118c308d7c0c6f85a5cf6054 100644 (file)
@@ -1,6 +1,6 @@
 /* valadovamemberaccessmodule.vala
  *
- * Copyright (C) 2006-2010  Jürg Billeter
+ * Copyright (C) 2006-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -91,11 +91,16 @@ public abstract class Vala.DovaMemberAccessModule : DovaControlFlowModule {
                                set_cvalue (expr, new CCodeIdentifier (m.get_cname ()));
                        }
                } else if (expr.symbol_reference is ArrayLengthField) {
-                       generate_property_accessor_declaration (((Property) array_class.scope.lookup ("length")).get_accessor, cfile);
-
-                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_length"));
-                       ccall.add_argument (pub_inst);
-                       set_cvalue (expr, ccall);
+                       var array_type = (ArrayType) expr.inner.value_type;
+                       if (array_type.fixed_length) {
+                               var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+                               csizeof.add_argument (pub_inst);
+                               var csizeofelement = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+                               csizeofelement.add_argument (new CCodeElementAccess (pub_inst, new CCodeConstant ("0")));
+                               set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.DIV, csizeof, csizeofelement));
+                       } else {
+                               set_cvalue (expr, new CCodeMemberAccess (pub_inst, "length"));
+                       }
                } else if (expr.symbol_reference is Field) {
                        var f = (Field) expr.symbol_reference;
                        expr.target_value = load_field (f, expr.inner != null ? expr.inner.target_value : null);
index 65f17b88b59758d858b9ff628ecd52759e27d697..eec278fd6a5501634c38841d5079bd13dfca5352 100644 (file)
@@ -1,6 +1,6 @@
 /* valadovaobjectmodule.vala
  *
- * Copyright (C) 2009-2010  Jürg Billeter
+ * Copyright (C) 2009-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1274,10 +1274,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
 
                        push_function (function);
 
-                       if (acc.result_var != null) {
-                               acc.result_var.accept (this);
-                       }
-
                        acc.body.emit (this);
 
                        if (acc.readable) {
@@ -1496,10 +1492,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
                                        }
                                }
 
-                               if (m.result_var != null) {
-                                       m.result_var.accept (this);
-                               }
-
                                m.body.emit (this);
 
                                if (!(m.return_type is VoidType) && !(m.return_type is GenericType)) {
@@ -1655,7 +1647,7 @@ public class Vala.DovaObjectModule : DovaArrayModule {
                pop_context ();
 
                if (m.entry_point) {
-                       generate_type_declaration (new ObjectType (array_class), cfile);
+                       generate_type_declaration (new StructValueType (array_struct), cfile);
 
                        // m is possible entry point, add appropriate startup code
                        var cmain = new CCodeFunction ("main", "int");
@@ -1962,10 +1954,7 @@ public class Vala.DovaObjectModule : DovaArrayModule {
                                        set_cvalue (expr, new CCodeElementAccess (get_cvalue (expr.container), cindex));
                                }
                        } else {
-                               generate_property_accessor_declaration (((Property) array_class.scope.lookup ("data")).get_accessor, cfile);
-
-                               var ccontainer = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
-                               ccontainer.add_argument (get_cvalue (expr.container));
+                               var ccontainer = new CCodeMemberAccess (get_cvalue (expr.container), "data");
 
                                if (array_type.element_type is GenericType) {
                                        // generic array
index 3f0d287502ec50ab696642c50164ae4178a008c3..dee99af5cf7b9d341c43a4b3002b1679119b62f5 100644 (file)
@@ -395,11 +395,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
 
                        var array_type = dest.value_type as ArrayType;
                        if (array_type != null && !array_type.inline_allocated) {
-                               generate_property_accessor_declaration (((Property) array_class.scope.lookup ("data")).get_accessor, cfile);
-
-                               var data_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
-                               data_call.add_argument ((CCodeExpression) get_ccodenode (dest));
-                               cdest = data_call;
+                               cdest = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (dest), "data");
                        } else {
                                cdest = (CCodeExpression) get_ccodenode (dest);
                        }
@@ -413,11 +409,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
 
                        var array_type = src.value_type as ArrayType;
                        if (array_type != null && !array_type.inline_allocated) {
-                               generate_property_accessor_declaration (((Property) array_class.scope.lookup ("data")).get_accessor, cfile);
-
-                               var data_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
-                               data_call.add_argument ((CCodeExpression) get_ccodenode (src));
-                               csrc = data_call;
+                               csrc = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (src), "data");
                        } else {
                                csrc = (CCodeExpression) get_ccodenode (src);
                        }
@@ -480,22 +472,14 @@ public class Vala.DovaValueModule : DovaObjectModule {
                var right_ea = expr.right as ElementAccess;
 
                if (left_ea != null) {
-                       generate_property_accessor_declaration (((Property) array_class.scope.lookup ("data")).get_accessor, cfile);
-
-                       var data_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
-                       data_call.add_argument ((CCodeExpression) get_ccodenode (left_ea.container));
-                       cleft = data_call;
+                       cleft = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (left_ea.container), "data");
                        left_index = (CCodeExpression) get_ccodenode (left_ea.get_indices ().get (0));
                } else {
                        cleft = (CCodeExpression) get_ccodenode (expr.left);
                }
 
                if (right_ea != null) {
-                       generate_property_accessor_declaration (((Property) array_class.scope.lookup ("data")).get_accessor, cfile);
-
-                       var data_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
-                       data_call.add_argument ((CCodeExpression) get_ccodenode (right_ea.container));
-                       cright = data_call;
+                       cright = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (right_ea.container), "data");
                        right_index = (CCodeExpression) get_ccodenode (right_ea.get_indices ().get (0));
                } else {
                        cright = (CCodeExpression) get_ccodenode (expr.right);
@@ -535,11 +519,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
                        if (val_ea != null) {
                                val = val_ea.container;
 
-                               generate_property_accessor_declaration (((Property) array_class.scope.lookup ("data")).get_accessor, cfile);
-
-                               var data_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
-                               data_call.add_argument ((CCodeExpression) get_ccodenode (val));
-                               cval = data_call;
+                               cval = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (val), "data");
                                val_index = (CCodeExpression) get_ccodenode (val_ea.get_indices ().get (0));
                        } else {
                                cval = (CCodeExpression) get_ccodenode (val);
@@ -555,11 +535,11 @@ public class Vala.DovaValueModule : DovaObjectModule {
        }
 
        public override void visit_list_literal (ListLiteral expr) {
-               var ce = new CCodeCommaExpression ();
+               CCodeExpression ptr;
                int length = expr.get_expressions ().size;
 
                if (length == 0) {
-                       ce.append_expression (new CCodeConstant ("NULL"));
+                       ptr = new CCodeConstant ("NULL");
                } else {
                        var array_type = new ArrayType (expr.element_type, 1, expr.source_reference);
                        array_type.inline_allocated = true;
@@ -573,17 +553,29 @@ public class Vala.DovaValueModule : DovaObjectModule {
 
                        int i = 0;
                        foreach (Expression e in expr.get_expressions ()) {
-                               ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e)));
+                               ccode.add_assignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e));
                                i++;
                        }
 
-                       ce.append_expression (name_cnode);
+                       ptr = name_cnode;
                }
 
+               var array_type = new ArrayType (expr.element_type, 1, expr.source_reference);
+
+               var temp_var = get_temp_variable (array_type, true, expr);
+               var name_cnode = get_variable_cexpression (temp_var.name);
+
+               emit_temp_var (temp_var);
+
+               var array_init = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_init"));
+               array_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, name_cnode));
+               array_init.add_argument (ptr);
+               array_init.add_argument (new CCodeConstant (length.to_string ()));
+               ccode.add_expression (array_init);
+
                var list_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_list_new"));
                list_creation.add_argument (get_type_id_expression (expr.element_type));
-               list_creation.add_argument (new CCodeConstant (length.to_string ()));
-               list_creation.add_argument (ce);
+               list_creation.add_argument (name_cnode);
 
                set_cvalue (expr, list_creation);
        }
index 5ed4ff68377c9df0773be639ba24cbd2e1e3d30f..ed284105fc617dba061a6fb06f9f66025636a07e 100644 (file)
@@ -1,6 +1,6 @@
 /* valaarraytype.vala
  *
- * Copyright (C) 2007-2010  Jürg Billeter
+ * Copyright (C) 2007-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -66,9 +66,7 @@ public class Vala.ArrayType : ReferenceType {
        }
 
        public override Symbol? get_member (string member_name) {
-               if (CodeContext.get ().profile == Profile.DOVA) {
-                       return SemanticAnalyzer.symbol_lookup_inherited (CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Array"), member_name);
-               } else if (member_name == "length") {
+               if (member_name == "length") {
                        return get_length_field ();
                } else if (member_name == "move") {
                        return get_move_method ();
@@ -155,7 +153,7 @@ public class Vala.ArrayType : ReferenceType {
                        return element_type.get_cname ();
                } else {
                        if (CodeContext.get ().profile == Profile.DOVA) {
-                               return "DovaArray*";
+                               return "DovaArray";
                        } else {
                                return element_type.get_cname () + "*";
                        }
@@ -271,6 +269,8 @@ public class Vala.ArrayType : ReferenceType {
        public override bool is_disposable () {
                if (fixed_length) {
                        return element_type.is_disposable ();
+               } else if (CodeContext.get ().profile == Profile.DOVA) {
+                       return false;
                } else {
                        return base.is_disposable ();
                }
index bb8da392297f2eca78ab5c2122c6f0ef3b382121..056b317652103156bc25fcbb3a01e84aa7051cbb 100644 (file)
@@ -1,6 +1,6 @@
 /* valadeletestatement.vala
  *
- * Copyright (C) 2008-2010  Jürg Billeter
+ * Copyright (C) 2008-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -54,7 +54,7 @@ public class Vala.DeleteStatement : CodeNode, Statement {
                        return false;
                }
 
-               if (!(expression.value_type is PointerType)) {
+               if (!(expression.value_type is PointerType) && !(expression.value_type is ArrayType)) {
                        error = true;
                        Report.error (source_reference, "delete operator not supported for `%s'".printf (expression.value_type.to_string ()));
                }