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.
102 if (left is UIntConstant)
108 if (other is UIntConstant)
111 IntConstant ic = other as IntConstant;
115 left = new UIntConstant ((uint) ic.Value);
117 right = new UIntConstant ((uint) ic.Value);
122 if (other is SByteConstant || other is ShortConstant || ic != null){
123 left = left.ToLong (loc);
124 right = right.ToLong (loc);
128 } else if (left is EnumConstant || right is EnumConstant){
130 // If either operand is an enum constant, the other one must
131 // be implicitly convertable to that enum's underlying type.
135 if (left is EnumConstant){
137 match = (EnumConstant) left;
140 match = (EnumConstant) right;
143 bool need_check = (other is EnumConstant) ||
144 ((oper != Binary.Operator.Addition) &&
145 (oper != Binary.Operator.Subtraction));
148 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
149 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
155 if (left is EnumConstant)
156 left = ((EnumConstant) left).Child;
157 if (right is EnumConstant)
158 right = ((EnumConstant) right).Child;
163 // Force conversions to int32
165 if (!(left is IntConstant))
166 left = left.ToInt (loc);
167 if (!(right is IntConstant))
168 right = right.ToInt (loc);
173 static void Error_CompileTimeOverflow (Location loc)
175 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
179 /// Constant expression folder for binary operations.
181 /// Returns null if the expression can not be folded.
183 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
184 Constant left, Constant right, Location loc)
187 Type rt = right.Type;
188 Type result_type = null;
192 // Enumerator folding
194 if (rt == lt && left is EnumConstant)
198 // During an enum evaluation, we need to unwrap enumerations
200 if (ec.InEnumContext){
201 if (left is EnumConstant)
202 left = ((EnumConstant) left).Child;
204 if (right is EnumConstant)
205 right = ((EnumConstant) right).Child;
209 Constant result = null;
211 case Binary.Operator.BitwiseOr:
212 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
213 if (left == null || right == null)
216 if (left is IntConstant){
218 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
220 v = new IntConstant (res);
221 if (result_type == null)
224 return new EnumConstant (v, result_type);
225 } else if (left is UIntConstant){
227 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
229 v = new UIntConstant (res);
230 if (result_type == null)
233 return new EnumConstant (v, result_type);
234 } else if (left is LongConstant){
236 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
238 v = new LongConstant (res);
239 if (result_type == null)
242 return new EnumConstant (v, result_type);
243 } else if (left is ULongConstant){
245 ulong res = ((ULongConstant)left).Value |
246 ((ULongConstant)right).Value;
248 v = new ULongConstant (res);
249 if (result_type == null)
252 return new EnumConstant (v, result_type);
253 } else if (left is UShortConstant){
255 ushort res = (ushort) (((UShortConstant)left).Value |
256 ((UShortConstant)right).Value);
258 v = new UShortConstant (res);
259 if (result_type == null)
262 return new EnumConstant (v, result_type);
263 } else if (left is ShortConstant){
265 short res = (short) (((ShortConstant)left).Value |
266 ((ShortConstant)right).Value);
268 v = new ShortConstant (res);
269 if (result_type == null)
272 return new EnumConstant (v, result_type);
276 case Binary.Operator.BitwiseAnd:
277 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
278 if (left == null || right == null)
281 if (left is IntConstant){
283 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
285 v = new IntConstant (res);
286 if (result_type == null)
289 return new EnumConstant (v, result_type);
290 } else if (left is UIntConstant){
292 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
294 v = new UIntConstant (res);
295 if (result_type == null)
298 return new EnumConstant (v, result_type);
299 } else if (left is LongConstant){
301 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
303 v = new LongConstant (res);
304 if (result_type == null)
307 return new EnumConstant (v, result_type);
308 } else if (left is ULongConstant){
310 ulong res = ((ULongConstant)left).Value &
311 ((ULongConstant)right).Value;
313 v = new ULongConstant (res);
314 if (result_type == null)
317 return new EnumConstant (v, result_type);
318 } else if (left is UShortConstant){
320 ushort res = (ushort) (((UShortConstant)left).Value &
321 ((UShortConstant)right).Value);
323 v = new UShortConstant (res);
324 if (result_type == null)
327 return new EnumConstant (v, result_type);
328 } else if (left is ShortConstant){
330 short res = (short) (((ShortConstant)left).Value &
331 ((ShortConstant)right).Value);
333 v = new ShortConstant (res);
334 if (result_type == null)
337 return new EnumConstant (v, result_type);
341 case Binary.Operator.ExclusiveOr:
342 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
343 if (left == null || right == null)
346 if (left is IntConstant){
348 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
350 v = new IntConstant (res);
351 if (result_type == null)
354 return new EnumConstant (v, result_type);
355 } else if (left is UIntConstant){
357 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
359 v = new UIntConstant (res);
360 if (result_type == null)
363 return new EnumConstant (v, result_type);
364 } else if (left is LongConstant){
366 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
368 v = new LongConstant (res);
369 if (result_type == null)
372 return new EnumConstant (v, result_type);
373 } else if (left is ULongConstant){
375 ulong res = ((ULongConstant)left).Value ^
376 ((ULongConstant)right).Value;
378 v = new ULongConstant (res);
379 if (result_type == null)
382 return new EnumConstant (v, result_type);
383 } else if (left is UShortConstant){
385 ushort res = (ushort) (((UShortConstant)left).Value ^
386 ((UShortConstant)right).Value);
388 v = new UShortConstant (res);
389 if (result_type == null)
392 return new EnumConstant (v, result_type);
393 } else if (left is ShortConstant){
395 short res = (short)(((ShortConstant)left).Value ^
396 ((ShortConstant)right).Value);
398 v = new ShortConstant (res);
399 if (result_type == null)
402 return new EnumConstant (v, result_type);
406 case Binary.Operator.Addition:
407 bool left_is_string = left is StringConstant;
408 bool right_is_string = right is StringConstant;
411 // If both sides are strings, then concatenate, if
412 // one is a string, and the other is not, then defer
413 // to runtime concatenation
416 if (left_is_string || right_is_string){
417 if (left_is_string && right_is_string)
418 return new StringConstant (
419 ((StringConstant) left).Value +
420 ((StringConstant) right).Value);
426 // handle "E operator + (E x, U y)"
427 // handle "E operator + (Y y, E x)"
429 // note that E operator + (E x, E y) is invalid
431 if (left is EnumConstant){
432 if (right is EnumConstant){
435 if (((EnumConstant) left).Child.Type != right.Type)
439 } else if (right is EnumConstant){
440 if (((EnumConstant) right).Child.Type != left.Type)
442 wrap_as = right.Type;
446 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
447 if (left == null || right == null)
451 if (left is DoubleConstant){
454 if (ec.ConstantCheckState)
455 res = checked (((DoubleConstant) left).Value +
456 ((DoubleConstant) right).Value);
458 res = unchecked (((DoubleConstant) left).Value +
459 ((DoubleConstant) right).Value);
461 result = new DoubleConstant (res);
462 } else if (left is FloatConstant){
465 if (ec.ConstantCheckState)
466 res = checked (((FloatConstant) left).Value +
467 ((FloatConstant) right).Value);
469 res = unchecked (((FloatConstant) left).Value +
470 ((FloatConstant) right).Value);
472 result = new FloatConstant (res);
473 } else if (left is ULongConstant){
476 if (ec.ConstantCheckState)
477 res = checked (((ULongConstant) left).Value +
478 ((ULongConstant) right).Value);
480 res = unchecked (((ULongConstant) left).Value +
481 ((ULongConstant) right).Value);
483 result = new ULongConstant (res);
484 } else if (left is LongConstant){
487 if (ec.ConstantCheckState)
488 res = checked (((LongConstant) left).Value +
489 ((LongConstant) right).Value);
491 res = unchecked (((LongConstant) left).Value +
492 ((LongConstant) right).Value);
494 result = new LongConstant (res);
495 } else if (left is UIntConstant){
498 if (ec.ConstantCheckState)
499 res = checked (((UIntConstant) left).Value +
500 ((UIntConstant) right).Value);
502 res = unchecked (((UIntConstant) left).Value +
503 ((UIntConstant) right).Value);
505 result = new UIntConstant (res);
506 } else if (left is IntConstant){
509 if (ec.ConstantCheckState)
510 res = checked (((IntConstant) left).Value +
511 ((IntConstant) right).Value);
513 res = unchecked (((IntConstant) left).Value +
514 ((IntConstant) right).Value);
516 result = new IntConstant (res);
518 throw new Exception ( "Unexepected input: " + left);
520 } catch (OverflowException){
521 Error_CompileTimeOverflow (loc);
525 return new EnumConstant (result, wrap_as);
529 case Binary.Operator.Subtraction:
531 // handle "E operator - (E x, U y)"
532 // handle "E operator - (Y y, E x)"
533 // handle "U operator - (E x, E y)"
536 if (left is EnumConstant){
537 if (right is EnumConstant){
538 if (left.Type == right.Type)
539 wrap_as = TypeManager.EnumToUnderlying (left.Type);
543 if (((EnumConstant) left).Child.Type != right.Type)
547 } else if (right is EnumConstant){
548 if (((EnumConstant) right).Child.Type != left.Type)
550 wrap_as = right.Type;
553 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
554 if (left == null || right == null)
558 if (left is DoubleConstant){
561 if (ec.ConstantCheckState)
562 res = checked (((DoubleConstant) left).Value -
563 ((DoubleConstant) right).Value);
565 res = unchecked (((DoubleConstant) left).Value -
566 ((DoubleConstant) right).Value);
568 result = new DoubleConstant (res);
569 } else if (left is FloatConstant){
572 if (ec.ConstantCheckState)
573 res = checked (((FloatConstant) left).Value -
574 ((FloatConstant) right).Value);
576 res = unchecked (((FloatConstant) left).Value -
577 ((FloatConstant) right).Value);
579 result = new FloatConstant (res);
580 } else if (left is ULongConstant){
583 if (ec.ConstantCheckState)
584 res = checked (((ULongConstant) left).Value -
585 ((ULongConstant) right).Value);
587 res = unchecked (((ULongConstant) left).Value -
588 ((ULongConstant) right).Value);
590 result = new ULongConstant (res);
591 } else if (left is LongConstant){
594 if (ec.ConstantCheckState)
595 res = checked (((LongConstant) left).Value -
596 ((LongConstant) right).Value);
598 res = unchecked (((LongConstant) left).Value -
599 ((LongConstant) right).Value);
601 result = new LongConstant (res);
602 } else if (left is UIntConstant){
605 if (ec.ConstantCheckState)
606 res = checked (((UIntConstant) left).Value -
607 ((UIntConstant) right).Value);
609 res = unchecked (((UIntConstant) left).Value -
610 ((UIntConstant) right).Value);
612 result = new UIntConstant (res);
613 } else if (left is IntConstant){
616 if (ec.ConstantCheckState)
617 res = checked (((IntConstant) left).Value -
618 ((IntConstant) right).Value);
620 res = unchecked (((IntConstant) left).Value -
621 ((IntConstant) right).Value);
623 result = new IntConstant (res);
625 throw new Exception ( "Unexepected input: " + left);
627 } catch (OverflowException){
628 Error_CompileTimeOverflow (loc);
631 return new EnumConstant (result, wrap_as);
635 case Binary.Operator.Multiply:
636 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
637 if (left == null || right == null)
641 if (left is DoubleConstant){
644 if (ec.ConstantCheckState)
645 res = checked (((DoubleConstant) left).Value *
646 ((DoubleConstant) right).Value);
648 res = unchecked (((DoubleConstant) left).Value *
649 ((DoubleConstant) right).Value);
651 return new DoubleConstant (res);
652 } else if (left is FloatConstant){
655 if (ec.ConstantCheckState)
656 res = checked (((FloatConstant) left).Value *
657 ((FloatConstant) right).Value);
659 res = unchecked (((FloatConstant) left).Value *
660 ((FloatConstant) right).Value);
662 return new FloatConstant (res);
663 } else if (left is ULongConstant){
666 if (ec.ConstantCheckState)
667 res = checked (((ULongConstant) left).Value *
668 ((ULongConstant) right).Value);
670 res = unchecked (((ULongConstant) left).Value *
671 ((ULongConstant) right).Value);
673 return new ULongConstant (res);
674 } else if (left is LongConstant){
677 if (ec.ConstantCheckState)
678 res = checked (((LongConstant) left).Value *
679 ((LongConstant) right).Value);
681 res = unchecked (((LongConstant) left).Value *
682 ((LongConstant) right).Value);
684 return new LongConstant (res);
685 } else if (left is UIntConstant){
688 if (ec.ConstantCheckState)
689 res = checked (((UIntConstant) left).Value *
690 ((UIntConstant) right).Value);
692 res = unchecked (((UIntConstant) left).Value *
693 ((UIntConstant) right).Value);
695 return new UIntConstant (res);
696 } else if (left is IntConstant){
699 if (ec.ConstantCheckState)
700 res = checked (((IntConstant) left).Value *
701 ((IntConstant) right).Value);
703 res = unchecked (((IntConstant) left).Value *
704 ((IntConstant) right).Value);
706 return new IntConstant (res);
708 throw new Exception ( "Unexepected input: " + left);
710 } catch (OverflowException){
711 Error_CompileTimeOverflow (loc);
715 case Binary.Operator.Division:
716 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
717 if (left == null || right == null)
721 if (left is DoubleConstant){
724 if (ec.ConstantCheckState)
725 res = checked (((DoubleConstant) left).Value /
726 ((DoubleConstant) right).Value);
728 res = unchecked (((DoubleConstant) left).Value /
729 ((DoubleConstant) right).Value);
731 return new DoubleConstant (res);
732 } else if (left is FloatConstant){
735 if (ec.ConstantCheckState)
736 res = checked (((FloatConstant) left).Value /
737 ((FloatConstant) right).Value);
739 res = unchecked (((FloatConstant) left).Value /
740 ((FloatConstant) right).Value);
742 return new FloatConstant (res);
743 } else if (left is ULongConstant){
746 if (ec.ConstantCheckState)
747 res = checked (((ULongConstant) left).Value /
748 ((ULongConstant) right).Value);
750 res = unchecked (((ULongConstant) left).Value /
751 ((ULongConstant) right).Value);
753 return new ULongConstant (res);
754 } else if (left is LongConstant){
757 if (ec.ConstantCheckState)
758 res = checked (((LongConstant) left).Value /
759 ((LongConstant) right).Value);
761 res = unchecked (((LongConstant) left).Value /
762 ((LongConstant) right).Value);
764 return new LongConstant (res);
765 } else if (left is UIntConstant){
768 if (ec.ConstantCheckState)
769 res = checked (((UIntConstant) left).Value /
770 ((UIntConstant) right).Value);
772 res = unchecked (((UIntConstant) left).Value /
773 ((UIntConstant) right).Value);
775 return new UIntConstant (res);
776 } else if (left is IntConstant){
779 if (ec.ConstantCheckState)
780 res = checked (((IntConstant) left).Value /
781 ((IntConstant) right).Value);
783 res = unchecked (((IntConstant) left).Value /
784 ((IntConstant) right).Value);
786 return new IntConstant (res);
788 throw new Exception ( "Unexepected input: " + left);
790 } catch (OverflowException){
791 Error_CompileTimeOverflow (loc);
793 } catch (DivideByZeroException) {
794 Report.Error (020, loc, "Division by constant zero");
799 case Binary.Operator.Modulus:
800 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
801 if (left == null || right == null)
805 if (left is DoubleConstant){
808 if (ec.ConstantCheckState)
809 res = checked (((DoubleConstant) left).Value %
810 ((DoubleConstant) right).Value);
812 res = unchecked (((DoubleConstant) left).Value %
813 ((DoubleConstant) right).Value);
815 return new DoubleConstant (res);
816 } else if (left is FloatConstant){
819 if (ec.ConstantCheckState)
820 res = checked (((FloatConstant) left).Value %
821 ((FloatConstant) right).Value);
823 res = unchecked (((FloatConstant) left).Value %
824 ((FloatConstant) right).Value);
826 return new FloatConstant (res);
827 } else if (left is ULongConstant){
830 if (ec.ConstantCheckState)
831 res = checked (((ULongConstant) left).Value %
832 ((ULongConstant) right).Value);
834 res = unchecked (((ULongConstant) left).Value %
835 ((ULongConstant) right).Value);
837 return new ULongConstant (res);
838 } else if (left is LongConstant){
841 if (ec.ConstantCheckState)
842 res = checked (((LongConstant) left).Value %
843 ((LongConstant) right).Value);
845 res = unchecked (((LongConstant) left).Value %
846 ((LongConstant) right).Value);
848 return new LongConstant (res);
849 } else if (left is UIntConstant){
852 if (ec.ConstantCheckState)
853 res = checked (((UIntConstant) left).Value %
854 ((UIntConstant) right).Value);
856 res = unchecked (((UIntConstant) left).Value %
857 ((UIntConstant) right).Value);
859 return new UIntConstant (res);
860 } else if (left is IntConstant){
863 if (ec.ConstantCheckState)
864 res = checked (((IntConstant) left).Value %
865 ((IntConstant) right).Value);
867 res = unchecked (((IntConstant) left).Value %
868 ((IntConstant) right).Value);
870 return new IntConstant (res);
872 throw new Exception ( "Unexepected input: " + left);
874 } catch (DivideByZeroException){
875 Report.Error (020, loc, "Division by constant zero");
876 } catch (OverflowException){
877 Error_CompileTimeOverflow (loc);
882 // There is no overflow checking on left shift
884 case Binary.Operator.LeftShift:
885 IntConstant ic = right.ToInt (loc);
887 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
890 int lshift_val = ic.Value;
893 if ((lic = left.ConvertToInt ()) != null)
894 return new IntConstant (lic.Value << lshift_val);
897 if ((luic = left.ConvertToUInt ()) != null)
898 return new UIntConstant (luic.Value << lshift_val);
901 if ((llc = left.ConvertToLong ()) != null)
902 return new LongConstant (llc.Value << lshift_val);
905 if ((lulc = left.ConvertToULong ()) != null)
906 return new ULongConstant (lulc.Value << lshift_val);
908 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
912 // There is no overflow checking on right shift
914 case Binary.Operator.RightShift:
915 IntConstant sic = right.ToInt (loc);
917 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
920 int rshift_val = sic.Value;
923 if ((ric = left.ConvertToInt ()) != null)
924 return new IntConstant (ric.Value >> rshift_val);
927 if ((ruic = left.ConvertToUInt ()) != null)
928 return new UIntConstant (ruic.Value >> rshift_val);
931 if ((rlc = left.ConvertToLong ()) != null)
932 return new LongConstant (rlc.Value >> rshift_val);
935 if ((rulc = left.ConvertToULong ()) != null)
936 return new ULongConstant (rulc.Value >> rshift_val);
938 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
941 case Binary.Operator.LogicalAnd:
942 if (left is BoolConstant && right is BoolConstant){
943 return new BoolConstant (
944 ((BoolConstant) left).Value &&
945 ((BoolConstant) right).Value);
949 case Binary.Operator.LogicalOr:
950 if (left is BoolConstant && right is BoolConstant){
951 return new BoolConstant (
952 ((BoolConstant) left).Value ||
953 ((BoolConstant) right).Value);
957 case Binary.Operator.Equality:
958 if (left is BoolConstant && right is BoolConstant){
959 return new BoolConstant (
960 ((BoolConstant) left).Value ==
961 ((BoolConstant) right).Value);
964 if (left is StringConstant && right is StringConstant){
965 return new BoolConstant (
966 ((StringConstant) left).Value ==
967 ((StringConstant) right).Value);
971 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
972 if (left == null || right == null)
976 if (left is DoubleConstant)
977 bool_res = ((DoubleConstant) left).Value ==
978 ((DoubleConstant) right).Value;
979 else if (left is FloatConstant)
980 bool_res = ((FloatConstant) left).Value ==
981 ((FloatConstant) right).Value;
982 else if (left is ULongConstant)
983 bool_res = ((ULongConstant) left).Value ==
984 ((ULongConstant) right).Value;
985 else if (left is LongConstant)
986 bool_res = ((LongConstant) left).Value ==
987 ((LongConstant) right).Value;
988 else if (left is UIntConstant)
989 bool_res = ((UIntConstant) left).Value ==
990 ((UIntConstant) right).Value;
991 else if (left is IntConstant)
992 bool_res = ((IntConstant) left).Value ==
993 ((IntConstant) right).Value;
997 return new BoolConstant (bool_res);
999 case Binary.Operator.Inequality:
1000 if (left is BoolConstant && right is BoolConstant){
1001 return new BoolConstant (
1002 ((BoolConstant) left).Value !=
1003 ((BoolConstant) right).Value);
1005 if (left is StringConstant && right is StringConstant){
1006 return new BoolConstant (
1007 ((StringConstant) left).Value !=
1008 ((StringConstant) right).Value);
1011 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1012 if (left == null || right == null)
1016 if (left is DoubleConstant)
1017 bool_res = ((DoubleConstant) left).Value !=
1018 ((DoubleConstant) right).Value;
1019 else if (left is FloatConstant)
1020 bool_res = ((FloatConstant) left).Value !=
1021 ((FloatConstant) right).Value;
1022 else if (left is ULongConstant)
1023 bool_res = ((ULongConstant) left).Value !=
1024 ((ULongConstant) right).Value;
1025 else if (left is LongConstant)
1026 bool_res = ((LongConstant) left).Value !=
1027 ((LongConstant) right).Value;
1028 else if (left is UIntConstant)
1029 bool_res = ((UIntConstant) left).Value !=
1030 ((UIntConstant) right).Value;
1031 else if (left is IntConstant)
1032 bool_res = ((IntConstant) left).Value !=
1033 ((IntConstant) right).Value;
1037 return new BoolConstant (bool_res);
1039 case Binary.Operator.LessThan:
1040 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1041 if (left == null || right == null)
1045 if (left is DoubleConstant)
1046 bool_res = ((DoubleConstant) left).Value <
1047 ((DoubleConstant) right).Value;
1048 else if (left is FloatConstant)
1049 bool_res = ((FloatConstant) left).Value <
1050 ((FloatConstant) right).Value;
1051 else if (left is ULongConstant)
1052 bool_res = ((ULongConstant) left).Value <
1053 ((ULongConstant) right).Value;
1054 else if (left is LongConstant)
1055 bool_res = ((LongConstant) left).Value <
1056 ((LongConstant) right).Value;
1057 else if (left is UIntConstant)
1058 bool_res = ((UIntConstant) left).Value <
1059 ((UIntConstant) right).Value;
1060 else if (left is IntConstant)
1061 bool_res = ((IntConstant) left).Value <
1062 ((IntConstant) right).Value;
1066 return new BoolConstant (bool_res);
1068 case Binary.Operator.GreaterThan:
1069 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1070 if (left == null || right == null)
1074 if (left is DoubleConstant)
1075 bool_res = ((DoubleConstant) left).Value >
1076 ((DoubleConstant) right).Value;
1077 else if (left is FloatConstant)
1078 bool_res = ((FloatConstant) left).Value >
1079 ((FloatConstant) right).Value;
1080 else if (left is ULongConstant)
1081 bool_res = ((ULongConstant) left).Value >
1082 ((ULongConstant) right).Value;
1083 else if (left is LongConstant)
1084 bool_res = ((LongConstant) left).Value >
1085 ((LongConstant) right).Value;
1086 else if (left is UIntConstant)
1087 bool_res = ((UIntConstant) left).Value >
1088 ((UIntConstant) right).Value;
1089 else if (left is IntConstant)
1090 bool_res = ((IntConstant) left).Value >
1091 ((IntConstant) right).Value;
1095 return new BoolConstant (bool_res);
1097 case Binary.Operator.GreaterThanOrEqual:
1098 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1099 if (left == null || right == null)
1103 if (left is DoubleConstant)
1104 bool_res = ((DoubleConstant) left).Value >=
1105 ((DoubleConstant) right).Value;
1106 else if (left is FloatConstant)
1107 bool_res = ((FloatConstant) left).Value >=
1108 ((FloatConstant) right).Value;
1109 else if (left is ULongConstant)
1110 bool_res = ((ULongConstant) left).Value >=
1111 ((ULongConstant) right).Value;
1112 else if (left is LongConstant)
1113 bool_res = ((LongConstant) left).Value >=
1114 ((LongConstant) right).Value;
1115 else if (left is UIntConstant)
1116 bool_res = ((UIntConstant) left).Value >=
1117 ((UIntConstant) right).Value;
1118 else if (left is IntConstant)
1119 bool_res = ((IntConstant) left).Value >=
1120 ((IntConstant) right).Value;
1124 return new BoolConstant (bool_res);
1126 case Binary.Operator.LessThanOrEqual:
1127 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1128 if (left == null || right == null)
1132 if (left is DoubleConstant)
1133 bool_res = ((DoubleConstant) left).Value <=
1134 ((DoubleConstant) right).Value;
1135 else if (left is FloatConstant)
1136 bool_res = ((FloatConstant) left).Value <=
1137 ((FloatConstant) right).Value;
1138 else if (left is ULongConstant)
1139 bool_res = ((ULongConstant) left).Value <=
1140 ((ULongConstant) right).Value;
1141 else if (left is LongConstant)
1142 bool_res = ((LongConstant) left).Value <=
1143 ((LongConstant) right).Value;
1144 else if (left is UIntConstant)
1145 bool_res = ((UIntConstant) left).Value <=
1146 ((UIntConstant) right).Value;
1147 else if (left is IntConstant)
1148 bool_res = ((IntConstant) left).Value <=
1149 ((IntConstant) right).Value;
1153 return new BoolConstant (bool_res);