[vala] Support equality checking on nullable boolean and numeric types



commit 5a597f879078b5785489dfcaa316b78bae033bcc
Author: Jürg Billeter <j bitron ch>
Date:   Fri Jan 29 17:23:29 2010 +0100

    Support equality checking on nullable boolean and numeric types
    
    Fixes bug 608434.

 codegen/valaccodebasemodule.vala |   68 ++++++++++++++++++++++++++++++++++++-
 vala/valabinaryexpression.vala   |   14 ++++++++
 2 files changed, 80 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a374679..af186bd 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2471,6 +2471,62 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		return equal_func;
 	}
 
+	private string generate_numeric_equal_function (Struct st) {
+		string equal_func = "_%sequal".printf (st.get_lower_case_cprefix ());
+
+		if (!add_wrapper (equal_func)) {
+			// wrapper already defined
+			return equal_func;
+		}
+		// declaration
+
+		var function = new CCodeFunction (equal_func, "gboolean");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("s1", "const " + st.get_cname () + "*"));
+		function.add_parameter (new CCodeFormalParameter ("s2", "const " + st.get_cname () + "*"));
+
+		// definition
+		var cblock = new CCodeBlock ();
+
+		// if (s1 == s2) return TRUE;
+		{
+			var block = new CCodeBlock ();
+			block.add_statement (new CCodeReturnStatement (new CCodeConstant ("TRUE")));
+
+			var cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("s1"), new CCodeIdentifier ("s2"));
+			var cif = new CCodeIfStatement (cexp, block);
+			cblock.add_statement (cif);
+		}
+		// if (s1 == NULL || s2 == NULL) return FALSE;
+		{
+			var block = new CCodeBlock ();
+			block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+
+			var cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("s1"), new CCodeConstant ("NULL"));
+			var cif = new CCodeIfStatement (cexp, block);
+			cblock.add_statement (cif);
+
+			cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("s2"), new CCodeConstant ("NULL"));
+			cif = new CCodeIfStatement (cexp, block);
+			cblock.add_statement (cif);
+		}
+		// return (*s1 == *s2);
+		{
+			var cexp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("s1")), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("s2")));
+			cblock.add_statement (new CCodeReturnStatement (cexp));
+		}
+
+		// append to file
+
+		source_declarations.add_type_member_declaration (function.copy ());
+
+		function.block = cblock;
+		source_type_member_definition.append (function);
+
+		return equal_func;
+	}
+
 	private string generate_struct_dup_wrapper (ValueType value_type) {
 		string dup_func = "_%sdup".printf (value_type.type_symbol.get_lower_case_cprefix ());
 
@@ -4335,8 +4391,8 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		
 		if (expr.operator == BinaryOperator.EQUALITY ||
 		    expr.operator == BinaryOperator.INEQUALITY) {
-			var left_type = expr.left.value_type;
-			var right_type = expr.right.value_type;
+			var left_type = expr.left.target_type;
+			var right_type = expr.right.target_type;
 			make_comparable_cexpression (ref left_type, ref cleft, ref right_type, ref cright);
 
 			if (left_type is StructValueType && right_type is StructValueType) {
@@ -4346,6 +4402,14 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 				ccall.add_argument (cright);
 				cleft = ccall;
 				cright = new CCodeConstant ("TRUE");
+			} else if ((left_type is IntegerType || left_type is FloatingType || left_type is BooleanType) && left_type.nullable &&
+			           (right_type is IntegerType || right_type is FloatingType || right_type is BooleanType) && right_type.nullable) {
+				var equalfunc = generate_numeric_equal_function ((Struct) left_type.data_type as Struct);
+				var ccall = new CCodeFunctionCall (new CCodeIdentifier (equalfunc));
+				ccall.add_argument (cleft);
+				ccall.add_argument (cright);
+				cleft = ccall;
+				cright = new CCodeConstant ("TRUE");
 			}
 		}
 
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 2747723..53dda1c 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -323,6 +323,20 @@ public class Vala.BinaryExpression : Expression {
 				return false;
 			}
 
+			left.target_type = left.value_type.copy ();
+			left.target_type.value_owned = false;
+			right.target_type = right.value_type.copy ();
+			right.target_type.value_owned = false;
+
+			if (left.value_type.nullable != right.value_type.nullable) {
+				// if only one operand is nullable, make sure the other operand is promoted to nullable as well
+				if (!left.value_type.nullable) {
+					left.target_type.nullable = true;
+				} else if (!right.value_type.nullable) {
+					right.target_type.nullable = true;
+				}
+			}
+
 			if (left.value_type.compatible (analyzer.string_type)
 			    && right.value_type.compatible (analyzer.string_type)) {
 				// string comparison



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