2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2002, 2003 Ximian, Inc.
12 namespace Mono.CSharp {
14 public class ConstantFold {
17 // Performs the numeric promotions on the left and right expresions
18 // and desposits the results on `lc' and `rc'.
20 // On success, the types of `lc' and `rc' on output will always match,
21 // and the pair will be one of:
29 // (short, short) (Happens with enumerations with underlying short type)
30 // (ushort, ushort) (Happens with enumerations with underlying short type)
32 static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
33 ref Constant left, ref Constant right,
36 if (left is DoubleConstant || right is DoubleConstant){
38 // If either side is a double, convert the other to a double
40 if (!(left is DoubleConstant))
41 left = left.ToDouble (loc);
43 if (!(right is DoubleConstant))
44 right = right.ToDouble (loc);
46 } else if (left is FloatConstant || right is FloatConstant) {
48 // If either side is a float, convert the other to a float
50 if (!(left is FloatConstant))
51 left = left.ToFloat (loc);
53 if (!(right is FloatConstant))
54 right = right.ToFloat (loc);
56 } else if (left is ULongConstant || right is ULongConstant){
58 // If either operand is of type ulong, the other operand is
59 // converted to type ulong. or an error ocurrs if the other
60 // operand is of type sbyte, short, int or long
62 Constant match, other;
64 if (left is ULongConstant){
67 if (!(right is ULongConstant))
68 right = right.ToULong (loc);
72 left = left.ToULong (loc);
76 if (other is SByteConstant || other is ShortConstant ||
77 other is IntConstant || other is LongConstant){
78 Binary.Error_OperatorAmbiguous
79 (loc, oper, other.Type, match.Type);
85 } else if (left is LongConstant || right is LongConstant){
87 // If either operand is of type long, the other operand is converted
90 if (!(left is LongConstant))
91 left = left.ToLong (loc);
92 else if (!(right is LongConstant))
93 right = right.ToLong (loc);
95 } else if (left is UIntConstant || right is UIntConstant){
97 // If either operand is of type uint, and the other
98 // operand is of type sbyte, short or int, the operands are
99 // converted to type long.
101 Constant match, other;
102 if (left is UIntConstant){
111 if (other is UIntConstant)
114 if (other is SByteConstant || other is ShortConstant ||
115 other is IntConstant){
116 left = left.ToLong (loc);
117 right = right.ToLong (loc);
121 } else if (left is EnumConstant || right is EnumConstant){
123 // If either operand is an enum constant, the other one must
124 // be implicitly convertable to that enum's underlying type.
128 if (left is EnumConstant){
130 match = (EnumConstant) left;
133 match = (EnumConstant) right;
136 bool need_check = (other is EnumConstant) ||
137 ((oper != Binary.Operator.Addition) &&
138 (oper != Binary.Operator.Subtraction));
141 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
142 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
148 if (left is EnumConstant)
149 left = ((EnumConstant) left).Child;
150 if (right is EnumConstant)
151 right = ((EnumConstant) right).Child;
156 // Force conversions to int32
158 if (!(left is IntConstant))
159 left = left.ToInt (loc);
160 if (!(right is IntConstant))
161 right = right.ToInt (loc);
166 static void Error_CompileTimeOverflow (Location loc)
168 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
172 /// Constant expression folder for binary operations.
174 /// Returns null if the expression can not be folded.
176 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
177 Constant left, Constant right, Location loc)
180 Type rt = right.Type;
181 Type result_type = null;
185 // Enumerator folding
187 if (rt == lt && left is EnumConstant)
191 // During an enum evaluation, we need to unwrap enumerations
193 if (ec.InEnumContext){
194 if (left is EnumConstant)
195 left = ((EnumConstant) left).Child;
197 if (right is EnumConstant)
198 right = ((EnumConstant) right).Child;
202 Constant result = null;
204 case Binary.Operator.BitwiseOr:
205 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
206 if (left == null || right == null)
209 if (left is IntConstant){
211 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
213 v = new IntConstant (res);
214 if (result_type == null)
217 return new EnumConstant (v, result_type);
218 } else if (left is UIntConstant){
220 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
222 v = new UIntConstant (res);
223 if (result_type == null)
226 return new EnumConstant (v, result_type);
227 } else if (left is LongConstant){
229 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
231 v = new LongConstant (res);
232 if (result_type == null)
235 return new EnumConstant (v, result_type);
236 } else if (left is ULongConstant){
238 ulong res = ((ULongConstant)left).Value |
239 ((ULongConstant)right).Value;
241 v = new ULongConstant (res);
242 if (result_type == null)
245 return new EnumConstant (v, result_type);
246 } else if (left is UShortConstant){
248 ushort res = (ushort) (((UShortConstant)left).Value |
249 ((UShortConstant)right).Value);
251 v = new UShortConstant (res);
252 if (result_type == null)
255 return new EnumConstant (v, result_type);
256 } else if (left is ShortConstant){
258 short res = (short) (((ShortConstant)left).Value |
259 ((ShortConstant)right).Value);
261 v = new ShortConstant (res);
262 if (result_type == null)
265 return new EnumConstant (v, result_type);
269 case Binary.Operator.BitwiseAnd:
270 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
271 if (left == null || right == null)
274 if (left is IntConstant){
276 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
278 v = new IntConstant (res);
279 if (result_type == null)
282 return new EnumConstant (v, result_type);
283 } else if (left is UIntConstant){
285 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
287 v = new UIntConstant (res);
288 if (result_type == null)
291 return new EnumConstant (v, result_type);
292 } else if (left is LongConstant){
294 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
296 v = new LongConstant (res);
297 if (result_type == null)
300 return new EnumConstant (v, result_type);
301 } else if (left is ULongConstant){
303 ulong res = ((ULongConstant)left).Value &
304 ((ULongConstant)right).Value;
306 v = new ULongConstant (res);
307 if (result_type == null)
310 return new EnumConstant (v, result_type);
311 } else if (left is UShortConstant){
313 ushort res = (ushort) (((UShortConstant)left).Value &
314 ((UShortConstant)right).Value);
316 v = new UShortConstant (res);
317 if (result_type == null)
320 return new EnumConstant (v, result_type);
321 } else if (left is ShortConstant){
323 short res = (short) (((ShortConstant)left).Value &
324 ((ShortConstant)right).Value);
326 v = new ShortConstant (res);
327 if (result_type == null)
330 return new EnumConstant (v, result_type);
334 case Binary.Operator.ExclusiveOr:
335 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
336 if (left == null || right == null)
339 if (left is IntConstant){
341 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
343 v = new IntConstant (res);
344 if (result_type == null)
347 return new EnumConstant (v, result_type);
348 } else if (left is UIntConstant){
350 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
352 v = new UIntConstant (res);
353 if (result_type == null)
356 return new EnumConstant (v, result_type);
357 } else if (left is LongConstant){
359 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
361 v = new LongConstant (res);
362 if (result_type == null)
365 return new EnumConstant (v, result_type);
366 } else if (left is ULongConstant){
368 ulong res = ((ULongConstant)left).Value ^
369 ((ULongConstant)right).Value;
371 v = new ULongConstant (res);
372 if (result_type == null)
375 return new EnumConstant (v, result_type);
376 } else if (left is UShortConstant){
378 ushort res = (ushort) (((UShortConstant)left).Value ^
379 ((UShortConstant)right).Value);
381 v = new UShortConstant (res);
382 if (result_type == null)
385 return new EnumConstant (v, result_type);
386 } else if (left is ShortConstant){
388 short res = (short)(((ShortConstant)left).Value ^
389 ((ShortConstant)right).Value);
391 v = new ShortConstant (res);
392 if (result_type == null)
395 return new EnumConstant (v, result_type);
399 case Binary.Operator.Addition:
400 bool left_is_string = left is StringConstant;
401 bool right_is_string = right is StringConstant;
404 // If both sides are strings, then concatenate, if
405 // one is a string, and the other is not, then defer
406 // to runtime concatenation
409 if (left_is_string || right_is_string){
410 if (left_is_string && right_is_string)
411 return new StringConstant (
412 ((StringConstant) left).Value +
413 ((StringConstant) right).Value);
419 // handle "E operator + (E x, U y)"
420 // handle "E operator + (Y y, E x)"
422 // note that E operator + (E x, E y) is invalid
424 if (left is EnumConstant){
425 if (right is EnumConstant){
428 if (((EnumConstant) left).Child.Type != right.Type)
432 } else if (right is EnumConstant){
433 if (((EnumConstant) right).Child.Type != left.Type)
435 wrap_as = right.Type;
439 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
440 if (left == null || right == null)
444 if (left is DoubleConstant){
447 if (ec.ConstantCheckState)
448 res = checked (((DoubleConstant) left).Value +
449 ((DoubleConstant) right).Value);
451 res = unchecked (((DoubleConstant) left).Value +
452 ((DoubleConstant) right).Value);
454 result = new DoubleConstant (res);
455 } else if (left is FloatConstant){
458 if (ec.ConstantCheckState)
459 res = checked (((FloatConstant) left).Value +
460 ((FloatConstant) right).Value);
462 res = unchecked (((FloatConstant) left).Value +
463 ((FloatConstant) right).Value);
465 result = new FloatConstant (res);
466 } else if (left is ULongConstant){
469 if (ec.ConstantCheckState)
470 res = checked (((ULongConstant) left).Value +
471 ((ULongConstant) right).Value);
473 res = unchecked (((ULongConstant) left).Value +
474 ((ULongConstant) right).Value);
476 result = new ULongConstant (res);
477 } else if (left is LongConstant){
480 if (ec.ConstantCheckState)
481 res = checked (((LongConstant) left).Value +
482 ((LongConstant) right).Value);
484 res = unchecked (((LongConstant) left).Value +
485 ((LongConstant) right).Value);
487 result = new LongConstant (res);
488 } else if (left is UIntConstant){
491 if (ec.ConstantCheckState)
492 res = checked (((UIntConstant) left).Value +
493 ((UIntConstant) right).Value);
495 res = unchecked (((UIntConstant) left).Value +
496 ((UIntConstant) right).Value);
498 result = new UIntConstant (res);
499 } else if (left is IntConstant){
502 if (ec.ConstantCheckState)
503 res = checked (((IntConstant) left).Value +
504 ((IntConstant) right).Value);
506 res = unchecked (((IntConstant) left).Value +
507 ((IntConstant) right).Value);
509 result = new IntConstant (res);
511 throw new Exception ( "Unexepected input: " + left);
513 } catch (OverflowException){
514 Error_CompileTimeOverflow (loc);
518 return new EnumConstant (result, wrap_as);
522 case Binary.Operator.Subtraction:
524 // handle "E operator - (E x, U y)"
525 // handle "E operator - (Y y, E x)"
526 // handle "U operator - (E x, E y)"
529 if (left is EnumConstant){
530 if (right is EnumConstant){
531 if (left.Type == right.Type)
532 wrap_as = TypeManager.EnumToUnderlying (left.Type);
536 if (((EnumConstant) left).Child.Type != right.Type)
540 } else if (right is EnumConstant){
541 if (((EnumConstant) right).Child.Type != left.Type)
543 wrap_as = right.Type;
546 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
547 if (left == null || right == null)
551 if (left is DoubleConstant){
554 if (ec.ConstantCheckState)
555 res = checked (((DoubleConstant) left).Value -
556 ((DoubleConstant) right).Value);
558 res = unchecked (((DoubleConstant) left).Value -
559 ((DoubleConstant) right).Value);
561 result = new DoubleConstant (res);
562 } else if (left is FloatConstant){
565 if (ec.ConstantCheckState)
566 res = checked (((FloatConstant) left).Value -
567 ((FloatConstant) right).Value);
569 res = unchecked (((FloatConstant) left).Value -
570 ((FloatConstant) right).Value);
572 result = new FloatConstant (res);
573 } else if (left is ULongConstant){
576 if (ec.ConstantCheckState)
577 res = checked (((ULongConstant) left).Value -
578 ((ULongConstant) right).Value);
580 res = unchecked (((ULongConstant) left).Value -
581 ((ULongConstant) right).Value);
583 result = new ULongConstant (res);
584 } else if (left is LongConstant){
587 if (ec.ConstantCheckState)
588 res = checked (((LongConstant) left).Value -
589 ((LongConstant) right).Value);
591 res = unchecked (((LongConstant) left).Value -
592 ((LongConstant) right).Value);
594 result = new LongConstant (res);
595 } else if (left is UIntConstant){
598 if (ec.ConstantCheckState)
599 res = checked (((UIntConstant) left).Value -
600 ((UIntConstant) right).Value);
602 res = unchecked (((UIntConstant) left).Value -
603 ((UIntConstant) right).Value);
605 result = new UIntConstant (res);
606 } else if (left is IntConstant){
609 if (ec.ConstantCheckState)
610 res = checked (((IntConstant) left).Value -
611 ((IntConstant) right).Value);
613 res = unchecked (((IntConstant) left).Value -
614 ((IntConstant) right).Value);
616 result = new IntConstant (res);
618 throw new Exception ( "Unexepected input: " + left);
620 } catch (OverflowException){
621 Error_CompileTimeOverflow (loc);
624 return new EnumConstant (result, wrap_as);
628 case Binary.Operator.Multiply:
629 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
630 if (left == null || right == null)
634 if (left is DoubleConstant){
637 if (ec.ConstantCheckState)
638 res = checked (((DoubleConstant) left).Value *
639 ((DoubleConstant) right).Value);
641 res = unchecked (((DoubleConstant) left).Value *
642 ((DoubleConstant) right).Value);
644 return new DoubleConstant (res);
645 } else if (left is FloatConstant){
648 if (ec.ConstantCheckState)
649 res = checked (((FloatConstant) left).Value *
650 ((FloatConstant) right).Value);
652 res = unchecked (((FloatConstant) left).Value *
653 ((FloatConstant) right).Value);
655 return new FloatConstant (res);
656 } else if (left is ULongConstant){
659 if (ec.ConstantCheckState)
660 res = checked (((ULongConstant) left).Value *
661 ((ULongConstant) right).Value);
663 res = unchecked (((ULongConstant) left).Value *
664 ((ULongConstant) right).Value);
666 return new ULongConstant (res);
667 } else if (left is LongConstant){
670 if (ec.ConstantCheckState)
671 res = checked (((LongConstant) left).Value *
672 ((LongConstant) right).Value);
674 res = unchecked (((LongConstant) left).Value *
675 ((LongConstant) right).Value);
677 return new LongConstant (res);
678 } else if (left is UIntConstant){
681 if (ec.ConstantCheckState)
682 res = checked (((UIntConstant) left).Value *
683 ((UIntConstant) right).Value);
685 res = unchecked (((UIntConstant) left).Value *
686 ((UIntConstant) right).Value);
688 return new UIntConstant (res);
689 } else if (left is IntConstant){
692 if (ec.ConstantCheckState)
693 res = checked (((IntConstant) left).Value *
694 ((IntConstant) right).Value);
696 res = unchecked (((IntConstant) left).Value *
697 ((IntConstant) right).Value);
699 return new IntConstant (res);
701 throw new Exception ( "Unexepected input: " + left);
703 } catch (OverflowException){
704 Error_CompileTimeOverflow (loc);
708 case Binary.Operator.Division:
709 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
710 if (left == null || right == null)
714 if (left is DoubleConstant){
717 if (ec.ConstantCheckState)
718 res = checked (((DoubleConstant) left).Value /
719 ((DoubleConstant) right).Value);
721 res = unchecked (((DoubleConstant) left).Value /
722 ((DoubleConstant) right).Value);
724 return new DoubleConstant (res);
725 } else if (left is FloatConstant){
728 if (ec.ConstantCheckState)
729 res = checked (((FloatConstant) left).Value /
730 ((FloatConstant) right).Value);
732 res = unchecked (((FloatConstant) left).Value /
733 ((FloatConstant) right).Value);
735 return new FloatConstant (res);
736 } else if (left is ULongConstant){
739 if (ec.ConstantCheckState)
740 res = checked (((ULongConstant) left).Value /
741 ((ULongConstant) right).Value);
743 res = unchecked (((ULongConstant) left).Value /
744 ((ULongConstant) right).Value);
746 return new ULongConstant (res);
747 } else if (left is LongConstant){
750 if (ec.ConstantCheckState)
751 res = checked (((LongConstant) left).Value /
752 ((LongConstant) right).Value);
754 res = unchecked (((LongConstant) left).Value /
755 ((LongConstant) right).Value);
757 return new LongConstant (res);
758 } else if (left is UIntConstant){
761 if (ec.ConstantCheckState)
762 res = checked (((UIntConstant) left).Value /
763 ((UIntConstant) right).Value);
765 res = unchecked (((UIntConstant) left).Value /
766 ((UIntConstant) right).Value);
768 return new UIntConstant (res);
769 } else if (left is IntConstant){
772 if (ec.ConstantCheckState)
773 res = checked (((IntConstant) left).Value /
774 ((IntConstant) right).Value);
776 res = unchecked (((IntConstant) left).Value /
777 ((IntConstant) right).Value);
779 return new IntConstant (res);
781 throw new Exception ( "Unexepected input: " + left);
783 } catch (OverflowException){
784 Error_CompileTimeOverflow (loc);
786 } catch (DivideByZeroException) {
787 Report.Error (020, loc, "Division by constant zero");
792 case Binary.Operator.Modulus:
793 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
794 if (left == null || right == null)
798 if (left is DoubleConstant){
801 if (ec.ConstantCheckState)
802 res = checked (((DoubleConstant) left).Value %
803 ((DoubleConstant) right).Value);
805 res = unchecked (((DoubleConstant) left).Value %
806 ((DoubleConstant) right).Value);
808 return new DoubleConstant (res);
809 } else if (left is FloatConstant){
812 if (ec.ConstantCheckState)
813 res = checked (((FloatConstant) left).Value %
814 ((FloatConstant) right).Value);
816 res = unchecked (((FloatConstant) left).Value %
817 ((FloatConstant) right).Value);
819 return new FloatConstant (res);
820 } else if (left is ULongConstant){
823 if (ec.ConstantCheckState)
824 res = checked (((ULongConstant) left).Value %
825 ((ULongConstant) right).Value);
827 res = unchecked (((ULongConstant) left).Value %
828 ((ULongConstant) right).Value);
830 return new ULongConstant (res);
831 } else if (left is LongConstant){
834 if (ec.ConstantCheckState)
835 res = checked (((LongConstant) left).Value %
836 ((LongConstant) right).Value);
838 res = unchecked (((LongConstant) left).Value %
839 ((LongConstant) right).Value);
841 return new LongConstant (res);
842 } else if (left is UIntConstant){
845 if (ec.ConstantCheckState)
846 res = checked (((UIntConstant) left).Value %
847 ((UIntConstant) right).Value);
849 res = unchecked (((UIntConstant) left).Value %
850 ((UIntConstant) right).Value);
852 return new UIntConstant (res);
853 } else if (left is IntConstant){
856 if (ec.ConstantCheckState)
857 res = checked (((IntConstant) left).Value %
858 ((IntConstant) right).Value);
860 res = unchecked (((IntConstant) left).Value %
861 ((IntConstant) right).Value);
863 return new IntConstant (res);
865 throw new Exception ( "Unexepected input: " + left);
867 } catch (DivideByZeroException){
868 Report.Error (020, loc, "Division by constant zero");
869 } catch (OverflowException){
870 Error_CompileTimeOverflow (loc);
875 // There is no overflow checking on left shift
877 case Binary.Operator.LeftShift:
878 IntConstant ic = right.ToInt (loc);
880 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
883 int lshift_val = ic.Value;
886 if ((lic = left.ConvertToInt ()) != null)
887 return new IntConstant (lic.Value << lshift_val);
890 if ((luic = left.ConvertToUInt ()) != null)
891 return new UIntConstant (luic.Value << lshift_val);
894 if ((llc = left.ConvertToLong ()) != null)
895 return new LongConstant (llc.Value << lshift_val);
898 if ((lulc = left.ConvertToULong ()) != null)
899 return new ULongConstant (lulc.Value << lshift_val);
901 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
905 // There is no overflow checking on right shift
907 case Binary.Operator.RightShift:
908 IntConstant sic = right.ToInt (loc);
910 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
913 int rshift_val = sic.Value;
916 if ((ric = left.ConvertToInt ()) != null)
917 return new IntConstant (ric.Value >> rshift_val);
920 if ((ruic = left.ConvertToUInt ()) != null)
921 return new UIntConstant (ruic.Value >> rshift_val);
924 if ((rlc = left.ConvertToLong ()) != null)
925 return new LongConstant (rlc.Value >> rshift_val);
928 if ((rulc = left.ConvertToULong ()) != null)
929 return new ULongConstant (rulc.Value >> rshift_val);
931 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
934 case Binary.Operator.LogicalAnd:
935 if (left is BoolConstant && right is BoolConstant){
936 return new BoolConstant (
937 ((BoolConstant) left).Value &&
938 ((BoolConstant) right).Value);
942 case Binary.Operator.LogicalOr:
943 if (left is BoolConstant && right is BoolConstant){
944 return new BoolConstant (
945 ((BoolConstant) left).Value ||
946 ((BoolConstant) right).Value);
950 case Binary.Operator.Equality:
951 if (left is BoolConstant && right is BoolConstant){
952 return new BoolConstant (
953 ((BoolConstant) left).Value ==
954 ((BoolConstant) right).Value);
957 if (left is StringConstant && right is StringConstant){
958 return new BoolConstant (
959 ((StringConstant) left).Value ==
960 ((StringConstant) right).Value);
964 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
965 if (left == null || right == null)
969 if (left is DoubleConstant)
970 bool_res = ((DoubleConstant) left).Value ==
971 ((DoubleConstant) right).Value;
972 else if (left is FloatConstant)
973 bool_res = ((FloatConstant) left).Value ==
974 ((FloatConstant) right).Value;
975 else if (left is ULongConstant)
976 bool_res = ((ULongConstant) left).Value ==
977 ((ULongConstant) right).Value;
978 else if (left is LongConstant)
979 bool_res = ((LongConstant) left).Value ==
980 ((LongConstant) right).Value;
981 else if (left is UIntConstant)
982 bool_res = ((UIntConstant) left).Value ==
983 ((UIntConstant) right).Value;
984 else if (left is IntConstant)
985 bool_res = ((IntConstant) left).Value ==
986 ((IntConstant) right).Value;
990 return new BoolConstant (bool_res);
992 case Binary.Operator.Inequality:
993 if (left is BoolConstant && right is BoolConstant){
994 return new BoolConstant (
995 ((BoolConstant) left).Value !=
996 ((BoolConstant) right).Value);
998 if (left is StringConstant && right is StringConstant){
999 return new BoolConstant (
1000 ((StringConstant) left).Value !=
1001 ((StringConstant) right).Value);
1004 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1005 if (left == null || right == null)
1009 if (left is DoubleConstant)
1010 bool_res = ((DoubleConstant) left).Value !=
1011 ((DoubleConstant) right).Value;
1012 else if (left is FloatConstant)
1013 bool_res = ((FloatConstant) left).Value !=
1014 ((FloatConstant) right).Value;
1015 else if (left is ULongConstant)
1016 bool_res = ((ULongConstant) left).Value !=
1017 ((ULongConstant) right).Value;
1018 else if (left is LongConstant)
1019 bool_res = ((LongConstant) left).Value !=
1020 ((LongConstant) right).Value;
1021 else if (left is UIntConstant)
1022 bool_res = ((UIntConstant) left).Value !=
1023 ((UIntConstant) right).Value;
1024 else if (left is IntConstant)
1025 bool_res = ((IntConstant) left).Value !=
1026 ((IntConstant) right).Value;
1030 return new BoolConstant (bool_res);
1032 case Binary.Operator.LessThan:
1033 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1034 if (left == null || right == null)
1038 if (left is DoubleConstant)
1039 bool_res = ((DoubleConstant) left).Value <
1040 ((DoubleConstant) right).Value;
1041 else if (left is FloatConstant)
1042 bool_res = ((FloatConstant) left).Value <
1043 ((FloatConstant) right).Value;
1044 else if (left is ULongConstant)
1045 bool_res = ((ULongConstant) left).Value <
1046 ((ULongConstant) right).Value;
1047 else if (left is LongConstant)
1048 bool_res = ((LongConstant) left).Value <
1049 ((LongConstant) right).Value;
1050 else if (left is UIntConstant)
1051 bool_res = ((UIntConstant) left).Value <
1052 ((UIntConstant) right).Value;
1053 else if (left is IntConstant)
1054 bool_res = ((IntConstant) left).Value <
1055 ((IntConstant) right).Value;
1059 return new BoolConstant (bool_res);
1061 case Binary.Operator.GreaterThan:
1062 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1063 if (left == null || right == null)
1067 if (left is DoubleConstant)
1068 bool_res = ((DoubleConstant) left).Value >
1069 ((DoubleConstant) right).Value;
1070 else if (left is FloatConstant)
1071 bool_res = ((FloatConstant) left).Value >
1072 ((FloatConstant) right).Value;
1073 else if (left is ULongConstant)
1074 bool_res = ((ULongConstant) left).Value >
1075 ((ULongConstant) right).Value;
1076 else if (left is LongConstant)
1077 bool_res = ((LongConstant) left).Value >
1078 ((LongConstant) right).Value;
1079 else if (left is UIntConstant)
1080 bool_res = ((UIntConstant) left).Value >
1081 ((UIntConstant) right).Value;
1082 else if (left is IntConstant)
1083 bool_res = ((IntConstant) left).Value >
1084 ((IntConstant) right).Value;
1088 return new BoolConstant (bool_res);
1090 case Binary.Operator.GreaterThanOrEqual:
1091 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1092 if (left == null || right == null)
1096 if (left is DoubleConstant)
1097 bool_res = ((DoubleConstant) left).Value >=
1098 ((DoubleConstant) right).Value;
1099 else if (left is FloatConstant)
1100 bool_res = ((FloatConstant) left).Value >=
1101 ((FloatConstant) right).Value;
1102 else if (left is ULongConstant)
1103 bool_res = ((ULongConstant) left).Value >=
1104 ((ULongConstant) right).Value;
1105 else if (left is LongConstant)
1106 bool_res = ((LongConstant) left).Value >=
1107 ((LongConstant) right).Value;
1108 else if (left is UIntConstant)
1109 bool_res = ((UIntConstant) left).Value >=
1110 ((UIntConstant) right).Value;
1111 else if (left is IntConstant)
1112 bool_res = ((IntConstant) left).Value >=
1113 ((IntConstant) right).Value;
1117 return new BoolConstant (bool_res);
1119 case Binary.Operator.LessThanOrEqual:
1120 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1121 if (left == null || right == null)
1125 if (left is DoubleConstant)
1126 bool_res = ((DoubleConstant) left).Value <=
1127 ((DoubleConstant) right).Value;
1128 else if (left is FloatConstant)
1129 bool_res = ((FloatConstant) left).Value <=
1130 ((FloatConstant) right).Value;
1131 else if (left is ULongConstant)
1132 bool_res = ((ULongConstant) left).Value <=
1133 ((ULongConstant) right).Value;
1134 else if (left is LongConstant)
1135 bool_res = ((LongConstant) left).Value <=
1136 ((LongConstant) right).Value;
1137 else if (left is UIntConstant)
1138 bool_res = ((UIntConstant) left).Value <=
1139 ((UIntConstant) right).Value;
1140 else if (left is IntConstant)
1141 bool_res = ((IntConstant) left).Value <=
1142 ((IntConstant) right).Value;
1146 return new BoolConstant (bool_res);