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
63 Constant match, other;
66 if (left is ULongConstant){
71 if (!(right is ULongConstant))
72 right = right.ToULong (loc);
78 left = left.ToULong (loc);
82 if (other is SByteConstant || other is ShortConstant ||
83 other is IntConstant || other is LongConstant){
84 Binary.Error_OperatorAmbiguous
85 (loc, oper, other.Type, match.Type);
91 } else if (left is LongConstant || right is LongConstant){
93 // If either operand is of type long, the other operand is converted
96 if (!(left is LongConstant))
97 left = left.ToLong (loc);
98 else if (!(right is LongConstant))
99 right = right.ToLong (loc);
101 } else if (left is UIntConstant || right is UIntConstant){
103 // If either operand is of type uint, and the other
104 // operand is of type sbyte, short or int, the operands are
105 // converted to type long.
108 if (left is UIntConstant)
114 if (other is UIntConstant)
117 IntConstant ic = other as IntConstant;
121 left = new UIntConstant ((uint) ic.Value);
123 right = new UIntConstant ((uint) ic.Value);
128 if (other is SByteConstant || other is ShortConstant || ic != null){
129 left = left.ToLong (loc);
130 right = right.ToLong (loc);
134 } else if (left is EnumConstant || right is EnumConstant){
136 // If either operand is an enum constant, the other one must
137 // be implicitly convertable to that enum's underlying type.
141 if (left is EnumConstant){
143 match = (EnumConstant) left;
146 match = (EnumConstant) right;
149 bool need_check = (other is EnumConstant) ||
150 ((oper != Binary.Operator.Addition) &&
151 (oper != Binary.Operator.Subtraction));
154 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
155 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
161 if (left is EnumConstant)
162 left = ((EnumConstant) left).Child;
163 if (right is EnumConstant)
164 right = ((EnumConstant) right).Child;
169 // Force conversions to int32
171 if (!(left is IntConstant))
172 left = left.ToInt (loc);
173 if (!(right is IntConstant))
174 right = right.ToInt (loc);
179 static void Error_CompileTimeOverflow (Location loc)
181 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
185 /// Constant expression folder for binary operations.
187 /// Returns null if the expression can not be folded.
189 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
190 Constant left, Constant right, Location loc)
193 Type rt = right.Type;
194 Type result_type = null;
198 // Enumerator folding
200 if (rt == lt && left is EnumConstant)
204 // During an enum evaluation, we need to unwrap enumerations
206 if (ec.InEnumContext){
207 if (left is EnumConstant)
208 left = ((EnumConstant) left).Child;
210 if (right is EnumConstant)
211 right = ((EnumConstant) right).Child;
215 Constant result = null;
217 case Binary.Operator.BitwiseOr:
218 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
219 if (left == null || right == null)
222 if (left is IntConstant){
224 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
226 v = new IntConstant (res);
227 if (result_type == null)
230 return new EnumConstant (v, result_type);
231 } else if (left is UIntConstant){
233 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
235 v = new UIntConstant (res);
236 if (result_type == null)
239 return new EnumConstant (v, result_type);
240 } else if (left is LongConstant){
242 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
244 v = new LongConstant (res);
245 if (result_type == null)
248 return new EnumConstant (v, result_type);
249 } else if (left is ULongConstant){
251 ulong res = ((ULongConstant)left).Value |
252 ((ULongConstant)right).Value;
254 v = new ULongConstant (res);
255 if (result_type == null)
258 return new EnumConstant (v, result_type);
259 } else if (left is UShortConstant){
261 ushort res = (ushort) (((UShortConstant)left).Value |
262 ((UShortConstant)right).Value);
264 v = new UShortConstant (res);
265 if (result_type == null)
268 return new EnumConstant (v, result_type);
269 } else if (left is ShortConstant){
271 short res = (short) (((ShortConstant)left).Value |
272 ((ShortConstant)right).Value);
274 v = new ShortConstant (res);
275 if (result_type == null)
278 return new EnumConstant (v, result_type);
282 case Binary.Operator.BitwiseAnd:
283 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
284 if (left == null || right == null)
287 if (left is IntConstant){
289 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
291 v = new IntConstant (res);
292 if (result_type == null)
295 return new EnumConstant (v, result_type);
296 } else if (left is UIntConstant){
298 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
300 v = new UIntConstant (res);
301 if (result_type == null)
304 return new EnumConstant (v, result_type);
305 } else if (left is LongConstant){
307 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
309 v = new LongConstant (res);
310 if (result_type == null)
313 return new EnumConstant (v, result_type);
314 } else if (left is ULongConstant){
316 ulong res = ((ULongConstant)left).Value &
317 ((ULongConstant)right).Value;
319 v = new ULongConstant (res);
320 if (result_type == null)
323 return new EnumConstant (v, result_type);
324 } else if (left is UShortConstant){
326 ushort res = (ushort) (((UShortConstant)left).Value &
327 ((UShortConstant)right).Value);
329 v = new UShortConstant (res);
330 if (result_type == null)
333 return new EnumConstant (v, result_type);
334 } else if (left is ShortConstant){
336 short res = (short) (((ShortConstant)left).Value &
337 ((ShortConstant)right).Value);
339 v = new ShortConstant (res);
340 if (result_type == null)
343 return new EnumConstant (v, result_type);
347 case Binary.Operator.ExclusiveOr:
348 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
349 if (left == null || right == null)
352 if (left is IntConstant){
354 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
356 v = new IntConstant (res);
357 if (result_type == null)
360 return new EnumConstant (v, result_type);
361 } else if (left is UIntConstant){
363 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
365 v = new UIntConstant (res);
366 if (result_type == null)
369 return new EnumConstant (v, result_type);
370 } else if (left is LongConstant){
372 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
374 v = new LongConstant (res);
375 if (result_type == null)
378 return new EnumConstant (v, result_type);
379 } else if (left is ULongConstant){
381 ulong res = ((ULongConstant)left).Value ^
382 ((ULongConstant)right).Value;
384 v = new ULongConstant (res);
385 if (result_type == null)
388 return new EnumConstant (v, result_type);
389 } else if (left is UShortConstant){
391 ushort res = (ushort) (((UShortConstant)left).Value ^
392 ((UShortConstant)right).Value);
394 v = new UShortConstant (res);
395 if (result_type == null)
398 return new EnumConstant (v, result_type);
399 } else if (left is ShortConstant){
401 short res = (short)(((ShortConstant)left).Value ^
402 ((ShortConstant)right).Value);
404 v = new ShortConstant (res);
405 if (result_type == null)
408 return new EnumConstant (v, result_type);
412 case Binary.Operator.Addition:
413 bool left_is_string = left is StringConstant;
414 bool right_is_string = right is StringConstant;
417 // If both sides are strings, then concatenate, if
418 // one is a string, and the other is not, then defer
419 // to runtime concatenation
422 if (left_is_string || right_is_string){
423 if (left_is_string && right_is_string)
424 return new StringConstant (
425 ((StringConstant) left).Value +
426 ((StringConstant) right).Value);
432 // handle "E operator + (E x, U y)"
433 // handle "E operator + (Y y, E x)"
435 // note that E operator + (E x, E y) is invalid
437 if (left is EnumConstant){
438 if (right is EnumConstant){
441 if (((EnumConstant) left).Child.Type != right.Type)
445 } else if (right is EnumConstant){
446 if (((EnumConstant) right).Child.Type != left.Type)
448 wrap_as = right.Type;
452 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
453 if (left == null || right == null)
457 if (left is DoubleConstant){
460 if (ec.ConstantCheckState)
461 res = checked (((DoubleConstant) left).Value +
462 ((DoubleConstant) right).Value);
464 res = unchecked (((DoubleConstant) left).Value +
465 ((DoubleConstant) right).Value);
467 result = new DoubleConstant (res);
468 } else if (left is FloatConstant){
471 if (ec.ConstantCheckState)
472 res = checked (((FloatConstant) left).Value +
473 ((FloatConstant) right).Value);
475 res = unchecked (((FloatConstant) left).Value +
476 ((FloatConstant) right).Value);
478 result = new FloatConstant (res);
479 } else if (left is ULongConstant){
482 if (ec.ConstantCheckState)
483 res = checked (((ULongConstant) left).Value +
484 ((ULongConstant) right).Value);
486 res = unchecked (((ULongConstant) left).Value +
487 ((ULongConstant) right).Value);
489 result = new ULongConstant (res);
490 } else if (left is LongConstant){
493 if (ec.ConstantCheckState)
494 res = checked (((LongConstant) left).Value +
495 ((LongConstant) right).Value);
497 res = unchecked (((LongConstant) left).Value +
498 ((LongConstant) right).Value);
500 result = new LongConstant (res);
501 } else if (left is UIntConstant){
504 if (ec.ConstantCheckState)
505 res = checked (((UIntConstant) left).Value +
506 ((UIntConstant) right).Value);
508 res = unchecked (((UIntConstant) left).Value +
509 ((UIntConstant) right).Value);
511 result = new UIntConstant (res);
512 } else if (left is IntConstant){
515 if (ec.ConstantCheckState)
516 res = checked (((IntConstant) left).Value +
517 ((IntConstant) right).Value);
519 res = unchecked (((IntConstant) left).Value +
520 ((IntConstant) right).Value);
522 result = new IntConstant (res);
524 throw new Exception ( "Unexepected input: " + left);
526 } catch (OverflowException){
527 Error_CompileTimeOverflow (loc);
531 return new EnumConstant (result, wrap_as);
535 case Binary.Operator.Subtraction:
537 // handle "E operator - (E x, U y)"
538 // handle "E operator - (Y y, E x)"
539 // handle "U operator - (E x, E y)"
542 if (left is EnumConstant){
543 if (right is EnumConstant){
544 if (left.Type == right.Type)
545 wrap_as = TypeManager.EnumToUnderlying (left.Type);
549 if (((EnumConstant) left).Child.Type != right.Type)
553 } else if (right is EnumConstant){
554 if (((EnumConstant) right).Child.Type != left.Type)
556 wrap_as = right.Type;
559 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
560 if (left == null || right == null)
564 if (left is DoubleConstant){
567 if (ec.ConstantCheckState)
568 res = checked (((DoubleConstant) left).Value -
569 ((DoubleConstant) right).Value);
571 res = unchecked (((DoubleConstant) left).Value -
572 ((DoubleConstant) right).Value);
574 result = new DoubleConstant (res);
575 } else if (left is FloatConstant){
578 if (ec.ConstantCheckState)
579 res = checked (((FloatConstant) left).Value -
580 ((FloatConstant) right).Value);
582 res = unchecked (((FloatConstant) left).Value -
583 ((FloatConstant) right).Value);
585 result = new FloatConstant (res);
586 } else if (left is ULongConstant){
589 if (ec.ConstantCheckState)
590 res = checked (((ULongConstant) left).Value -
591 ((ULongConstant) right).Value);
593 res = unchecked (((ULongConstant) left).Value -
594 ((ULongConstant) right).Value);
596 result = new ULongConstant (res);
597 } else if (left is LongConstant){
600 if (ec.ConstantCheckState)
601 res = checked (((LongConstant) left).Value -
602 ((LongConstant) right).Value);
604 res = unchecked (((LongConstant) left).Value -
605 ((LongConstant) right).Value);
607 result = new LongConstant (res);
608 } else if (left is UIntConstant){
611 if (ec.ConstantCheckState)
612 res = checked (((UIntConstant) left).Value -
613 ((UIntConstant) right).Value);
615 res = unchecked (((UIntConstant) left).Value -
616 ((UIntConstant) right).Value);
618 result = new UIntConstant (res);
619 } else if (left is IntConstant){
622 if (ec.ConstantCheckState)
623 res = checked (((IntConstant) left).Value -
624 ((IntConstant) right).Value);
626 res = unchecked (((IntConstant) left).Value -
627 ((IntConstant) right).Value);
629 result = new IntConstant (res);
631 throw new Exception ( "Unexepected input: " + left);
633 } catch (OverflowException){
634 Error_CompileTimeOverflow (loc);
637 return new EnumConstant (result, wrap_as);
641 case Binary.Operator.Multiply:
642 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
643 if (left == null || right == null)
647 if (left is DoubleConstant){
650 if (ec.ConstantCheckState)
651 res = checked (((DoubleConstant) left).Value *
652 ((DoubleConstant) right).Value);
654 res = unchecked (((DoubleConstant) left).Value *
655 ((DoubleConstant) right).Value);
657 return new DoubleConstant (res);
658 } else if (left is FloatConstant){
661 if (ec.ConstantCheckState)
662 res = checked (((FloatConstant) left).Value *
663 ((FloatConstant) right).Value);
665 res = unchecked (((FloatConstant) left).Value *
666 ((FloatConstant) right).Value);
668 return new FloatConstant (res);
669 } else if (left is ULongConstant){
672 if (ec.ConstantCheckState)
673 res = checked (((ULongConstant) left).Value *
674 ((ULongConstant) right).Value);
676 res = unchecked (((ULongConstant) left).Value *
677 ((ULongConstant) right).Value);
679 return new ULongConstant (res);
680 } else if (left is LongConstant){
683 if (ec.ConstantCheckState)
684 res = checked (((LongConstant) left).Value *
685 ((LongConstant) right).Value);
687 res = unchecked (((LongConstant) left).Value *
688 ((LongConstant) right).Value);
690 return new LongConstant (res);
691 } else if (left is UIntConstant){
694 if (ec.ConstantCheckState)
695 res = checked (((UIntConstant) left).Value *
696 ((UIntConstant) right).Value);
698 res = unchecked (((UIntConstant) left).Value *
699 ((UIntConstant) right).Value);
701 return new UIntConstant (res);
702 } else if (left is IntConstant){
705 if (ec.ConstantCheckState)
706 res = checked (((IntConstant) left).Value *
707 ((IntConstant) right).Value);
709 res = unchecked (((IntConstant) left).Value *
710 ((IntConstant) right).Value);
712 return new IntConstant (res);
714 throw new Exception ( "Unexepected input: " + left);
716 } catch (OverflowException){
717 Error_CompileTimeOverflow (loc);
721 case Binary.Operator.Division:
722 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
723 if (left == null || right == null)
727 if (left is DoubleConstant){
730 if (ec.ConstantCheckState)
731 res = checked (((DoubleConstant) left).Value /
732 ((DoubleConstant) right).Value);
734 res = unchecked (((DoubleConstant) left).Value /
735 ((DoubleConstant) right).Value);
737 return new DoubleConstant (res);
738 } else if (left is FloatConstant){
741 if (ec.ConstantCheckState)
742 res = checked (((FloatConstant) left).Value /
743 ((FloatConstant) right).Value);
745 res = unchecked (((FloatConstant) left).Value /
746 ((FloatConstant) right).Value);
748 return new FloatConstant (res);
749 } else if (left is ULongConstant){
752 if (ec.ConstantCheckState)
753 res = checked (((ULongConstant) left).Value /
754 ((ULongConstant) right).Value);
756 res = unchecked (((ULongConstant) left).Value /
757 ((ULongConstant) right).Value);
759 return new ULongConstant (res);
760 } else if (left is LongConstant){
763 if (ec.ConstantCheckState)
764 res = checked (((LongConstant) left).Value /
765 ((LongConstant) right).Value);
767 res = unchecked (((LongConstant) left).Value /
768 ((LongConstant) right).Value);
770 return new LongConstant (res);
771 } else if (left is UIntConstant){
774 if (ec.ConstantCheckState)
775 res = checked (((UIntConstant) left).Value /
776 ((UIntConstant) right).Value);
778 res = unchecked (((UIntConstant) left).Value /
779 ((UIntConstant) right).Value);
781 return new UIntConstant (res);
782 } else if (left is IntConstant){
785 if (ec.ConstantCheckState)
786 res = checked (((IntConstant) left).Value /
787 ((IntConstant) right).Value);
789 res = unchecked (((IntConstant) left).Value /
790 ((IntConstant) right).Value);
792 return new IntConstant (res);
794 throw new Exception ( "Unexepected input: " + left);
796 } catch (OverflowException){
797 Error_CompileTimeOverflow (loc);
799 } catch (DivideByZeroException) {
800 Report.Error (020, loc, "Division by constant zero");
805 case Binary.Operator.Modulus:
806 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
807 if (left == null || right == null)
811 if (left is DoubleConstant){
814 if (ec.ConstantCheckState)
815 res = checked (((DoubleConstant) left).Value %
816 ((DoubleConstant) right).Value);
818 res = unchecked (((DoubleConstant) left).Value %
819 ((DoubleConstant) right).Value);
821 return new DoubleConstant (res);
822 } else if (left is FloatConstant){
825 if (ec.ConstantCheckState)
826 res = checked (((FloatConstant) left).Value %
827 ((FloatConstant) right).Value);
829 res = unchecked (((FloatConstant) left).Value %
830 ((FloatConstant) right).Value);
832 return new FloatConstant (res);
833 } else if (left is ULongConstant){
836 if (ec.ConstantCheckState)
837 res = checked (((ULongConstant) left).Value %
838 ((ULongConstant) right).Value);
840 res = unchecked (((ULongConstant) left).Value %
841 ((ULongConstant) right).Value);
843 return new ULongConstant (res);
844 } else if (left is LongConstant){
847 if (ec.ConstantCheckState)
848 res = checked (((LongConstant) left).Value %
849 ((LongConstant) right).Value);
851 res = unchecked (((LongConstant) left).Value %
852 ((LongConstant) right).Value);
854 return new LongConstant (res);
855 } else if (left is UIntConstant){
858 if (ec.ConstantCheckState)
859 res = checked (((UIntConstant) left).Value %
860 ((UIntConstant) right).Value);
862 res = unchecked (((UIntConstant) left).Value %
863 ((UIntConstant) right).Value);
865 return new UIntConstant (res);
866 } else if (left is IntConstant){
869 if (ec.ConstantCheckState)
870 res = checked (((IntConstant) left).Value %
871 ((IntConstant) right).Value);
873 res = unchecked (((IntConstant) left).Value %
874 ((IntConstant) right).Value);
876 return new IntConstant (res);
878 throw new Exception ( "Unexepected input: " + left);
880 } catch (DivideByZeroException){
881 Report.Error (020, loc, "Division by constant zero");
882 } catch (OverflowException){
883 Error_CompileTimeOverflow (loc);
888 // There is no overflow checking on left shift
890 case Binary.Operator.LeftShift:
891 IntConstant ic = right.ToInt (loc);
893 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
896 int lshift_val = ic.Value;
899 if ((lic = left.ConvertToInt ()) != null)
900 return new IntConstant (lic.Value << lshift_val);
903 if ((luic = left.ConvertToUInt ()) != null)
904 return new UIntConstant (luic.Value << lshift_val);
907 if ((llc = left.ConvertToLong ()) != null)
908 return new LongConstant (llc.Value << lshift_val);
911 if ((lulc = left.ConvertToULong ()) != null)
912 return new ULongConstant (lulc.Value << lshift_val);
914 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
918 // There is no overflow checking on right shift
920 case Binary.Operator.RightShift:
921 IntConstant sic = right.ToInt (loc);
923 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
926 int rshift_val = sic.Value;
929 if ((ric = left.ConvertToInt ()) != null)
930 return new IntConstant (ric.Value >> rshift_val);
933 if ((ruic = left.ConvertToUInt ()) != null)
934 return new UIntConstant (ruic.Value >> rshift_val);
937 if ((rlc = left.ConvertToLong ()) != null)
938 return new LongConstant (rlc.Value >> rshift_val);
941 if ((rulc = left.ConvertToULong ()) != null)
942 return new ULongConstant (rulc.Value >> rshift_val);
944 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
947 case Binary.Operator.LogicalAnd:
948 if (left is BoolConstant && right is BoolConstant){
949 return new BoolConstant (
950 ((BoolConstant) left).Value &&
951 ((BoolConstant) right).Value);
955 case Binary.Operator.LogicalOr:
956 if (left is BoolConstant && right is BoolConstant){
957 return new BoolConstant (
958 ((BoolConstant) left).Value ||
959 ((BoolConstant) right).Value);
963 case Binary.Operator.Equality:
964 if (left is BoolConstant && right is BoolConstant){
965 return new BoolConstant (
966 ((BoolConstant) left).Value ==
967 ((BoolConstant) right).Value);
970 if (left is NullLiteral){
971 if (right is NullLiteral)
972 return new BoolConstant (true);
973 else if (right is StringConstant)
974 return new BoolConstant (
975 ((StringConstant) right).Value == null);
976 } else if (right is NullLiteral){
977 if (left is NullLiteral)
978 return new BoolConstant (true);
979 else if (left is StringConstant)
980 return new BoolConstant (
981 ((StringConstant) left).Value == null);
983 if (left is StringConstant && right is StringConstant){
984 return new BoolConstant (
985 ((StringConstant) left).Value ==
986 ((StringConstant) right).Value);
990 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
991 if (left == null || right == null)
995 if (left is DoubleConstant)
996 bool_res = ((DoubleConstant) left).Value ==
997 ((DoubleConstant) right).Value;
998 else if (left is FloatConstant)
999 bool_res = ((FloatConstant) left).Value ==
1000 ((FloatConstant) right).Value;
1001 else if (left is ULongConstant)
1002 bool_res = ((ULongConstant) left).Value ==
1003 ((ULongConstant) right).Value;
1004 else if (left is LongConstant)
1005 bool_res = ((LongConstant) left).Value ==
1006 ((LongConstant) right).Value;
1007 else if (left is UIntConstant)
1008 bool_res = ((UIntConstant) left).Value ==
1009 ((UIntConstant) right).Value;
1010 else if (left is IntConstant)
1011 bool_res = ((IntConstant) left).Value ==
1012 ((IntConstant) right).Value;
1016 return new BoolConstant (bool_res);
1018 case Binary.Operator.Inequality:
1019 if (left is BoolConstant && right is BoolConstant){
1020 return new BoolConstant (
1021 ((BoolConstant) left).Value !=
1022 ((BoolConstant) right).Value);
1024 if (left is NullLiteral){
1025 if (right is NullLiteral)
1026 return new BoolConstant (false);
1027 else if (right is StringConstant)
1028 return new BoolConstant (
1029 ((StringConstant) right).Value != null);
1030 } else if (right is NullLiteral){
1031 if (left is NullLiteral)
1032 return new BoolConstant (false);
1033 else if (left is StringConstant)
1034 return new BoolConstant (
1035 ((StringConstant) left).Value != null);
1037 if (left is StringConstant && right is StringConstant){
1038 return new BoolConstant (
1039 ((StringConstant) left).Value !=
1040 ((StringConstant) right).Value);
1043 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1044 if (left == null || right == null)
1048 if (left is DoubleConstant)
1049 bool_res = ((DoubleConstant) left).Value !=
1050 ((DoubleConstant) right).Value;
1051 else if (left is FloatConstant)
1052 bool_res = ((FloatConstant) left).Value !=
1053 ((FloatConstant) right).Value;
1054 else if (left is ULongConstant)
1055 bool_res = ((ULongConstant) left).Value !=
1056 ((ULongConstant) right).Value;
1057 else if (left is LongConstant)
1058 bool_res = ((LongConstant) left).Value !=
1059 ((LongConstant) right).Value;
1060 else if (left is UIntConstant)
1061 bool_res = ((UIntConstant) left).Value !=
1062 ((UIntConstant) right).Value;
1063 else if (left is IntConstant)
1064 bool_res = ((IntConstant) left).Value !=
1065 ((IntConstant) right).Value;
1069 return new BoolConstant (bool_res);
1071 case Binary.Operator.LessThan:
1072 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1073 if (left == null || right == null)
1077 if (left is DoubleConstant)
1078 bool_res = ((DoubleConstant) left).Value <
1079 ((DoubleConstant) right).Value;
1080 else if (left is FloatConstant)
1081 bool_res = ((FloatConstant) left).Value <
1082 ((FloatConstant) right).Value;
1083 else if (left is ULongConstant)
1084 bool_res = ((ULongConstant) left).Value <
1085 ((ULongConstant) right).Value;
1086 else if (left is LongConstant)
1087 bool_res = ((LongConstant) left).Value <
1088 ((LongConstant) right).Value;
1089 else if (left is UIntConstant)
1090 bool_res = ((UIntConstant) left).Value <
1091 ((UIntConstant) right).Value;
1092 else if (left is IntConstant)
1093 bool_res = ((IntConstant) left).Value <
1094 ((IntConstant) right).Value;
1098 return new BoolConstant (bool_res);
1100 case Binary.Operator.GreaterThan:
1101 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1102 if (left == null || right == null)
1106 if (left is DoubleConstant)
1107 bool_res = ((DoubleConstant) left).Value >
1108 ((DoubleConstant) right).Value;
1109 else if (left is FloatConstant)
1110 bool_res = ((FloatConstant) left).Value >
1111 ((FloatConstant) right).Value;
1112 else if (left is ULongConstant)
1113 bool_res = ((ULongConstant) left).Value >
1114 ((ULongConstant) right).Value;
1115 else if (left is LongConstant)
1116 bool_res = ((LongConstant) left).Value >
1117 ((LongConstant) right).Value;
1118 else if (left is UIntConstant)
1119 bool_res = ((UIntConstant) left).Value >
1120 ((UIntConstant) right).Value;
1121 else if (left is IntConstant)
1122 bool_res = ((IntConstant) left).Value >
1123 ((IntConstant) right).Value;
1127 return new BoolConstant (bool_res);
1129 case Binary.Operator.GreaterThanOrEqual:
1130 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1131 if (left == null || right == null)
1135 if (left is DoubleConstant)
1136 bool_res = ((DoubleConstant) left).Value >=
1137 ((DoubleConstant) right).Value;
1138 else if (left is FloatConstant)
1139 bool_res = ((FloatConstant) left).Value >=
1140 ((FloatConstant) right).Value;
1141 else if (left is ULongConstant)
1142 bool_res = ((ULongConstant) left).Value >=
1143 ((ULongConstant) right).Value;
1144 else if (left is LongConstant)
1145 bool_res = ((LongConstant) left).Value >=
1146 ((LongConstant) right).Value;
1147 else if (left is UIntConstant)
1148 bool_res = ((UIntConstant) left).Value >=
1149 ((UIntConstant) right).Value;
1150 else if (left is IntConstant)
1151 bool_res = ((IntConstant) left).Value >=
1152 ((IntConstant) right).Value;
1156 return new BoolConstant (bool_res);
1158 case Binary.Operator.LessThanOrEqual:
1159 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1160 if (left == null || right == null)
1164 if (left is DoubleConstant)
1165 bool_res = ((DoubleConstant) left).Value <=
1166 ((DoubleConstant) right).Value;
1167 else if (left is FloatConstant)
1168 bool_res = ((FloatConstant) left).Value <=
1169 ((FloatConstant) right).Value;
1170 else if (left is ULongConstant)
1171 bool_res = ((ULongConstant) left).Value <=
1172 ((ULongConstant) right).Value;
1173 else if (left is LongConstant)
1174 bool_res = ((LongConstant) left).Value <=
1175 ((LongConstant) right).Value;
1176 else if (left is UIntConstant)
1177 bool_res = ((UIntConstant) left).Value <=
1178 ((UIntConstant) right).Value;
1179 else if (left is IntConstant)
1180 bool_res = ((IntConstant) left).Value <=
1181 ((IntConstant) right).Value;
1185 return new BoolConstant (bool_res);