2004-06-09 Umadevi S <sumadevi@novell.com>
[mono.git] / mcs / mbas / cfold.cs
index 058c3089254127800dc88d2c580ef18423a890b8..e53b71e1ebc27546d8b7cb67ae084b34fd08b331 100644 (file)
-//\r
-// cfold.cs: Constant Folding\r
-//\r
-// Author:\r
-//   Miguel de Icaza (miguel@ximian.com)\r
-//\r
-// (C) 2002 Ximian, Inc.\r
-//\r
-\r
-using System;\r
-\r
-namespace Mono.CSharp {\r
-\r
-       public class ConstantFold {\r
-\r
-               //\r
-               // Performs the numeric promotions on the left and right expresions\r
-               // and desposits the results on `lc' and `rc'.\r
-               //\r
-               // On success, the types of `lc' and `rc' on output will always match,\r
-               // and the pair will be one of:\r
-               //\r
-               //   (double, double)\r
-               //   (float, float)\r
-               //   (ulong, ulong)\r
-               //   (long, long)\r
-               //   (uint, uint)\r
-               //   (int, int)\r
-               //\r
-               static void DoConstantNumericPromotions (Binary.Operator oper,\r
-                                                        ref Constant left, ref Constant right,\r
-                                                        Location loc)\r
-               {\r
-                       if (left is DoubleConstant || right is DoubleConstant){\r
-                               //\r
-                               // If either side is a double, convert the other to a double\r
-                               //\r
-                               if (!(left is DoubleConstant))\r
-                                       left = left.ToDouble (loc);\r
-\r
-                               if (!(right is DoubleConstant))\r
-                                       right = right.ToDouble (loc);\r
-                               return;\r
-                       } else if (left is FloatConstant || right is FloatConstant) {\r
-                               //\r
-                               // If either side is a float, convert the other to a float\r
-                               //\r
-                               if (!(left is FloatConstant))\r
-                                       left = left.ToFloat (loc);\r
-\r
-                               if (!(right is FloatConstant))\r
-                                       right = right.ToFloat (loc);\r
-                               return;\r
-                       } else if (left is ULongConstant || right is ULongConstant){\r
-                               //\r
-                               // If either operand is of type ulong, the other operand is\r
-                               // converted to type ulong.  or an error ocurrs if the other\r
-                               // operand is of type sbyte, short, int or long\r
-                               //\r
-                               Constant match, other;\r
-                                       \r
-                               if (left is ULongConstant){\r
-                                       other = right;\r
-                                       match = left;\r
-                                       if (!(right is ULongConstant))\r
-                                               right = right.ToULong (loc);\r
-                               } else {\r
-                                       other = left;\r
-                                       match = right;\r
-                                       left = left.ToULong (loc);\r
-                               }\r
-\r
-#if WRONG\r
-                               if (other is SByteConstant || other is ShortConstant ||\r
-                                   other is IntConstant || other is LongConstant){\r
-                                       Binary.Error_OperatorAmbiguous\r
-                                               (loc, oper, other.Type, match.Type);\r
-                                       left = null;\r
-                                       right = null;\r
-                               }\r
-#endif\r
-                               return;\r
-                       } else if (left is LongConstant || right is LongConstant){\r
-                               //\r
-                               // If either operand is of type long, the other operand is converted\r
-                               // to type long.\r
-                               //\r
-                               if (!(left is LongConstant))\r
-                                       left = left.ToLong (loc);\r
-                               else if (!(right is LongConstant))\r
-                                       right = right.ToLong (loc);\r
-                               return;\r
-                       } else if (left is UIntConstant || right is UIntConstant){\r
-                               //\r
-                               // If either operand is of type uint, and the other\r
-                               // operand is of type sbyte, short or int, othe operands are\r
-                               // converted to type long.\r
-                               //\r
-                               if (!(left is UIntConstant))\r
-                                       left = left.ToUInt (loc);\r
-                               else if (!(right is UIntConstant))\r
-                                       right = right.ToUInt (loc);\r
-                               return;\r
-                       } else {\r
-                               //\r
-                               // Force conversions to int32\r
-                               //\r
-                               if (!(left is IntConstant))\r
-                                       left = left.ToInt (loc);\r
-                               if (!(right is IntConstant))\r
-                                       right = right.ToInt (loc);\r
-                       }\r
-                       return;\r
-               }\r
-\r
-               static void Error_CompileTimeOverflow (Location loc)\r
-               {\r
-                       Report.Error (220, loc, "The operation overflows at compile time in checked mode");\r
-               }\r
-               \r
-               /// <summary>\r
-               ///   Constant expression folder for binary operations.\r
-               ///\r
-               ///   Returns null if the expression can not be folded.\r
-               /// </summary>\r
-               static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,\r
-                                                    Constant left, Constant right, Location loc)\r
-               {\r
-                       Type lt = left.Type;\r
-                       Type rt = right.Type;\r
-                       Type result_type = null;\r
-                       bool bool_res;\r
-                       \r
-                       //\r
-                       // Enumerator folding\r
-                       //\r
-                       if (rt == lt && left is EnumConstant)\r
-                               result_type = lt;\r
-\r
-                       switch (oper){\r
-                       case Binary.Operator.BitwiseOr:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-                               \r
-                               if (left is IntConstant){\r
-                                       IntConstant v;\r
-                                       int res = ((IntConstant) left).Value | ((IntConstant) right).Value;\r
-                                       \r
-                                       v = new IntConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is UIntConstant){\r
-                                       UIntConstant v;\r
-                                       uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;\r
-                                       \r
-                                       v = new UIntConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is LongConstant){\r
-                                       LongConstant v;\r
-                                       long res = ((LongConstant)left).Value | ((LongConstant)right).Value;\r
-                                       \r
-                                       v = new LongConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is ULongConstant){\r
-                                       ULongConstant v;\r
-                                       ulong res = ((ULongConstant)left).Value |\r
-                                               ((ULongConstant)right).Value;\r
-                                       \r
-                                       v = new ULongConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               }\r
-                               break;\r
-                               \r
-                       case Binary.Operator.BitwiseAnd:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-                               \r
-                               if (left is IntConstant){\r
-                                       IntConstant v;\r
-                                       int res = ((IntConstant) left).Value & ((IntConstant) right).Value;\r
-                                       \r
-                                       v = new IntConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is UIntConstant){\r
-                                       UIntConstant v;\r
-                                       uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;\r
-                                       \r
-                                       v = new UIntConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is LongConstant){\r
-                                       LongConstant v;\r
-                                       long res = ((LongConstant)left).Value & ((LongConstant)right).Value;\r
-                                       \r
-                                       v = new LongConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is ULongConstant){\r
-                                       ULongConstant v;\r
-                                       ulong res = ((ULongConstant)left).Value &\r
-                                               ((ULongConstant)right).Value;\r
-                                       \r
-                                       v = new ULongConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               }\r
-                               break;\r
-\r
-                       case Binary.Operator.ExclusiveOr:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-                               \r
-                               if (left is IntConstant){\r
-                                       IntConstant v;\r
-                                       int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;\r
-                                       \r
-                                       v = new IntConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is UIntConstant){\r
-                                       UIntConstant v;\r
-                                       uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;\r
-                                       \r
-                                       v = new UIntConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is LongConstant){\r
-                                       LongConstant v;\r
-                                       long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;\r
-                                       \r
-                                       v = new LongConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               } else if (left is ULongConstant){\r
-                                       ULongConstant v;\r
-                                       ulong res = ((ULongConstant)left).Value ^\r
-                                               ((ULongConstant)right).Value;\r
-                                       \r
-                                       v = new ULongConstant (res);\r
-                                       if (result_type == null)\r
-                                               return v;\r
-                                       else\r
-                                               return new EnumConstant (v, result_type);\r
-                               }\r
-                               break;\r
-\r
-                       case Binary.Operator.Addition:\r
-                               bool left_is_string = left is StringConstant;\r
-                               bool right_is_string = right is StringConstant;\r
-\r
-                               //\r
-                               // If both sides are strings, then concatenate, if\r
-                               // one is a string, and the other is not, then defer\r
-                               // to runtime concatenation\r
-                               //\r
-                               if (left_is_string || right_is_string){\r
-                                       if (left_is_string && right_is_string)\r
-                                               return new StringConstant (\r
-                                                       ((StringConstant) left).Value +\r
-                                                       ((StringConstant) right).Value);\r
-                                       \r
-                                       return null;\r
-                               }\r
-\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               try {\r
-                                       if (left is DoubleConstant){\r
-                                               double res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((DoubleConstant) left).Value +\r
-                                                                      ((DoubleConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((DoubleConstant) left).Value +\r
-                                                                        ((DoubleConstant) right).Value);\r
-                                               \r
-                                               return new DoubleConstant (res);\r
-                                       } else if (left is FloatConstant){\r
-                                               float res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((FloatConstant) left).Value +\r
-                                                                      ((FloatConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((FloatConstant) left).Value +\r
-                                                                        ((FloatConstant) right).Value);\r
-                                               \r
-                                               return new FloatConstant (res);\r
-                                       } else if (left is ULongConstant){\r
-                                               ulong res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((ULongConstant) left).Value +\r
-                                                                      ((ULongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((ULongConstant) left).Value +\r
-                                                                        ((ULongConstant) right).Value);\r
-                                               \r
-                                               return new ULongConstant (res);\r
-                                       } else if (left is LongConstant){\r
-                                               long res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((LongConstant) left).Value +\r
-                                                                      ((LongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((LongConstant) left).Value +\r
-                                                                        ((LongConstant) right).Value);\r
-                                               \r
-                                               return new LongConstant (res);\r
-                                       } else if (left is UIntConstant){\r
-                                               uint res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((UIntConstant) left).Value +\r
-                                                                      ((UIntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((UIntConstant) left).Value +\r
-                                                                        ((UIntConstant) right).Value);\r
-                                               \r
-                                               return new UIntConstant (res);\r
-                                       } else if (left is IntConstant){\r
-                                               int res;\r
-\r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((IntConstant) left).Value +\r
-                                                                      ((IntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((IntConstant) left).Value +\r
-                                                                        ((IntConstant) right).Value);\r
-\r
-                                               return new IntConstant (res);\r
-                                       } else {\r
-                                               throw new Exception ( "Unexepected input: " + left);\r
-                                       }\r
-                               } catch (OverflowException){\r
-                                       Error_CompileTimeOverflow (loc);\r
-                               }\r
-                               break;\r
-\r
-                       case Binary.Operator.Subtraction:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               try {\r
-                                       if (left is DoubleConstant){\r
-                                               double res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((DoubleConstant) left).Value -\r
-                                                                      ((DoubleConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((DoubleConstant) left).Value -\r
-                                                                        ((DoubleConstant) right).Value);\r
-                                               \r
-                                               return new DoubleConstant (res);\r
-                                       } else if (left is FloatConstant){\r
-                                               float res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((FloatConstant) left).Value -\r
-                                                                      ((FloatConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((FloatConstant) left).Value -\r
-                                                                        ((FloatConstant) right).Value);\r
-                                               \r
-                                               return new FloatConstant (res);\r
-                                       } else if (left is ULongConstant){\r
-                                               ulong res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((ULongConstant) left).Value -\r
-                                                                      ((ULongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((ULongConstant) left).Value -\r
-                                                                        ((ULongConstant) right).Value);\r
-                                               \r
-                                               return new ULongConstant (res);\r
-                                       } else if (left is LongConstant){\r
-                                               long res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((LongConstant) left).Value -\r
-                                                                      ((LongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((LongConstant) left).Value -\r
-                                                                        ((LongConstant) right).Value);\r
-                                               \r
-                                               return new LongConstant (res);\r
-                                       } else if (left is UIntConstant){\r
-                                               uint res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((UIntConstant) left).Value -\r
-                                                                      ((UIntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((UIntConstant) left).Value -\r
-                                                                        ((UIntConstant) right).Value);\r
-                                               \r
-                                               return new UIntConstant (res);\r
-                                       } else if (left is IntConstant){\r
-                                               int res;\r
-\r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((IntConstant) left).Value -\r
-                                                                      ((IntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((IntConstant) left).Value -\r
-                                                                        ((IntConstant) right).Value);\r
-\r
-                                               return new IntConstant (res);\r
-                                       } else {\r
-                                               throw new Exception ( "Unexepected input: " + left);\r
-                                       }\r
-                               } catch (OverflowException){\r
-                                       Error_CompileTimeOverflow (loc);\r
-                               }\r
-                               break;\r
-                               \r
-                       case Binary.Operator.Multiply:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               try {\r
-                                       if (left is DoubleConstant){\r
-                                               double res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((DoubleConstant) left).Value *\r
-                                                                      ((DoubleConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((DoubleConstant) left).Value *\r
-                                                                        ((DoubleConstant) right).Value);\r
-                                               \r
-                                               return new DoubleConstant (res);\r
-                                       } else if (left is FloatConstant){\r
-                                               float res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((FloatConstant) left).Value *\r
-                                                                      ((FloatConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((FloatConstant) left).Value *\r
-                                                                        ((FloatConstant) right).Value);\r
-                                               \r
-                                               return new FloatConstant (res);\r
-                                       } else if (left is ULongConstant){\r
-                                               ulong res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((ULongConstant) left).Value *\r
-                                                                      ((ULongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((ULongConstant) left).Value *\r
-                                                                        ((ULongConstant) right).Value);\r
-                                               \r
-                                               return new ULongConstant (res);\r
-                                       } else if (left is LongConstant){\r
-                                               long res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((LongConstant) left).Value *\r
-                                                                      ((LongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((LongConstant) left).Value *\r
-                                                                        ((LongConstant) right).Value);\r
-                                               \r
-                                               return new LongConstant (res);\r
-                                       } else if (left is UIntConstant){\r
-                                               uint res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((UIntConstant) left).Value *\r
-                                                                      ((UIntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((UIntConstant) left).Value *\r
-                                                                        ((UIntConstant) right).Value);\r
-                                               \r
-                                               return new UIntConstant (res);\r
-                                       } else if (left is IntConstant){\r
-                                               int res;\r
-\r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((IntConstant) left).Value *\r
-                                                                      ((IntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((IntConstant) left).Value *\r
-                                                                        ((IntConstant) right).Value);\r
-\r
-                                               return new IntConstant (res);\r
-                                       } else {\r
-                                               throw new Exception ( "Unexepected input: " + left);\r
-                                       }\r
-                               } catch (OverflowException){\r
-                                       Error_CompileTimeOverflow (loc);\r
-                               }\r
-                               break;\r
-\r
-                       case Binary.Operator.Division:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               try {\r
-                                       if (left is DoubleConstant){\r
-                                               double res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((DoubleConstant) left).Value /\r
-                                                                      ((DoubleConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((DoubleConstant) left).Value /\r
-                                                                        ((DoubleConstant) right).Value);\r
-                                               \r
-                                               return new DoubleConstant (res);\r
-                                       } else if (left is FloatConstant){\r
-                                               float res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((FloatConstant) left).Value /\r
-                                                                      ((FloatConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((FloatConstant) left).Value /\r
-                                                                        ((FloatConstant) right).Value);\r
-                                               \r
-                                               return new FloatConstant (res);\r
-                                       } else if (left is ULongConstant){\r
-                                               ulong res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((ULongConstant) left).Value /\r
-                                                                      ((ULongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((ULongConstant) left).Value /\r
-                                                                        ((ULongConstant) right).Value);\r
-                                               \r
-                                               return new ULongConstant (res);\r
-                                       } else if (left is LongConstant){\r
-                                               long res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((LongConstant) left).Value /\r
-                                                                      ((LongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((LongConstant) left).Value /\r
-                                                                        ((LongConstant) right).Value);\r
-                                               \r
-                                               return new LongConstant (res);\r
-                                       } else if (left is UIntConstant){\r
-                                               uint res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((UIntConstant) left).Value /\r
-                                                                      ((UIntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((UIntConstant) left).Value /\r
-                                                                        ((UIntConstant) right).Value);\r
-                                               \r
-                                               return new UIntConstant (res);\r
-                                       } else if (left is IntConstant){\r
-                                               int res;\r
-\r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((IntConstant) left).Value /\r
-                                                                      ((IntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((IntConstant) left).Value /\r
-                                                                        ((IntConstant) right).Value);\r
-\r
-                                               return new IntConstant (res);\r
-                                       } else {\r
-                                               throw new Exception ( "Unexepected input: " + left);\r
-                                       }\r
-                               } catch (OverflowException){\r
-                                       Error_CompileTimeOverflow (loc);\r
-                               }\r
-                               break;\r
-                               \r
-                       case Binary.Operator.Modulus:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               try {\r
-                                       if (left is DoubleConstant){\r
-                                               double res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((DoubleConstant) left).Value %\r
-                                                                      ((DoubleConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((DoubleConstant) left).Value %\r
-                                                                        ((DoubleConstant) right).Value);\r
-                                               \r
-                                               return new DoubleConstant (res);\r
-                                       } else if (left is FloatConstant){\r
-                                               float res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((FloatConstant) left).Value %\r
-                                                                      ((FloatConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((FloatConstant) left).Value %\r
-                                                                        ((FloatConstant) right).Value);\r
-                                               \r
-                                               return new FloatConstant (res);\r
-                                       } else if (left is ULongConstant){\r
-                                               ulong res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((ULongConstant) left).Value %\r
-                                                                      ((ULongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((ULongConstant) left).Value %\r
-                                                                        ((ULongConstant) right).Value);\r
-                                               \r
-                                               return new ULongConstant (res);\r
-                                       } else if (left is LongConstant){\r
-                                               long res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((LongConstant) left).Value %\r
-                                                                      ((LongConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((LongConstant) left).Value %\r
-                                                                        ((LongConstant) right).Value);\r
-                                               \r
-                                               return new LongConstant (res);\r
-                                       } else if (left is UIntConstant){\r
-                                               uint res;\r
-                                               \r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((UIntConstant) left).Value %\r
-                                                                      ((UIntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((UIntConstant) left).Value %\r
-                                                                        ((UIntConstant) right).Value);\r
-                                               \r
-                                               return new UIntConstant (res);\r
-                                       } else if (left is IntConstant){\r
-                                               int res;\r
-\r
-                                               if (ec.ConstantCheckState)\r
-                                                       res = checked (((IntConstant) left).Value %\r
-                                                                      ((IntConstant) right).Value);\r
-                                               else\r
-                                                       res = unchecked (((IntConstant) left).Value %\r
-                                                                        ((IntConstant) right).Value);\r
-\r
-                                               return new IntConstant (res);\r
-                                       } else {\r
-                                               throw new Exception ( "Unexepected input: " + left);\r
-                                       }\r
-                               } catch (OverflowException){\r
-                                       Error_CompileTimeOverflow (loc);\r
-                               }\r
-                               break;\r
-\r
-                               //\r
-                               // There is no overflow checking on left shift\r
-                               //\r
-                       case Binary.Operator.LeftShift:\r
-                               IntConstant ic = right.ToInt (loc);\r
-                               if (ic == null){\r
-                                       Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);\r
-                                       return null;\r
-                               }\r
-                               int lshift_val = ic.Value;\r
-\r
-                               IntConstant lic;\r
-                               if ((lic = left.ConvertToInt ()) != null)\r
-                                       return new IntConstant (lic.Value << lshift_val);\r
-\r
-                               UIntConstant luic;\r
-                               if ((luic = left.ConvertToUInt ()) != null)\r
-                                       return new UIntConstant (luic.Value << lshift_val);\r
-\r
-                               LongConstant llc;\r
-                               if ((llc = left.ConvertToLong ()) != null)\r
-                                       return new LongConstant (llc.Value << lshift_val);\r
-\r
-                               ULongConstant lulc;\r
-                               if ((lulc = left.ConvertToULong ()) != null)\r
-                                       return new ULongConstant (lulc.Value << lshift_val);\r
-\r
-                               Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);\r
-                               break;\r
-\r
-                               //\r
-                               // There is no overflow checking on right shift\r
-                               //\r
-                       case Binary.Operator.RightShift:\r
-                               IntConstant sic = right.ToInt (loc);\r
-                               if (sic == null){\r
-                                       Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);\r
-                                       return null;\r
-                               }\r
-                               int rshift_val = sic.Value;\r
-\r
-                               IntConstant ric;\r
-                               if ((ric = left.ConvertToInt ()) != null)\r
-                                       return new IntConstant (ric.Value >> rshift_val);\r
-\r
-                               UIntConstant ruic;\r
-                               if ((ruic = left.ConvertToUInt ()) != null)\r
-                                       return new UIntConstant (ruic.Value >> rshift_val);\r
-\r
-                               LongConstant rlc;\r
-                               if ((rlc = left.ConvertToLong ()) != null)\r
-                                       return new LongConstant (rlc.Value >> rshift_val);\r
-\r
-                               ULongConstant rulc;\r
-                               if ((rulc = left.ConvertToULong ()) != null)\r
-                                       return new ULongConstant (rulc.Value >> rshift_val);\r
-\r
-                               Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);\r
-                               break;\r
-\r
-                       case Binary.Operator.LogicalAnd:\r
-                               if (left is BoolConstant && right is BoolConstant){\r
-                                       return new BoolConstant (\r
-                                               ((BoolConstant) left).Value &&\r
-                                               ((BoolConstant) right).Value);\r
-                               }\r
-                               break;\r
-\r
-                       case Binary.Operator.LogicalOr:\r
-                               if (left is BoolConstant && right is BoolConstant){\r
-                                       return new BoolConstant (\r
-                                               ((BoolConstant) left).Value ||\r
-                                               ((BoolConstant) right).Value);\r
-                               }\r
-                               break;\r
-                               \r
-                       case Binary.Operator.Equality:\r
-                               if (left is BoolConstant && right is BoolConstant){\r
-                                       return new BoolConstant (\r
-                                               ((BoolConstant) left).Value ==\r
-                                               ((BoolConstant) right).Value);\r
-                               \r
-                               }\r
-                               if (left is StringConstant && right is StringConstant){\r
-                                       return new BoolConstant (\r
-                                               ((StringConstant) left).Value ==\r
-                                               ((StringConstant) right).Value);\r
-                                       \r
-                               }\r
-                               \r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               bool_res = false;\r
-                               if (left is DoubleConstant)\r
-                                       bool_res = ((DoubleConstant) left).Value ==\r
-                                               ((DoubleConstant) right).Value;\r
-                               else if (left is FloatConstant)\r
-                                       bool_res = ((FloatConstant) left).Value ==\r
-                                               ((FloatConstant) right).Value;\r
-                               else if (left is ULongConstant)\r
-                                       bool_res = ((ULongConstant) left).Value ==\r
-                                               ((ULongConstant) right).Value;\r
-                               else if (left is LongConstant)\r
-                                       bool_res = ((LongConstant) left).Value ==\r
-                                               ((LongConstant) right).Value;\r
-                               else if (left is UIntConstant)\r
-                                       bool_res = ((UIntConstant) left).Value ==\r
-                                               ((UIntConstant) right).Value;\r
-                               else if (left is IntConstant)\r
-                                       bool_res = ((IntConstant) left).Value ==\r
-                                               ((IntConstant) right).Value;\r
-                               else\r
-                                       return null;\r
-\r
-                               return new BoolConstant (bool_res);\r
-\r
-                       case Binary.Operator.Inequality:\r
-                               if (left is BoolConstant && right is BoolConstant){\r
-                                       return new BoolConstant (\r
-                                               ((BoolConstant) left).Value !=\r
-                                               ((BoolConstant) right).Value);\r
-                               }\r
-                               if (left is StringConstant && right is StringConstant){\r
-                                       return new BoolConstant (\r
-                                               ((StringConstant) left).Value !=\r
-                                               ((StringConstant) right).Value);\r
-                                       \r
-                               }\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               bool_res = false;\r
-                               if (left is DoubleConstant)\r
-                                       bool_res = ((DoubleConstant) left).Value !=\r
-                                               ((DoubleConstant) right).Value;\r
-                               else if (left is FloatConstant)\r
-                                       bool_res = ((FloatConstant) left).Value !=\r
-                                               ((FloatConstant) right).Value;\r
-                               else if (left is ULongConstant)\r
-                                       bool_res = ((ULongConstant) left).Value !=\r
-                                               ((ULongConstant) right).Value;\r
-                               else if (left is LongConstant)\r
-                                       bool_res = ((LongConstant) left).Value !=\r
-                                               ((LongConstant) right).Value;\r
-                               else if (left is UIntConstant)\r
-                                       bool_res = ((UIntConstant) left).Value !=\r
-                                               ((UIntConstant) right).Value;\r
-                               else if (left is IntConstant)\r
-                                       bool_res = ((IntConstant) left).Value !=\r
-                                               ((IntConstant) right).Value;\r
-                               else\r
-                                       return null;\r
-\r
-                               return new BoolConstant (bool_res);\r
-\r
-                       case Binary.Operator.LessThan:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               bool_res = false;\r
-                               if (left is DoubleConstant)\r
-                                       bool_res = ((DoubleConstant) left).Value <\r
-                                               ((DoubleConstant) right).Value;\r
-                               else if (left is FloatConstant)\r
-                                       bool_res = ((FloatConstant) left).Value <\r
-                                               ((FloatConstant) right).Value;\r
-                               else if (left is ULongConstant)\r
-                                       bool_res = ((ULongConstant) left).Value <\r
-                                               ((ULongConstant) right).Value;\r
-                               else if (left is LongConstant)\r
-                                       bool_res = ((LongConstant) left).Value <\r
-                                               ((LongConstant) right).Value;\r
-                               else if (left is UIntConstant)\r
-                                       bool_res = ((UIntConstant) left).Value <\r
-                                               ((UIntConstant) right).Value;\r
-                               else if (left is IntConstant)\r
-                                       bool_res = ((IntConstant) left).Value <\r
-                                               ((IntConstant) right).Value;\r
-                               else\r
-                                       return null;\r
-\r
-                               return new BoolConstant (bool_res);\r
-                               \r
-                       case Binary.Operator.GreaterThan:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               bool_res = false;\r
-                               if (left is DoubleConstant)\r
-                                       bool_res = ((DoubleConstant) left).Value >\r
-                                               ((DoubleConstant) right).Value;\r
-                               else if (left is FloatConstant)\r
-                                       bool_res = ((FloatConstant) left).Value >\r
-                                               ((FloatConstant) right).Value;\r
-                               else if (left is ULongConstant)\r
-                                       bool_res = ((ULongConstant) left).Value >\r
-                                               ((ULongConstant) right).Value;\r
-                               else if (left is LongConstant)\r
-                                       bool_res = ((LongConstant) left).Value >\r
-                                               ((LongConstant) right).Value;\r
-                               else if (left is UIntConstant)\r
-                                       bool_res = ((UIntConstant) left).Value >\r
-                                               ((UIntConstant) right).Value;\r
-                               else if (left is IntConstant)\r
-                                       bool_res = ((IntConstant) left).Value >\r
-                                               ((IntConstant) right).Value;\r
-                               else\r
-                                       return null;\r
-\r
-                               return new BoolConstant (bool_res);\r
-\r
-                       case Binary.Operator.GreaterThanOrEqual:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               bool_res = false;\r
-                               if (left is DoubleConstant)\r
-                                       bool_res = ((DoubleConstant) left).Value >=\r
-                                               ((DoubleConstant) right).Value;\r
-                               else if (left is FloatConstant)\r
-                                       bool_res = ((FloatConstant) left).Value >=\r
-                                               ((FloatConstant) right).Value;\r
-                               else if (left is ULongConstant)\r
-                                       bool_res = ((ULongConstant) left).Value >=\r
-                                               ((ULongConstant) right).Value;\r
-                               else if (left is LongConstant)\r
-                                       bool_res = ((LongConstant) left).Value >=\r
-                                               ((LongConstant) right).Value;\r
-                               else if (left is UIntConstant)\r
-                                       bool_res = ((UIntConstant) left).Value >=\r
-                                               ((UIntConstant) right).Value;\r
-                               else if (left is IntConstant)\r
-                                       bool_res = ((IntConstant) left).Value >=\r
-                                               ((IntConstant) right).Value;\r
-                               else\r
-                                       return null;\r
-\r
-                               return new BoolConstant (bool_res);\r
-\r
-                       case Binary.Operator.LessThanOrEqual:\r
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);\r
-                               if (left == null || right == null)\r
-                                       return null;\r
-\r
-                               bool_res = false;\r
-                               if (left is DoubleConstant)\r
-                                       bool_res = ((DoubleConstant) left).Value <=\r
-                                               ((DoubleConstant) right).Value;\r
-                               else if (left is FloatConstant)\r
-                                       bool_res = ((FloatConstant) left).Value <=\r
-                                               ((FloatConstant) right).Value;\r
-                               else if (left is ULongConstant)\r
-                                       bool_res = ((ULongConstant) left).Value <=\r
-                                               ((ULongConstant) right).Value;\r
-                               else if (left is LongConstant)\r
-                                       bool_res = ((LongConstant) left).Value <=\r
-                                               ((LongConstant) right).Value;\r
-                               else if (left is UIntConstant)\r
-                                       bool_res = ((UIntConstant) left).Value <=\r
-                                               ((UIntConstant) right).Value;\r
-                               else if (left is IntConstant)\r
-                                       bool_res = ((IntConstant) left).Value <=\r
-                                               ((IntConstant) right).Value;\r
-                               else\r
-                                       return null;\r
-\r
-                               return new BoolConstant (bool_res);\r
-                       }\r
-                                       \r
-                       return null;\r
-               }\r
-       }\r
-}\r
+//
+// cfold.cs: Constant Folding
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2002 Ximian, Inc.
+//
+
+using System;
+
+namespace Mono.MonoBASIC {
+
+       public class ConstantFold {
+
+               //
+               // Performs the numeric promotions on the left and right expresions
+               // and desposits the results on `lc' and `rc'.
+               //
+               // On success, the types of `lc' and `rc' on output will always match,
+               // and the pair will be one of:
+               //
+               //   (double, double)
+               //   (float, float)
+               //   (ulong, ulong)
+               //   (long, long)
+               //   (uint, uint)
+               //   (int, int)
+               //
+               static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
+                                                        ref Constant left, ref Constant right,
+                                                        Location loc)
+               {
+                       if (left is DoubleConstant || right is DoubleConstant){
+                               //
+                               // If either side is a double, convert the other to a double
+                               //
+                               if (!(left is DoubleConstant))
+                                       left = left.ToDouble (loc);
+
+                               if (!(right is DoubleConstant))
+                                       right = right.ToDouble (loc);
+                               return;
+                       } else if (left is FloatConstant || right is FloatConstant) {
+                               //
+                               // If either side is a float, convert the other to a float
+                               //
+                               if (!(left is FloatConstant))
+                                       left = left.ToFloat (loc);
+
+                               if (!(right is FloatConstant))
+                                       right = right.ToFloat (loc);
+;                              return;
+                       } else if (left is ULongConstant || right is ULongConstant){
+                               //
+                               // If either operand is of type ulong, the other operand is
+                               // converted to type ulong.  or an error ocurrs if the other
+                               // operand is of type sbyte, short, int or long
+                               //
+                               Constant match, other;
+                                       
+                               if (left is ULongConstant){
+                                       other = right;
+                                       match = left;
+                                       if (!(right is ULongConstant))
+                                               right = right.ToULong (loc);
+                               } else {
+                                       other = left;
+                                       match = right;
+                                       left = left.ToULong (loc);
+                               }
+
+#if WRONG
+                               if (other is SByteConstant || other is ShortConstant ||
+                                   other is IntConstant || other is LongConstant){
+                                       Binary.Error_OperatorAmbiguous
+                                               (loc, oper, other.Type, match.Type);
+                                       left = null;
+                                       right = null;
+                               }
+#endif
+                               return;
+                       } else if (left is LongConstant || right is LongConstant){
+                               //
+                               // If either operand is of type long, the other operand is converted
+                               // to type long.
+                               //
+                               if (!(left is LongConstant))
+                                       left = left.ToLong (loc);
+                               else if (!(right is LongConstant))
+                                       right = right.ToLong (loc);
+                               return;
+                       } else if (left is UIntConstant || right is UIntConstant){
+                               //
+                               // If either operand is of type uint, and the other
+                               // operand is of type sbyte, short or int, the operands are
+                               // converted to type long.
+                               //
+                               Constant match, other;
+                               if (left is UIntConstant){
+                                       other = right;
+                                       match = left;
+                               } else {
+                                       other = left;
+                                       match = right;
+                               }
+
+                               // Nothing to do.
+                               if (other is UIntConstant)
+                                       return;
+
+                               if (other is SByteConstant || other is ShortConstant ||
+                                   other is IntConstant){
+                                       left = left.ToLong (loc);
+                                       right = right.ToLong (loc);
+                               }
+
+                               return;
+                       } else if (left is EnumConstant || right is EnumConstant){
+                               //
+                               // If either operand is an enum constant, the other one must
+                               // be implicitly convertable to that enum's underlying type.
+                               //
+                               EnumConstant match;
+                               Constant other;
+                               if (left is EnumConstant){
+                                       other = right;
+                                       match = (EnumConstant) left;
+                               } else {
+                                       other = left;
+                                       match = (EnumConstant) right;
+                               }
+
+                               bool need_check = (other is EnumConstant) ||
+                                       ((oper != Binary.Operator.Addition) &&
+                                        (oper != Binary.Operator.Subtraction));
+
+                               if (need_check &&
+                                   !Expression.ImplicitConversionExists (ec, match, other.Type)) {
+                                       Expression.Error_CannotConvertImplicit (loc, match.Type, other.Type);
+                                       left = null;
+                                       right = null;
+                                       return;
+                               }
+
+                               if (left is EnumConstant)
+                                       left = ((EnumConstant) left).Child;
+                               if (right is EnumConstant)
+                                       right = ((EnumConstant) right).Child;
+                               return;
+
+                       } else {
+                               //
+                               // Force conversions to int32
+                               //
+                               if (!(left is IntConstant))
+                                       left = left.ToInt (loc);
+                               if (!(right is IntConstant))
+                                       right = right.ToInt (loc);
+                       }
+                       return;
+               }
+
+               static void Error_CompileTimeOverflow (Location loc)
+               {
+                       Report.Error (220, loc, "The operation overflows at compile time in checked mode");
+               }
+               
+               /// <summary>
+               ///   Constant expression folder for binary operations.
+               ///
+               ///   Returns null if the expression can not be folded.
+               /// </summary>
+               static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
+                                                    Constant left, Constant right, Location loc)
+               {
+                       Type lt = left.Type;
+                       Type rt = right.Type;
+                       Type result_type = null;
+                       bool bool_res;
+                       
+                       //
+                       // Enumerator folding
+                       //
+                       if (rt == lt && left is EnumConstant)
+                               result_type = lt;
+
+                       //
+                       // During an enum evaluation, we need to unwrap enumerations
+                       //
+                       if (ec.InEnumContext){
+                               if (left is EnumConstant)
+                                       left = ((EnumConstant) left).Child;
+                               
+                               if (right is EnumConstant)
+                                       right = ((EnumConstant) right).Child;
+                       }
+
+                       Type wrap_as;
+                       Constant result = null;
+                       switch (oper){
+                       case Binary.Operator.BitwiseOr:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+                               
+                               if (left is IntConstant){
+                                       IntConstant v;
+                                       int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
+                                       
+                                       v = new IntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UIntConstant){
+                                       UIntConstant v;
+                                       uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
+                                       
+                                       v = new UIntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is LongConstant){
+                                       LongConstant v;
+                                       long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
+                                       
+                                       v = new LongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ULongConstant){
+                                       ULongConstant v;
+                                       ulong res = ((ULongConstant)left).Value |
+                                               ((ULongConstant)right).Value;
+                                       
+                                       v = new ULongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               }
+                               break;
+                               
+                       case Binary.Operator.BitwiseAnd:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+                               
+                               if (left is IntConstant){
+                                       IntConstant v;
+                                       int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
+                                       
+                                       v = new IntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UIntConstant){
+                                       UIntConstant v;
+                                       uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
+                                       
+                                       v = new UIntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is LongConstant){
+                                       LongConstant v;
+                                       long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
+                                       
+                                       v = new LongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ULongConstant){
+                                       ULongConstant v;
+                                       ulong res = ((ULongConstant)left).Value &
+                                               ((ULongConstant)right).Value;
+                                       
+                                       v = new ULongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               }
+                               break;
+
+                       case Binary.Operator.ExclusiveOr:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+                               
+                               if (left is IntConstant){
+                                       IntConstant v;
+                                       int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
+                                       
+                                       v = new IntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UIntConstant){
+                                       UIntConstant v;
+                                       uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
+                                       
+                                       v = new UIntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is LongConstant){
+                                       LongConstant v;
+                                       long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
+                                       
+                                       v = new LongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ULongConstant){
+                                       ULongConstant v;
+                                       ulong res = ((ULongConstant)left).Value ^
+                                               ((ULongConstant)right).Value;
+                                       
+                                       v = new ULongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               }
+                               break;
+
+                       case Binary.Operator.Addition:
+                               bool left_is_string = left is StringConstant;
+                               bool right_is_string = right is StringConstant;
+
+                               //
+                               // If both sides are strings, then concatenate, if
+                               // one is a string, and the other is not, then defer
+                               // to runtime concatenation
+                               //
+                               wrap_as = null;
+                               if (left_is_string || right_is_string){
+                                       if (left_is_string && right_is_string)
+                                               return new StringConstant (
+                                                       ((StringConstant) left).Value +
+                                                       ((StringConstant) right).Value);
+                                       
+                                       return null;
+                               }
+
+                               //
+                               // handle "E operator + (E x, U y)"
+                               // handle "E operator + (Y y, E x)"
+                               //
+                               // note that E operator + (E x, E y) is invalid
+                               //
+                               if (left is EnumConstant){
+                                       if (right is EnumConstant){
+                                               return null;
+                                       }
+                                       if (((EnumConstant) left).Child.Type != right.Type)
+                                               return null;
+
+                                       wrap_as = left.Type;
+                               } else if (right is EnumConstant){
+                                       if (((EnumConstant) right).Child.Type != left.Type)
+                                               return null;
+                                       wrap_as = right.Type;
+                               }
+
+                               result = null;
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value +
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value +
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               result = new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value +
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value +
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               result = new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value +
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value +
+                                                                        ((ULongConstant) right).Value);
+
+                                               result = new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value +
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value +
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               result = new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value +
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value +
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               result = new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value +
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value +
+                                                                        ((IntConstant) right).Value);
+
+                                               result = new IntConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+
+                               if (wrap_as != null)
+                                       return new EnumConstant (result, wrap_as);
+                               else
+                                       return result;
+
+                       case Binary.Operator.Subtraction:
+                               //
+                               // handle "E operator - (E x, U y)"
+                               // handle "E operator - (Y y, E x)"
+                               // handle "U operator - (E x, E y)"
+                               //
+                               wrap_as = null;
+                               if (left is EnumConstant){
+                                       if (right is EnumConstant){
+                                               if (left.Type == right.Type)
+                                                       wrap_as = TypeManager.EnumToUnderlying (left.Type);
+                                               else
+                                                       return null;
+                                       }
+                                       if (((EnumConstant) left).Child.Type != right.Type)
+                                               return null;
+
+                                       wrap_as = left.Type;
+                               } else if (right is EnumConstant){
+                                       if (((EnumConstant) right).Child.Type != left.Type)
+                                               return null;
+                                       wrap_as = right.Type;
+                               }
+
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value -
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value -
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               result = new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value -
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value -
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               result = new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value -
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value -
+                                                                        ((ULongConstant) right).Value);
+                                               
+                                               result = new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value -
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value -
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               result = new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value -
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value -
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               result = new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value -
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value -
+                                                                        ((IntConstant) right).Value);
+
+                                               result = new IntConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+                               if (wrap_as != null)
+                                       return new EnumConstant (result, wrap_as);
+                               else
+                                       return result;
+                               
+                       case Binary.Operator.Multiply:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value *
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value *
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               return new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value *
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value *
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               return new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value *
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value *
+                                                                        ((ULongConstant) right).Value);
+                                               
+                                               return new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value *
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value *
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               return new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value *
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value *
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               return new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value *
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value *
+                                                                        ((IntConstant) right).Value);
+
+                                               return new IntConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+                               break;
+
+                       case Binary.Operator.Division:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value /
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value /
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               return new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value /
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value /
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               return new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value /
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value /
+                                                                        ((ULongConstant) right).Value);
+                                               
+                                               return new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value /
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value /
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               return new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value /
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value /
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               return new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value /
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value /
+                                                                        ((IntConstant) right).Value);
+
+                                               return new IntConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+
+                               } catch (DivideByZeroException) {
+                                       Report.Error (020, loc, "Division by constant zero");
+                               }
+                               
+                               break;
+                               
+                       case Binary.Operator.Modulus:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value %
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value %
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               return new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value %
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value %
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               return new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value %
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value %
+                                                                        ((ULongConstant) right).Value);
+                                               
+                                               return new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value %
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value %
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               return new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value %
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value %
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               return new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value %
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value %
+                                                                        ((IntConstant) right).Value);
+
+                                               return new IntConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+                               break;
+
+                               //
+                               // There is no overflow checking on left shift
+                               //
+                       case Binary.Operator.LeftShift:
+                               IntConstant ic = right.ToInt (loc);
+                               if (ic == null){
+                                       Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
+                                       return null;
+                               }
+                               int lshift_val = ic.Value;
+
+                               IntConstant lic;
+                               if ((lic = left.ConvertToInt ()) != null)
+                                       return new IntConstant (lic.Value << lshift_val);
+
+                               UIntConstant luic;
+                               if ((luic = left.ConvertToUInt ()) != null)
+                                       return new UIntConstant (luic.Value << lshift_val);
+
+                               LongConstant llc;
+                               if ((llc = left.ConvertToLong ()) != null)
+                                       return new LongConstant (llc.Value << lshift_val);
+
+                               ULongConstant lulc;
+                               if ((lulc = left.ConvertToULong ()) != null)
+                                       return new ULongConstant (lulc.Value << lshift_val);
+
+                               Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
+                               break;
+
+                               //
+                               // There is no overflow checking on right shift
+                               //
+                       case Binary.Operator.RightShift:
+                               IntConstant sic = right.ToInt (loc);
+                               if (sic == null){
+                                       Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
+                                       return null;
+                               }
+                               int rshift_val = sic.Value;
+
+                               IntConstant ric;
+                               if ((ric = left.ConvertToInt ()) != null)
+                                       return new IntConstant (ric.Value >> rshift_val);
+
+                               UIntConstant ruic;
+                               if ((ruic = left.ConvertToUInt ()) != null)
+                                       return new UIntConstant (ruic.Value >> rshift_val);
+
+                               LongConstant rlc;
+                               if ((rlc = left.ConvertToLong ()) != null)
+                                       return new LongConstant (rlc.Value >> rshift_val);
+
+                               ULongConstant rulc;
+                               if ((rulc = left.ConvertToULong ()) != null)
+                                       return new ULongConstant (rulc.Value >> rshift_val);
+
+                               Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
+                               break;
+
+                       case Binary.Operator.LogicalAnd:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value &&
+                                               ((BoolConstant) right).Value);
+                               }
+                               break;
+
+                       case Binary.Operator.LogicalOr:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value ||
+                                               ((BoolConstant) right).Value);
+                               }
+                               break;
+                               
+                       case Binary.Operator.Equality:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value ==
+                                               ((BoolConstant) right).Value);
+                               
+                               }
+                               if (left is StringConstant && right is StringConstant){
+                                       return new BoolConstant (
+                                               ((StringConstant) left).Value ==
+                                               ((StringConstant) right).Value);
+                                       
+                               }
+                               
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value ==
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value ==
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value ==
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value ==
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value ==
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value ==
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.Inequality:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value !=
+                                               ((BoolConstant) right).Value);
+                               }
+                               if (left is StringConstant && right is StringConstant){
+                                       return new BoolConstant (
+                                               ((StringConstant) left).Value !=
+                                               ((StringConstant) right).Value);
+                                       
+                               }
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value !=
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value !=
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value !=
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value !=
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value !=
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value !=
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.LessThan:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value <
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value <
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value <
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value <
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value <
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value <
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+                               
+                       case Binary.Operator.GreaterThan:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value >
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value >
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value >
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value >
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value >
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value >
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.GreaterThanOrEqual:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value >=
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value >=
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value >=
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value >=
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value >=
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value >=
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.LessThanOrEqual:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value <=
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value <=
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value <=
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value <=
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value <=
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value <=
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+                       }
+                                       
+                       return null;
+               }
+       }
+}