2008-04-09 Jb Evain <jbevain@novell.com>
authorJb Evain <jbevain@gmail.com>
Wed, 9 Apr 2008 11:44:47 +0000 (11:44 -0000)
committerJb Evain <jbevain@gmail.com>
Wed, 9 Apr 2008 11:44:47 +0000 (11:44 -0000)
* UnaryExpression.cs, Expression.cs: implement IsLifted and IsLifted
to null for simple unary operators. Implement Not compilation.

svn path=/trunk/mcs/; revision=100215

mcs/class/System.Core/System.Linq.Expressions/ChangeLog
mcs/class/System.Core/System.Linq.Expressions/Expression.cs
mcs/class/System.Core/System.Linq.Expressions/UnaryExpression.cs

index a47318836f4d4016947da7b2e61fb9fc37cd69c5..b2b161e48dad3a9aac4950008b1ad2fc2df0fe1a 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-09  Jb Evain  <jbevain@novell.com>
+
+       * UnaryExpression.cs, Expression.cs: implement IsLifted and IsLifted
+       to null for simple unary operators. Implement Not compilation.
+
 2008-04-08  Jb Evain  <jbevain@novell.com>
 
        * ElementInit.cs: emit pop if the add method doesn't return void.
index d7fbfdf1905771b0f500b01df61efe9a392a8154..a37068d069cd94dd8fc0fb8752c8c1ab32f13b51 100644 (file)
@@ -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);
                }
 
index d3e44b5d1d1cc7f36f6e95d40b5fc94c767168cb..721d2a7c5d8dc7484626556dea8b9e4fcff0a57a 100644 (file)
@@ -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 ());
                        }