Ver Fonte

2008-04-09 Jb Evain <[email protected]>

	* UnaryExpression.cs, Expression.cs: implement IsLifted and IsLifted
	to null for simple unary operators. Implement Not compilation.


svn path=/trunk/mcs/; revision=100215
Jb Evain há 17 anos atrás
pai
commit
e083f12ffc

+ 5 - 0
mcs/class/System.Core/System.Linq.Expressions/ChangeLog

@@ -1,3 +1,8 @@
+2008-04-09  Jb Evain  <[email protected]>
+
+	* UnaryExpression.cs, Expression.cs: implement IsLifted and IsLifted
+	to null for simple unary operators. Implement Not compilation.
+
 2008-04-08  Jb Evain  <[email protected]>
 
 	* ElementInit.cs: emit pop if the add method doesn't return void.

+ 19 - 5
mcs/class/System.Core/System.Linq.Expressions/Expression.cs

@@ -117,11 +117,13 @@ namespace System.Linq.Expressions {
 
 				return method;
 			} else {
-				if (IsNumber (expression.Type))
+				var type = GetNotNullableOf (expression.Type);
+
+				if (IsIntOrBool (type))
 					return null;
 
 				if (oper_name != null) {
-					method = GetUnaryOperator (oper_name, expression.Type, expression);
+					method = GetUnaryOperator (oper_name, GetNotNullableOf (type), expression);
 					if (method != null)
 						return method;
 				}
@@ -286,7 +288,16 @@ namespace System.Linq.Expressions {
 
 		static UnaryExpression MakeSimpleUnary (ExpressionType et, Expression expression, MethodInfo method)
 		{
-			return new UnaryExpression (et, expression, GetResultType (expression, method), method);
+			bool is_lifted;
+
+			if (method == null) {
+				is_lifted = IsNullable (expression.Type);
+			} else {
+				// FIXME: implement
+				is_lifted = false;
+			}
+
+			return new UnaryExpression (et, expression, GetResultType (expression, method), method, is_lifted);
 		}
 
 		static BinaryExpression MakeBoolBinary (ExpressionType et, Expression left, Expression right, bool liftToNull, MethodInfo method)
@@ -1029,7 +1040,7 @@ namespace System.Linq.Expressions {
 
 			// TODO: check for valid convertions
 
-			return new UnaryExpression (ExpressionType.Convert, expression, type, method);
+			return new UnaryExpression (ExpressionType.Convert, expression, type, method, false);
 		}
 
 		public static UnaryExpression ConvertChecked (Expression expression, Type type)
@@ -1047,7 +1058,7 @@ namespace System.Linq.Expressions {
 
 			// TODO: check for valid convertions
 
-			return new UnaryExpression (ExpressionType.ConvertChecked, expression, type, method);
+			return new UnaryExpression (ExpressionType.ConvertChecked, expression, type, method, false);
 		}
 
 		public static ElementInit ElementInit (MethodInfo addMethod, params Expression [] arguments)
@@ -1711,6 +1722,9 @@ namespace System.Linq.Expressions {
 		{
 			method = UnaryCoreCheck ("op_LogicalNot", expression, method);
 
+			if (method == null)
+				method = UnaryCoreCheck ("op_OnesComplement", expression, method);
+
 			return MakeSimpleUnary (ExpressionType.Not, expression, method);
 		}
 

+ 31 - 5
mcs/class/System.Core/System.Linq.Expressions/UnaryExpression.cs

@@ -36,6 +36,8 @@ namespace System.Linq.Expressions {
 
 		Expression operand;
 		MethodInfo method;
+		bool is_lifted;
+		bool is_lifted_to_null;
 
 		public Expression Operand {
 			get { return operand; }
@@ -45,14 +47,12 @@ namespace System.Linq.Expressions {
 			get { return method; }
 		}
 
-		[MonoTODO]
 		public bool IsLifted {
-			get { throw new NotImplementedException (); }
+			get { return is_lifted; }
 		}
 
-		[MonoTODO]
 		public bool IsLiftedToNull {
-			get { throw new NotImplementedException (); }
+			get { return is_lifted_to_null; }
 		}
 
 		internal UnaryExpression (ExpressionType node_type, Expression operand)
@@ -67,11 +67,13 @@ namespace System.Linq.Expressions {
 			this.operand = operand;
 		}
 
-		internal UnaryExpression (ExpressionType node_type, Expression operand, Type type, MethodInfo method)
+		internal UnaryExpression (ExpressionType node_type, Expression operand, Type type, MethodInfo method, bool is_lifted)
 			: base (node_type, type)
 		{
 			this.operand = operand;
 			this.method = method;
+			this.is_lifted = is_lifted;
+			this.is_lifted_to_null = is_lifted;
 		}
 
 		void EmitArrayLength (EmitContext ec)
@@ -90,6 +92,21 @@ namespace System.Linq.Expressions {
 				ec.ig.Emit (OpCodes.Unbox_Any, type);
 		}
 
+		void EmitUnaryOperator (EmitContext ec)
+		{
+			var ig = ec.ig;
+
+			switch (NodeType) {
+			case ExpressionType.Not:
+				if (GetNotNullableOf (operand.Type) == typeof (bool)) {
+					ig.Emit (OpCodes.Ldc_I4_0);
+					ig.Emit (OpCodes.Ceq);
+				} else
+					ig.Emit (OpCodes.Not);
+				break;
+			}
+		}
+
 		internal override void Emit (EmitContext ec)
 		{
 			switch (this.NodeType) {
@@ -99,6 +116,15 @@ namespace System.Linq.Expressions {
 			case ExpressionType.TypeAs:
 				EmitTypeAs (ec);
 				return;
+			case ExpressionType.Not:
+				if (!is_lifted) {
+					operand.Emit (ec);
+					EmitUnaryOperator (ec);
+				} else
+					throw new NotImplementedException ();
+				return;
+			case ExpressionType.UnaryPlus:
+				return;
 			default:
 				throw new NotImplementedException (this.NodeType.ToString ());
 			}