merge 99630:99762
[mono.git] / mcs / tests / gtest-etree-01.cs
index 0f07eaa16c058acb0b41b3558ba3dcbd0be530dd..c19d638895709fe6fbc2951d98216ad36a82a388 100644 (file)
@@ -22,7 +22,8 @@ public struct InverseLogicalOperator
        }
 }
 
-/*
+/* TODO: Add tests for every numeric expression where a type has only 1 implicit
+               numeric conversion
 public struct MyType<T>
 {
        T value;
@@ -39,6 +40,10 @@ public struct MyType<T>
 }
 */
 
+
+// TODO: Create a clone which uses +(MyType, int) pattern and an implicit conversion
+// is required to do the user-conversion
+
 public struct MyType
 {
        int value;
@@ -47,6 +52,11 @@ public struct MyType
        {
                this.value = value;
        }
+       
+       public override int GetHashCode ()
+       {
+               throw new NotImplementedException ();
+       }
 
        public static implicit operator int (MyType o)
        {
@@ -63,16 +73,31 @@ public struct MyType
                return a.value != a;
        }
 
-       //public static implicit operator MyType (int i)
-       //{
-       //    return new MyType (i);
-       //}
-
-       public static MyType operator +(MyType a, MyType b)
+       public static MyType operator + (MyType a, MyType b)
        {
                return new MyType (a.value + b.value);
        }
 
+       public static MyType operator - (MyType a, MyType b)
+       {
+               return new MyType (a.value - b.value);
+       }
+
+       public static MyType operator / (MyType a, MyType b)
+       {
+               return new MyType (a.value / b.value);
+       }
+
+       public static MyType operator * (MyType a, MyType b)
+       {
+               return new MyType (a.value * b.value);
+       }
+
+       public static MyType operator % (MyType a, MyType b)
+       {
+               return new MyType (a.value % b.value);
+       }
+
        public static MyType operator &(MyType a, MyType b)
        {
                return new MyType (a.value & b.value);
@@ -83,12 +108,80 @@ public struct MyType
                return new MyType (a.value | b.value);
        }
 
+       public static MyType operator ^ (MyType a, MyType b)
+       {
+               return new MyType (a.value ^ b.value);
+       }
+
+       public static bool operator == (MyType a, MyType b)
+       {
+               return a.value == b.value;
+       }
+
+       public static bool operator != (MyType a, MyType b)
+       {
+               return a.value != b.value;
+       }
+       
+       public static bool operator > (MyType a, MyType b)
+       {
+               return a.value > b.value;
+       }
+
+       public static bool operator < (MyType a, MyType b)
+       {
+               return a.value < b.value;
+       }
+
+       public static bool operator >= (MyType a, MyType b)
+       {
+               return a.value >= b.value;
+       }
+       
+       public static bool operator <= (MyType a, MyType b)
+       {
+               return a.value <= b.value;
+       }
+
+       public static bool operator ! (MyType a)
+       {
+               return a.value > 0;
+       }
+
+       public static int operator >> (MyType a, int b)
+       {
+               return a.value >> b;
+       }
+       
+       public static int operator << (MyType a, int b)
+       {
+               return a.value << b;
+       }
+
        public override string ToString ()
        {
                return value.ToString ();
        }
 }
 
+
+class MyTypeExplicit
+{
+       int value;
+       
+       public MyTypeExplicit (int value)
+       {
+               this.value = value;
+       }
+       
+       public static explicit operator int (MyTypeExplicit m)
+       {
+               return m.value;
+       }
+}
+
+// TODO: Add more nullable tests, follow AddTest pattern.
+
 class Tester
 {
        static void AssertNodeType (LambdaExpression e, ExpressionType et)
@@ -99,8 +192,16 @@ class Tester
 
        static void Assert<T> (T expected, T value)
        {
-               if (!EqualityComparer<T>.Default.Equals (expected, value))
-                       throw new ApplicationException (expected + " != " + value);
+               Assert (expected, value, null);
+       }
+
+       static void Assert<T> (T expected, T value, string name)
+       {
+               if (!EqualityComparer<T>.Default.Equals (expected, value)) {
+                       if (!string.IsNullOrEmpty (name))
+                               name += ": ";
+                       throw new ApplicationException (name + expected + " != " + value);
+               }
        }
 
        static void Assert<T> (T [] expected, T [] value)
@@ -126,8 +227,20 @@ class Tester
 
                Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a + b;
                AssertNodeType (e3, ExpressionType.Add);
-// FIXME: type inference
-//             Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
+               Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
+
+               Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a + b;
+               AssertNodeType (e4, ExpressionType.Add);
+               Assert (new MyType (10), e4.Compile ().Invoke (new MyType (-20), new MyType (30)));
+               Assert (null, e4.Compile ().Invoke (null, new MyType (30)));
+
+               Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a + b;
+               AssertNodeType (e5, ExpressionType.Add);
+               Assert (31, e5.Compile ().Invoke (1, new MyType (30)));
+
+               Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a + b;
+               AssertNodeType (e6, ExpressionType.Add);
+               Assert (-1, e6.Compile ().Invoke (-31, new MyType (30)));
        }
 
        void AddCheckedTest ()
@@ -143,10 +256,31 @@ class Tester
 
                Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a + b;
                AssertNodeType (e3, ExpressionType.Add);
-// FIXME: type inference
-//             Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
+               Assert (10, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
                }
        }
+       
+       void AddStringTest ()
+       {
+               Expression<Func<string, string>> e6 = (a) => 1 + a;
+               AssertNodeType (e6, ExpressionType.Add);
+               Assert ("1to", e6.Compile ().Invoke ("to"));
+       
+               Expression<Func<object, string, string>> e7 = (object a, string b) => a + b;
+               AssertNodeType (e7, ExpressionType.Add);
+               Assert ("testme", e7.Compile ().Invoke ("test", "me"));
+               Assert ("test", e7.Compile ().Invoke ("test", null));
+               Assert ("", e7.Compile ().Invoke (null, null));
+
+               Expression<Func<string, int, string>> e8 = (a, b) => a + " " + "-" + "> " + b;
+               AssertNodeType (e8, ExpressionType.Add);
+               Assert ("test -> 2", e8.Compile ().Invoke ("test", 2));
+
+               Expression<Func<string, ushort?, string>> e9 = (a, b) => a + b;
+               AssertNodeType (e9, ExpressionType.Add);
+               Assert ("test2", e9.Compile ().Invoke ("test", 2));
+               Assert ("test", e9.Compile ().Invoke ("test", null));   
+       }
 
        void AndTest ()
        {
@@ -200,15 +334,18 @@ class Tester
        void AndAlsoTest ()
        {
                Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a && b;
-
                AssertNodeType (e, ExpressionType.AndAlso);
                Assert (false, e.Compile ().Invoke (true, false));
 
                Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a && b;
-
                AssertNodeType (e2, ExpressionType.AndAlso);
                Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64)));
                Assert (new MyType (0), e2.Compile ().Invoke (new MyType (32), new MyType (64)));
+
+               Expression<Func<bool, bool>> e3 = (bool a) => a && true;
+               AssertNodeType (e3, ExpressionType.AndAlso);
+               Assert (false, e3.Compile ().Invoke (false));
+               Assert (true, e3.Compile ().Invoke (true));
        }
 
        void ArrayIndexTest ()
@@ -236,8 +373,6 @@ class Tester
 
        void ArrayLengthTest ()
        {
-               int o = new int [0].Length;
-
                Expression<Func<double [], int>> e = (double [] a) => a.Length;
                AssertNodeType (e, ExpressionType.ArrayLength);
                Assert (0, e.Compile ().Invoke (new double [0]));
@@ -271,6 +406,9 @@ class Tester
                Expression<Func<int, int>> e5 = (int a) => GenericMethod (a);
                AssertNodeType (e5, ExpressionType.Call);
                Assert (5, e5.Compile ().Invoke (5));
+               
+               Expression<Action> e6 = () => Console.WriteLine ("call test");
+               AssertNodeType (e6, ExpressionType.Call);
        }
 
        void CoalesceTest ()
@@ -315,8 +453,35 @@ class Tester
                Assert (3, r4.Invoke (new InverseLogicalOperator (true), 3, 4));
                Assert (4, r4.Invoke (new InverseLogicalOperator (false), 3, 4));
        }
+       
+       void ConstantTest ()
+       {
+               Expression<Func<int>> e1 = () => default (int);
+               AssertNodeType (e1, ExpressionType.Constant);
+               Assert (0, e1.Compile ().Invoke ());
+
+               Expression<Func<int?>> e2 = () => default (int?);
+               AssertNodeType (e2, ExpressionType.Constant);
+               Assert (null, e2.Compile ().Invoke ());
+               
+               Expression<Func<Tester>> e3 = () => default (Tester);
+               AssertNodeType (e3, ExpressionType.Constant);
+               Assert (null, e3.Compile ().Invoke ());
+               
+               Expression<Func<object>> e4 = () => null;
+               AssertNodeType (e4, ExpressionType.Constant);
+               Assert (null, e4.Compile ().Invoke ());
+
+               Expression<Func<int>> e5 = () => 8 / 4;
+               AssertNodeType (e5, ExpressionType.Constant);
+               Assert (2, e5.Compile ().Invoke ());
+
+               Expression<Func<int>> e6 = () => 0xFFFFFF >> 0x40;
+               AssertNodeType (e6, ExpressionType.Constant);
+               Assert (0xFFFFFF, e6.Compile ().Invoke ());
+       }
 
-       public void ConvertTest ()
+       void ConvertTest ()
        {
                Expression<Func<int, byte>> e = (int a) => ((byte) a);
                AssertNodeType (e, ExpressionType.Convert);
@@ -333,9 +498,25 @@ class Tester
                Expression<Func<MyType, int>> e4 = (MyType a) => (a);
                AssertNodeType (e4, ExpressionType.Convert);
                Assert (-9, e4.Compile ().Invoke (new MyType (-9)));
+
+               Expression<Func<MyType, MyType, bool?>> e5 = (MyType a, MyType b) => a == b;
+               AssertNodeType (e5, ExpressionType.Convert);
+
+               Expression<Func<MyType?, MyType?, bool?>> e6 = (MyType? a, MyType? b) => a == b;
+               AssertNodeType (e6, ExpressionType.Convert);
+               Assert (false, e6.Compile ().Invoke (null, new MyType (-20)));
+               Assert (true, e6.Compile ().Invoke (null, null));
+               Assert (true, e6.Compile ().Invoke (new MyType (120), new MyType (120)));
+               
+               // TODO: redundant return conversion
+               // Expression<Func<MyTypeExplicit, int?>> e6 = x => (int?)x;
+               
+               // TODO: redundant convert
+               // TODO: pass null value
+               // Expression<Func<int?, object>> ex = x => (object)x;
        }
 
-       public void ConvertCheckedTest ()
+       void ConvertCheckedTest ()
        {
                Expression<Func<int, byte>> e = (int a) => checked((byte) a);
                AssertNodeType (e, ExpressionType.ConvertChecked);
@@ -356,6 +537,377 @@ class Tester
                }
        }
 
+       void DivideTest ()
+       {
+               Expression<Func<int, int, int>> e = (int a, int b) => a / b;
+               AssertNodeType (e, ExpressionType.Divide);
+               Assert (2, e.Compile ().Invoke (60, 30));
+
+               Expression<Func<double?, double?, double?>> e2 = (a, b) => a / b;
+               AssertNodeType (e2, ExpressionType.Divide);
+               Assert (null, e2.Compile ().Invoke (null, 3));
+               Assert (1.5, e2.Compile ().Invoke (3, 2));
+
+               Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a / b;
+               AssertNodeType (e3, ExpressionType.Divide);
+               Assert (1, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a / b;
+               AssertNodeType (e4, ExpressionType.Divide);
+               Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (new MyType (-6), e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
+
+               Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a / b;
+               AssertNodeType (e5, ExpressionType.Divide);
+               Assert (50, e5.Compile ().Invoke (100, new MyType (2)));
+               
+               Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a / b;
+               AssertNodeType (e6, ExpressionType.Divide);
+               Assert (50, e6.Compile ().Invoke (100, new MyType (2)));
+               Assert (null, e6.Compile ().Invoke (20, null));
+       }
+
+       void EqualTest ()
+       {
+               Expression<Func<int, int, bool>> e = (int a, int b) => a == b;
+               AssertNodeType (e, ExpressionType.Equal);
+               Assert (false, e.Compile ().Invoke (60, 30));
+               Assert (true, e.Compile ().Invoke (-1, -1));
+
+               Expression<Func<double?, double?, bool>> e2 = (a, b) => a == b;
+               AssertNodeType (e2, ExpressionType.Equal);
+               Assert (true, e2.Compile ().Invoke (3, 3));
+               Assert (false, e2.Compile ().Invoke (3, 2));
+
+               Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a == b;
+               AssertNodeType (e3, ExpressionType.Equal);
+               Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a == b;
+               AssertNodeType (e4, ExpressionType.Equal);
+               Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (true, e4.Compile ().Invoke (null, null));
+               Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (120)));
+
+               Expression<Func<bool?, bool?, bool>> e5 = (bool? a, bool? b) => a == b;
+               AssertNodeType (e5, ExpressionType.Equal);
+               Assert (false, e5.Compile ().Invoke (true, null));
+               Assert (true, e5.Compile ().Invoke (null, null));
+               Assert (true, e5.Compile ().Invoke (false, false));
+               
+               Expression<Func<bool, bool>> e6 = (bool a) => a == null;
+               AssertNodeType (e6, ExpressionType.Equal);
+               Assert (false, e6.Compile ().Invoke (true));
+               Assert (false, e6.Compile ().Invoke (false));
+
+               Expression<Func<string, string, bool>> e7 = (string a, string b) => a == b;
+               AssertNodeType (e7, ExpressionType.Equal);
+               Assert (true, e7.Compile ().Invoke (null, null));
+               Assert (false, e7.Compile ().Invoke ("a", "A"));
+               Assert (true, e7.Compile ().Invoke ("a", "a"));
+
+               Expression<Func<object, bool>> e8 = (object a) => null == a;
+               AssertNodeType (e8, ExpressionType.Equal);
+               Assert (true, e8.Compile ().Invoke (null));
+               Assert (false, e8.Compile ().Invoke ("a"));
+               Assert (false, e8.Compile ().Invoke (this));
+       }
+
+       delegate void EmptyDelegate ();
+       
+       void EqualTestDelegate ()
+       {
+               Expression<Func<Delegate, Delegate, bool>> e1 = (a, b) => a == b;
+               AssertNodeType (e1, ExpressionType.Equal);
+               Assert (true, e1.Compile ().Invoke (null, null));
+
+               EmptyDelegate ed = delegate () {};
+
+               Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
+               AssertNodeType (e2, ExpressionType.Equal);
+               Assert (false, e2.Compile ().Invoke (delegate () {}, null));
+               Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
+               Assert (false, e2.Compile ().Invoke (ed, delegate {}));
+               Assert (true, e2.Compile ().Invoke (ed, ed));
+       }       
+
+       void ExclusiveOrTest ()
+       {
+               Expression<Func<int, short, int>> e = (int a, short b) => a ^ b;
+               AssertNodeType (e, ExpressionType.ExclusiveOr);
+               Assert (34, e.Compile ().Invoke (60, 30));
+
+               Expression<Func<byte?, byte?, int?>> e2 = (a, b) => a ^ b;
+               AssertNodeType (e2, ExpressionType.ExclusiveOr);
+               Assert (null, e2.Compile ().Invoke (null, 3));
+               Assert (1, e2.Compile ().Invoke (3, 2));
+
+               Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a ^ b;
+               AssertNodeType (e3, ExpressionType.ExclusiveOr);
+               Assert (0, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a ^ b;
+               AssertNodeType (e4, ExpressionType.ExclusiveOr);
+               Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (new MyType (-108), e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
+
+               Expression<Func<MyType?, byte, int?>> e5 = (MyType? a, byte b) => a ^ b;
+               AssertNodeType (e5, ExpressionType.ExclusiveOr);
+               Assert (null, e5.Compile ().Invoke (null, 64));
+               Assert (96, e5.Compile ().Invoke (new MyType (64), 32));
+       }
+
+       void GreaterThanTest ()
+       {
+               Expression<Func<int, int, bool>> e = (int a, int b) => a > b;
+               AssertNodeType (e, ExpressionType.GreaterThan);
+               Assert (true, e.Compile ().Invoke (60, 30));
+
+               Expression<Func<uint?, byte?, bool>> e2 = (a, b) => a > b;
+               AssertNodeType (e2, ExpressionType.GreaterThan);
+               Assert (false, e2.Compile ().Invoke (null, 3));
+               Assert (false, e2.Compile ().Invoke (2, 2));
+
+               Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a > b;
+               AssertNodeType (e3, ExpressionType.GreaterThan);
+               Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a > b;
+               AssertNodeType (e4, ExpressionType.GreaterThan);
+               Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (false, e4.Compile ().Invoke (null, null));
+               Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
+
+               Expression<Func<MyType?, sbyte, bool>> e5 = (MyType? a, sbyte b) => a > b;
+               AssertNodeType (e5, ExpressionType.GreaterThan);
+               Assert (false, e5.Compile ().Invoke (null, 33));
+               Assert (false, e5.Compile ().Invoke (null, 0));
+               Assert (true, e5.Compile ().Invoke (new MyType (120), 3));
+
+               Expression<Func<ushort, bool>> e6 = (ushort a) => a > null;
+               AssertNodeType (e6, ExpressionType.GreaterThan);
+               Assert (false, e6.Compile ().Invoke (60));
+       }
+
+       void GreaterThanOrEqualTest ()
+       {
+               Expression<Func<int, int, bool>> e = (int a, int b) => a >= b;
+               AssertNodeType (e, ExpressionType.GreaterThanOrEqual);
+               Assert (true, e.Compile ().Invoke (60, 30));
+
+               Expression<Func<byte?, byte?, bool>> e2 = (a, b) => a >= b;
+               AssertNodeType (e2, ExpressionType.GreaterThanOrEqual);
+               Assert (false, e2.Compile ().Invoke (null, 3));
+               Assert (true, e2.Compile ().Invoke (2, 2));
+
+               Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a >= b;
+               AssertNodeType (e3, ExpressionType.GreaterThanOrEqual);
+               Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)), "D1");
+
+               Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a >= b;
+               AssertNodeType (e4, ExpressionType.GreaterThanOrEqual);
+               Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (false, e4.Compile ().Invoke (null, null));
+               Assert (true, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
+
+               Expression<Func<MyType?, sbyte, bool>> e5 = (MyType? a, sbyte b) => a >= b;
+               AssertNodeType (e5, ExpressionType.GreaterThanOrEqual);
+               Assert (false, e5.Compile ().Invoke (null, 33));
+               Assert (false, e5.Compile ().Invoke (null, 0));
+               Assert (true, e5.Compile ().Invoke (new MyType (120), 3));
+
+               Expression<Func<ushort, bool>> e6 = (ushort a) => a >= null;
+               AssertNodeType (e6, ExpressionType.GreaterThanOrEqual);
+               Assert (false, e6.Compile ().Invoke (60));
+       }
+       
+       void LeftShiftTest ()
+       {
+               Expression<Func<ulong, short, ulong>> e = (ulong a, short b) => a << b;
+               AssertNodeType (e, ExpressionType.LeftShift);
+               Assert ((ulong) 0x7F000, e.Compile ().Invoke (0xFE, 11));
+               Assert ((ulong) 0xFFFFFFFE00000000, e.Compile ().Invoke (0xFFFFFFFF, 0xA01));
+
+               Expression<Func<MyType, MyType, int>> e2 = (MyType a, MyType b) => a << b;
+               AssertNodeType (e2, ExpressionType.LeftShift);
+               var c2 = e2.Compile ();
+               Assert (1024, c2 (new MyType (256), new MyType (2)));
+
+               Expression<Func<long?, sbyte, long?>> e3 = (long? a, sbyte b) => a << b;
+               AssertNodeType (e3, ExpressionType.LeftShift);
+               Assert (null, e3.Compile ().Invoke (null, 11));
+               Assert (2048, e3.Compile ().Invoke (1024, 1));
+
+               Expression<Func<MyType?, MyType?, int?>> e4 = (MyType? a, MyType? b) => a << b;
+               AssertNodeType (e4, ExpressionType.LeftShift);
+               var c4 = e4.Compile ();
+               Assert (null, c4 (new MyType (8), null));
+               Assert (null, c4 (null, new MyType (8)));
+               Assert (1024, c4 (new MyType (256), new MyType (2)));
+
+               Expression<Func<ushort, int?>> e5 = (ushort a) => a << null;
+               AssertNodeType (e5, ExpressionType.LeftShift);
+               Assert (null, e5.Compile ().Invoke (30));
+       }
+       
+       void LessThanTest ()
+       {
+               Expression<Func<int, int, bool>> e = (int a, int b) => a < b;
+               AssertNodeType (e, ExpressionType.LessThan);
+               Assert (false, e.Compile ().Invoke (60, 30));
+
+               Expression<Func<uint?, byte?, bool>> e2 = (a, b) => a < b;
+               AssertNodeType (e2, ExpressionType.LessThan);
+               Assert (false, e2.Compile ().Invoke (null, 3));
+               Assert (false, e2.Compile ().Invoke (2, 2));
+
+               Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a < b;
+               AssertNodeType (e3, ExpressionType.LessThan);
+               Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a < b;
+               AssertNodeType (e4, ExpressionType.LessThan);
+               Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (false, e4.Compile ().Invoke (null, null));
+               Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
+
+               Expression<Func<MyType?, sbyte, bool>> e5 = (MyType? a, sbyte b) => a < b;
+               AssertNodeType (e5, ExpressionType.LessThan);
+               Assert (false, e5.Compile ().Invoke (null, 33));
+               Assert (false, e5.Compile ().Invoke (null, 0));
+               Assert (false, e5.Compile ().Invoke (new MyType (120), 3));
+
+               Expression<Func<ushort, bool>> e6 = (ushort a) => a < null;
+               AssertNodeType (e6, ExpressionType.LessThan);
+               Assert (false, e6.Compile ().Invoke (60));
+       }
+
+       void LessThanOrEqualTest ()
+       {
+               Expression<Func<int, int, bool>> e = (int a, int b) => a <= b;
+               AssertNodeType (e, ExpressionType.LessThanOrEqual);
+               Assert (false, e.Compile ().Invoke (60, 30));
+
+               Expression<Func<byte?, byte?, bool>> e2 = (a, b) => a <= b;
+               AssertNodeType (e2, ExpressionType.LessThanOrEqual);
+               Assert (false, e2.Compile ().Invoke (null, 3));
+               Assert (true, e2.Compile ().Invoke (2, 2));
+
+               Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a <= b;
+               AssertNodeType (e3, ExpressionType.LessThanOrEqual);
+               Assert (true, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a <= b;
+               AssertNodeType (e4, ExpressionType.LessThanOrEqual);
+               Assert (false, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (false, e4.Compile ().Invoke (null, null));
+               Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (-20)));
+
+               Expression<Func<MyType?, sbyte, bool>> e5 = (MyType? a, sbyte b) => a <= b;
+               AssertNodeType (e5, ExpressionType.LessThanOrEqual);
+               Assert (false, e5.Compile ().Invoke (null, 33));
+               Assert (false, e5.Compile ().Invoke (null, 0));
+               Assert (false, e5.Compile ().Invoke (new MyType (120), 3));
+
+               Expression<Func<ushort, bool>> e6 = (ushort a) => a <= null;
+               AssertNodeType (e6, ExpressionType.LessThanOrEqual);
+               Assert (false, e6.Compile ().Invoke (60));
+       }
+
+       void ModuloTest ()
+       {
+               Expression<Func<int, int, int>> e = (int a, int b) => a % b;
+               AssertNodeType (e, ExpressionType.Modulo);
+               Assert (29, e.Compile ().Invoke (60, 31));
+
+               Expression<Func<double?, double?, double?>> e2 = (a, b) => a % b;
+               AssertNodeType (e2, ExpressionType.Modulo);
+               Assert (null, e2.Compile ().Invoke (null, 3));
+               Assert (1.1, e2.Compile ().Invoke (3.1, 2));
+
+               Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a % b;
+               AssertNodeType (e3, ExpressionType.Modulo);
+               Assert (0, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a % b;
+               AssertNodeType (e4, ExpressionType.Modulo);
+               Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (new MyType (12), e4.Compile ().Invoke (new MyType (12), new MyType (-20)));
+
+               Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a % b;
+               AssertNodeType (e5, ExpressionType.Modulo);
+               Assert (1, e5.Compile ().Invoke (99, new MyType (2)));
+
+               Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a % b;
+               AssertNodeType (e6, ExpressionType.Modulo);
+               Assert (100, e6.Compile ().Invoke (100, new MyType (200)));
+               Assert (null, e6.Compile ().Invoke (20, null));
+               
+               Expression<Func<ushort, int?>> e7 = (ushort a) => a % null;
+               AssertNodeType (e7, ExpressionType.Modulo);
+               Assert (null, e7.Compile ().Invoke (60));
+       }
+       
+       void MultiplyTest ()
+       {
+               Expression<Func<int, int, int>> e = (int a, int b) => a * b;
+               AssertNodeType (e, ExpressionType.Multiply);
+               Assert (1860, e.Compile ().Invoke (60, 31));
+               Assert (2147483617, e.Compile ().Invoke (int.MaxValue, 31));
+
+               Expression<Func<double?, double?, double?>> e2 = (a, b) => a * b;
+               AssertNodeType (e2, ExpressionType.Multiply);
+               Assert (null, e2.Compile ().Invoke (null, 3));
+               Assert (6.2, e2.Compile ().Invoke (3.1, 2));
+
+               Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a * b;
+               AssertNodeType (e3, ExpressionType.Multiply);
+               Assert (400, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a * b;
+               AssertNodeType (e4, ExpressionType.Multiply);
+               Assert (null, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (new MyType (-240), e4.Compile ().Invoke (new MyType (12), new MyType (-20)));
+
+               Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a * b;
+               AssertNodeType (e5, ExpressionType.Multiply);
+               Assert (198, e5.Compile ().Invoke (99, new MyType (2)));
+
+               Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a * b;
+               AssertNodeType (e6, ExpressionType.Multiply);
+               Assert (0, e6.Compile ().Invoke (int.MinValue, new MyType (200)));
+               Assert (null, e6.Compile ().Invoke (20, null));
+
+               Expression<Func<ushort, int?>> e7 = (ushort a) => a * null;
+               AssertNodeType (e7, ExpressionType.Multiply);
+               Assert (null, e7.Compile ().Invoke (60));
+       }
+       
+       void MultiplyCheckedTest ()
+       {
+               checked {
+                       Expression<Func<int, int, int>> e = (int a, int b) => a * b;
+                       AssertNodeType (e, ExpressionType.MultiplyChecked);
+                       try {
+                               e.Compile ().Invoke (int.MaxValue, 309);
+                               throw new ApplicationException ("MultiplyCheckedTest #1");
+                       } catch (OverflowException) { }
+
+                       Expression<Func<byte?, byte?, int?>> e2 = (a, b) => a * b;
+                       AssertNodeType (e2, ExpressionType.MultiplyChecked);
+                       Assert (null, e2.Compile ().Invoke (null, 3));
+                       Assert (14025, e2.Compile ().Invoke (byte.MaxValue, 55));
+
+                       Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a * b;
+                       AssertNodeType (e3, ExpressionType.Multiply);
+                       Assert (-600, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
+
+                       Expression<Func<double, double, double>> e4 = (a, b) => a * b;
+                       AssertNodeType (e4, ExpressionType.Multiply);
+                       Assert (double.PositiveInfinity, e4.Compile ().Invoke (double.MaxValue, int.MaxValue));
+               }
+       }       
+       
        void NewArrayInitTest ()
        {
                Expression<Func<int []>> e = () => new int [0];
@@ -375,6 +927,77 @@ class Tester
                Assert (new char [] { 'a' }, e3.Compile ().Invoke () [0]);
        }
 
+       void NotTest ()
+       {
+               Expression<Func<bool, bool>> e = (bool a) => !a;
+               AssertNodeType (e, ExpressionType.Not);
+               Assert (false, e.Compile ().Invoke (true));
+
+               Expression<Func<MyType, bool>> e2 = (MyType a) => !a;
+               AssertNodeType (e2, ExpressionType.Not);
+               Assert (true, e2.Compile ().Invoke (new MyType (1)));
+               Assert (false, e2.Compile ().Invoke (new MyType (-1)));
+       }
+
+       void NotNullableTest ()
+       {
+               Expression<Func<bool?, bool?>> e = (bool? a) => !a;
+               AssertNodeType (e, ExpressionType.Not);
+               Assert (false, e.Compile ().Invoke (true));
+               Assert (null, e.Compile ().Invoke (null));
+
+               Expression<Func<MyType?, bool?>> e2 = (MyType? a) => !a;
+               AssertNodeType (e2, ExpressionType.Not);
+               Assert (true, e2.Compile ().Invoke (new MyType (1)));
+               Assert (null, e2.Compile ().Invoke (null));
+       }
+
+       void NotEqualTest ()
+       {
+               Expression<Func<int, int, bool>> e = (int a, int b) => a != b;
+               AssertNodeType (e, ExpressionType.NotEqual);
+               Assert (true, e.Compile ().Invoke (60, 30));
+               Assert (false, e.Compile ().Invoke (-1, -1));
+
+               Expression<Func<sbyte?, sbyte?, bool>> e2 = (a, b) => a != b;
+               AssertNodeType (e2, ExpressionType.NotEqual);
+               Assert (false, e2.Compile ().Invoke (3, 3));
+               Assert (true, e2.Compile ().Invoke (3, 2));
+
+               Expression<Func<MyType, MyType, bool>> e3 = (MyType a, MyType b) => a != b;
+               AssertNodeType (e3, ExpressionType.NotEqual);
+               Assert (false, e3.Compile ().Invoke (new MyType (-20), new MyType (-20)));
+
+               Expression<Func<MyType?, MyType?, bool>> e4 = (MyType? a, MyType? b) => a != b;
+               AssertNodeType (e4, ExpressionType.NotEqual);
+               Assert (true, e4.Compile ().Invoke (null, new MyType (-20)));
+               Assert (false, e4.Compile ().Invoke (null, null));
+               Assert (false, e4.Compile ().Invoke (new MyType (120), new MyType (120)));
+
+               Expression<Func<bool?, bool?, bool>> e5 = (bool? a, bool? b) => a != b;
+               AssertNodeType (e5, ExpressionType.NotEqual);
+               Assert (true, e5.Compile ().Invoke (true, null));
+               Assert (false, e5.Compile ().Invoke (null, null));
+               Assert (false, e5.Compile ().Invoke (false, false));
+
+               Expression<Func<bool, bool>> e6 = (bool a) => a != null;
+               AssertNodeType (e6, ExpressionType.NotEqual);
+               Assert (true, e6.Compile ().Invoke (true));
+               Assert (true, e6.Compile ().Invoke (false));
+
+               Expression<Func<string, string, bool>> e7 = (string a, string b) => a != b;
+               AssertNodeType (e7, ExpressionType.NotEqual);
+               Assert (false, e7.Compile ().Invoke (null, null));
+               Assert (true, e7.Compile ().Invoke ("a", "A"));
+               Assert (false, e7.Compile ().Invoke ("a", "a"));
+
+               Expression<Func<object, bool>> e8 = (object a) => null != a;
+               AssertNodeType (e8, ExpressionType.NotEqual);
+               Assert (false, e8.Compile ().Invoke (null));
+               Assert (true, e8.Compile ().Invoke ("a"));
+               Assert (true, e8.Compile ().Invoke (this));
+       }
+
        void OrTest ()
        {
                Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a | b;
@@ -416,6 +1039,131 @@ class Tester
                var c2 = e2.Compile ();
                Assert (new MyType (3), c2 (new MyType (1), new MyType (2)));
                Assert (null, c2 (new MyType (1), null));
+
+               /* BUG: This does not work with csc either, because nullable conversions on top of user conversion is required
+               
+               Expression<Func<MyType?, uint, long?>> e3 = (MyType? a, uint b) => a | b;
+               AssertNodeType (e3, ExpressionType.Or);
+               var c3 = e3.Compile ();
+               Assert (9, c3 (new MyType (1), 8));
+               Assert (null, c3 (null, 4));
+               */
+       }
+
+       void OrElseTest ()
+       {
+               Expression<Func<bool, bool, bool>> e = (bool a, bool b) => a || b;
+               AssertNodeType (e, ExpressionType.OrElse);
+               Assert (true, e.Compile ().Invoke (true, false));
+
+               Expression<Func<MyType, MyType, MyType>> e2 = (MyType a, MyType b) => a || b;
+               AssertNodeType (e2, ExpressionType.OrElse);
+               Assert (new MyType (64), e2.Compile ().Invoke (new MyType (64), new MyType (64)));
+               Assert (new MyType (32), e2.Compile ().Invoke (new MyType (32), new MyType (64)));
+       }
+
+       void ParameterTest ()
+       {
+               Expression<Func<string, string>> e = (string a) => a;
+               AssertNodeType (e, ExpressionType.Parameter);
+               Assert ("t", e.Compile ().Invoke ("t"));
+
+               Expression<Func<object[], object[]>> e2 = (object[] a) => a;
+               AssertNodeType (e2, ExpressionType.Parameter);
+               Assert (new object [0], e2.Compile ().Invoke (new object [0]));
+
+               Expression<Func<IntPtr, IntPtr>> e3 = a => a;
+               AssertNodeType (e3, ExpressionType.Parameter);
+               Assert (IntPtr.Zero, e3.Compile ().Invoke (IntPtr.Zero));
+       }
+
+       void QuoteTest ()
+       {
+               Expression<Func<Expression<Func<int>>>> e = () => () => 2;
+               AssertNodeType (e, ExpressionType.Quote);
+               Assert (2, e.Compile ().Invoke ().Compile ().Invoke ());
+       }
+
+       void RightShiftTest ()
+       {
+               Expression<Func<ulong, short, ulong>> e = (ulong a, short b) => a >> b;
+               AssertNodeType (e, ExpressionType.RightShift);
+               Assert ((ulong)0x1FD940L, e.Compile ().Invoke (0xFECA0000, 11));
+               Assert ((ulong)0, e.Compile ().Invoke (0xFFFFFFFF, 0xA01));
+
+               Expression<Func<MyType, MyType, int>> e2 = (MyType a, MyType b) => a >> b;
+               AssertNodeType (e2, ExpressionType.RightShift);
+               var c2 = e2.Compile ();
+               Assert (64, c2 (new MyType (256), new MyType (2)));
+               
+               Expression<Func<long?, sbyte, long?>> e3 = (long? a, sbyte b) => a >> b;
+               AssertNodeType (e3, ExpressionType.RightShift);
+               Assert (null, e3.Compile ().Invoke (null, 11));
+               Assert (512, e3.Compile ().Invoke (1024, 1));
+
+               Expression<Func<MyType?, MyType?, int?>> e4 = (MyType? a, MyType? b) => a >> b;
+               AssertNodeType (e4, ExpressionType.RightShift);
+               var c4 = e4.Compile ();
+               Assert (null, c4 (new MyType (8), null));
+               Assert (null, c4 (null, new MyType (8)));
+               Assert (64, c4 (new MyType (256), new MyType (2)));
+       }
+       
+       void SubtractTest ()
+       {
+               Expression<Func<int, int, int>> e = (int a, int b) => a - b;
+               AssertNodeType (e, ExpressionType.Subtract);
+               Assert (-10, e.Compile ().Invoke (20, 30));
+
+               Expression<Func<int?, int?, int?>> e2 = (a, b) => a - b;
+               AssertNodeType (e2, ExpressionType.Subtract);
+               Assert (null, e2.Compile ().Invoke (null, 3));
+
+               Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a - b;
+               AssertNodeType (e3, ExpressionType.Subtract);
+               Assert (-50, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
+
+               Expression<Func<MyType?, MyType?, MyType?>> e4 = (MyType? a, MyType? b) => a - b;
+               AssertNodeType (e4, ExpressionType.Subtract);
+               Assert (new MyType (-50), e4.Compile ().Invoke (new MyType (-20), new MyType (30)));
+               Assert (null, e4.Compile ().Invoke (null, new MyType (30)));
+
+               Expression<Func<int, MyType, int>> e5 = (int a, MyType b) => a - b;
+               AssertNodeType (e5, ExpressionType.Subtract);
+               Assert (-29, e5.Compile ().Invoke (1, new MyType (30)));
+
+               Expression<Func<int, MyType?, int?>> e6 = (int a, MyType? b) => a - b;
+               AssertNodeType (e6, ExpressionType.Subtract);
+               Assert (-61, e6.Compile ().Invoke (-31, new MyType (30)));
+
+               Expression<Func<ushort, int?>> e7 = (ushort a) => null - a;
+               AssertNodeType (e7, ExpressionType.Subtract);
+               Assert (null, e7.Compile ().Invoke (690));
+       }
+
+       void SubtractCheckedTest ()
+       {
+               checked {
+                       Expression<Func<long, long, long>> e = (long a, long b) => a - b;
+                       AssertNodeType (e, ExpressionType.SubtractChecked);
+                       try {
+                               e.Compile ().Invoke (long.MinValue, 309);
+                               throw new ApplicationException ("SubtractCheckedTest #1");
+                       } catch (OverflowException) { }
+
+                       Expression<Func<byte?, byte?, int?>> e2 = (a, b) => a - b;
+                       AssertNodeType (e2, ExpressionType.SubtractChecked);
+                       Assert (null, e2.Compile ().Invoke (null, 3));
+                       Assert (-55, e2.Compile ().Invoke (byte.MinValue, 55));
+
+                       Expression<Func<MyType, MyType, MyType>> e3 = (MyType a, MyType b) => a - b;
+                       AssertNodeType (e3, ExpressionType.Subtract);
+                       Assert (-50, e3.Compile ().Invoke (new MyType (-20), new MyType (30)));
+
+                       Expression<Func<double, double, double>> e4 = (a, b) => a - b;
+                       AssertNodeType (e4, ExpressionType.Subtract);
+                       Assert (double.PositiveInfinity, e4.Compile ().Invoke (double.MinValue, double.NegativeInfinity));
+               }
        }
 
        //
@@ -445,6 +1193,7 @@ class Tester
        {
                Tester e = new Tester ();
                e.AddTest ();
+               e.AddStringTest ();
                e.AndNullableTest ();
                e.AddCheckedTest ();
                e.AndTest ();
@@ -454,11 +1203,34 @@ class Tester
                e.CallTest ();
                e.CoalesceTest ();
                e.ConditionTest ();
+               e.ConstantTest ();
                e.ConvertTest ();
                e.ConvertCheckedTest ();
+               e.DivideTest ();
+               e.EqualTest ();
+               e.EqualTestDelegate ();
+               e.ExclusiveOrTest ();
+               e.GreaterThanTest ();
+               e.GreaterThanOrEqualTest ();
+               e.LeftShiftTest ();
+               e.LessThanTest ();
+               e.LessThanOrEqualTest ();
+
+               e.ModuloTest ();        
+               e.MultiplyTest ();
+               e.MultiplyCheckedTest ();
                e.NewArrayInitTest ();
+               e.NotTest ();
+               e.NotNullableTest ();
+               e.NotEqualTest ();
                e.OrTest ();
                e.OrNullableTest ();
+               e.OrElseTest ();
+               e.ParameterTest ();
+               e.QuoteTest ();
+               e.RightShiftTest ();
+               e.SubtractTest ();
+               e.SubtractCheckedTest ();
 
                return 0;
        }