[vala] dova: Convert Array to struct



commit 2a3f71d2bbed0c1be6075e4d59b5ecfb342ed3a4
Author: Jürg Billeter <j bitron ch>
Date:   Fri Apr 8 21:21:11 2011 +0200

    dova: Convert Array to struct

 codegen/valadovaarraymodule.vala        |   20 ++++++-
 codegen/valadovabasemodule.vala         |   82 +++++++++++++++++++++++++------
 codegen/valadovamemberaccessmodule.vala |   17 ++++--
 codegen/valadovaobjectmodule.vala       |   17 +-----
 codegen/valadovavaluemodule.vala        |   54 +++++++++------------
 vala/valaarraytype.vala                 |   10 ++--
 vala/valadeletestatement.vala           |    4 +-
 7 files changed, 128 insertions(+), 76 deletions(-)
---
diff --git a/codegen/valadovaarraymodule.vala b/codegen/valadovaarraymodule.vala
index ce24987..4a3150c 100644
--- a/codegen/valadovaarraymodule.vala
+++ b/codegen/valadovaarraymodule.vala
@@ -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);
+	}
 }
diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala
index 3ddf0e7..d92ac98 100644
--- a/codegen/valadovabasemodule.vala
+++ b/codegen/valadovabasemodule.vala
@@ -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 ());
diff --git a/codegen/valadovamemberaccessmodule.vala b/codegen/valadovamemberaccessmodule.vala
index 20629fb..3a23548 100644
--- a/codegen/valadovamemberaccessmodule.vala
+++ b/codegen/valadovamemberaccessmodule.vala
@@ -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);
diff --git a/codegen/valadovaobjectmodule.vala b/codegen/valadovaobjectmodule.vala
index 65f17b8..eec278f 100644
--- a/codegen/valadovaobjectmodule.vala
+++ b/codegen/valadovaobjectmodule.vala
@@ -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
diff --git a/codegen/valadovavaluemodule.vala b/codegen/valadovavaluemodule.vala
index 3f0d287..dee99af 100644
--- a/codegen/valadovavaluemodule.vala
+++ b/codegen/valadovavaluemodule.vala
@@ -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);
 	}
diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala
index 5ed4ff6..ed28410 100644
--- a/vala/valaarraytype.vala
+++ b/vala/valaarraytype.vala
@@ -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 ();
 		}
diff --git a/vala/valadeletestatement.vala b/vala/valadeletestatement.vala
index bb8da39..056b317 100644
--- a/vala/valadeletestatement.vala
+++ b/vala/valadeletestatement.vala
@@ -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 ()));
 		}



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