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);
132 left = left.ToUInt (loc);
133 right = left.ToUInt (loc);
137 } else if (left is DecimalConstant || right is DecimalConstant) {
138 if (!(left is DecimalConstant))
139 left = left.ToDecimal (loc);
140 else if (!(right is DecimalConstant))
141 right = right.ToDecimal (loc);
143 } else if (left is EnumConstant || right is EnumConstant){
145 // If either operand is an enum constant, the other one must
146 // be implicitly convertable to that enum's underlying type.
150 if (left is EnumConstant){
152 match = (EnumConstant) left;
155 match = (EnumConstant) right;
158 bool need_check = (other is EnumConstant) ||
159 ((oper != Binary.Operator.Addition) &&
160 (oper != Binary.Operator.Subtraction));
163 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
164 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
170 if (left is EnumConstant)
171 left = ((EnumConstant) left).Child;
172 if (right is EnumConstant)
173 right = ((EnumConstant) right).Child;
178 // Force conversions to int32
180 if (!(left is IntConstant))
181 left = left.ToInt (loc);
182 if (!(right is IntConstant))
183 right = right.ToInt (loc);
188 static void Error_CompileTimeOverflow (Location loc)
190 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
194 /// Constant expression folder for binary operations.
196 /// Returns null if the expression can not be folded.
198 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
199 Constant left, Constant right, Location loc)
202 Type rt = right.Type;
203 Type result_type = null;
207 // Enumerator folding
209 if (rt == lt && left is EnumConstant)
213 // During an enum evaluation, we need to unwrap enumerations
215 if (ec.InEnumContext){
216 if (left is EnumConstant)
217 left = ((EnumConstant) left).Child;
219 if (right is EnumConstant)
220 right = ((EnumConstant) right).Child;
224 Constant result = null;
226 case Binary.Operator.BitwiseOr:
227 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
228 if (left == null || right == null)
231 if (left is IntConstant){
233 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
235 v = new IntConstant (res);
236 if (result_type == null)
239 return new EnumConstant (v, result_type);
240 } else if (left is UIntConstant){
242 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
244 v = new UIntConstant (res);
245 if (result_type == null)
248 return new EnumConstant (v, result_type);
249 } else if (left is LongConstant){
251 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
253 v = new LongConstant (res);
254 if (result_type == null)
257 return new EnumConstant (v, result_type);
258 } else if (left is ULongConstant){
260 ulong res = ((ULongConstant)left).Value |
261 ((ULongConstant)right).Value;
263 v = new ULongConstant (res);
264 if (result_type == null)
267 return new EnumConstant (v, result_type);
268 } else if (left is UShortConstant){
270 ushort res = (ushort) (((UShortConstant)left).Value |
271 ((UShortConstant)right).Value);
273 v = new UShortConstant (res);
274 if (result_type == null)
277 return new EnumConstant (v, result_type);
278 } else if (left is ShortConstant){
280 short res = (short) (((ShortConstant)left).Value |
281 ((ShortConstant)right).Value);
283 v = new ShortConstant (res);
284 if (result_type == null)
287 return new EnumConstant (v, result_type);
291 case Binary.Operator.BitwiseAnd:
292 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
293 if (left == null || right == null)
296 if (left is IntConstant){
298 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
300 v = new IntConstant (res);
301 if (result_type == null)
304 return new EnumConstant (v, result_type);
305 } else if (left is UIntConstant){
307 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
309 v = new UIntConstant (res);
310 if (result_type == null)
313 return new EnumConstant (v, result_type);
314 } else if (left is LongConstant){
316 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
318 v = new LongConstant (res);
319 if (result_type == null)
322 return new EnumConstant (v, result_type);
323 } else if (left is ULongConstant){
325 ulong res = ((ULongConstant)left).Value &
326 ((ULongConstant)right).Value;
328 v = new ULongConstant (res);
329 if (result_type == null)
332 return new EnumConstant (v, result_type);
333 } else if (left is UShortConstant){
335 ushort res = (ushort) (((UShortConstant)left).Value &
336 ((UShortConstant)right).Value);
338 v = new UShortConstant (res);
339 if (result_type == null)
342 return new EnumConstant (v, result_type);
343 } else if (left is ShortConstant){
345 short res = (short) (((ShortConstant)left).Value &
346 ((ShortConstant)right).Value);
348 v = new ShortConstant (res);
349 if (result_type == null)
352 return new EnumConstant (v, result_type);
356 case Binary.Operator.ExclusiveOr:
357 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
358 if (left == null || right == null)
361 if (left is IntConstant){
363 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
365 v = new IntConstant (res);
366 if (result_type == null)
369 return new EnumConstant (v, result_type);
370 } else if (left is UIntConstant){
372 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
374 v = new UIntConstant (res);
375 if (result_type == null)
378 return new EnumConstant (v, result_type);
379 } else if (left is LongConstant){
381 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
383 v = new LongConstant (res);
384 if (result_type == null)
387 return new EnumConstant (v, result_type);
388 } else if (left is ULongConstant){
390 ulong res = ((ULongConstant)left).Value ^
391 ((ULongConstant)right).Value;
393 v = new ULongConstant (res);
394 if (result_type == null)
397 return new EnumConstant (v, result_type);
398 } else if (left is UShortConstant){
400 ushort res = (ushort) (((UShortConstant)left).Value ^
401 ((UShortConstant)right).Value);
403 v = new UShortConstant (res);
404 if (result_type == null)
407 return new EnumConstant (v, result_type);
408 } else if (left is ShortConstant){
410 short res = (short)(((ShortConstant)left).Value ^
411 ((ShortConstant)right).Value);
413 v = new ShortConstant (res);
414 if (result_type == null)
417 return new EnumConstant (v, result_type);
421 case Binary.Operator.Addition:
422 bool left_is_string = left is StringConstant;
423 bool right_is_string = right is StringConstant;
426 // If both sides are strings, then concatenate, if
427 // one is a string, and the other is not, then defer
428 // to runtime concatenation
431 if (left_is_string || right_is_string){
432 if (left_is_string && right_is_string)
433 return new StringConstant (
434 ((StringConstant) left).Value +
435 ((StringConstant) right).Value);
441 // handle "E operator + (E x, U y)"
442 // handle "E operator + (Y y, E x)"
444 // note that E operator + (E x, E y) is invalid
446 if (left is EnumConstant){
447 if (right is EnumConstant){
450 if (((EnumConstant) left).Child.Type != right.Type)
454 } else if (right is EnumConstant){
455 if (((EnumConstant) right).Child.Type != left.Type)
457 wrap_as = right.Type;
461 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
462 if (left == null || right == null)
466 if (left is DoubleConstant){
469 if (ec.ConstantCheckState)
470 res = checked (((DoubleConstant) left).Value +
471 ((DoubleConstant) right).Value);
473 res = unchecked (((DoubleConstant) left).Value +
474 ((DoubleConstant) right).Value);
476 result = new DoubleConstant (res);
477 } else if (left is FloatConstant){
480 if (ec.ConstantCheckState)
481 res = checked (((FloatConstant) left).Value +
482 ((FloatConstant) right).Value);
484 res = unchecked (((FloatConstant) left).Value +
485 ((FloatConstant) right).Value);
487 result = new FloatConstant (res);
488 } else if (left is ULongConstant){
491 if (ec.ConstantCheckState)
492 res = checked (((ULongConstant) left).Value +
493 ((ULongConstant) right).Value);
495 res = unchecked (((ULongConstant) left).Value +
496 ((ULongConstant) right).Value);
498 result = new ULongConstant (res);
499 } else if (left is LongConstant){
502 if (ec.ConstantCheckState)
503 res = checked (((LongConstant) left).Value +
504 ((LongConstant) right).Value);
506 res = unchecked (((LongConstant) left).Value +
507 ((LongConstant) right).Value);
509 result = new LongConstant (res);
510 } else if (left is UIntConstant){
513 if (ec.ConstantCheckState)
514 res = checked (((UIntConstant) left).Value +
515 ((UIntConstant) right).Value);
517 res = unchecked (((UIntConstant) left).Value +
518 ((UIntConstant) right).Value);
520 result = new UIntConstant (res);
521 } else if (left is IntConstant){
524 if (ec.ConstantCheckState)
525 res = checked (((IntConstant) left).Value +
526 ((IntConstant) right).Value);
528 res = unchecked (((IntConstant) left).Value +
529 ((IntConstant) right).Value);
531 result = new IntConstant (res);
533 throw new Exception ( "Unexepected addition input: " + left);
535 } catch (OverflowException){
536 Error_CompileTimeOverflow (loc);
540 return new EnumConstant (result, wrap_as);
544 case Binary.Operator.Subtraction:
546 // handle "E operator - (E x, U y)"
547 // handle "E operator - (Y y, E x)"
548 // handle "U operator - (E x, E y)"
551 if (left is EnumConstant){
552 if (right is EnumConstant){
553 if (left.Type == right.Type)
554 wrap_as = TypeManager.EnumToUnderlying (left.Type);
558 if (((EnumConstant) left).Child.Type != right.Type)
562 } else if (right is EnumConstant){
563 if (((EnumConstant) right).Child.Type != left.Type)
565 wrap_as = right.Type;
568 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
569 if (left == null || right == null)
573 if (left is DoubleConstant){
576 if (ec.ConstantCheckState)
577 res = checked (((DoubleConstant) left).Value -
578 ((DoubleConstant) right).Value);
580 res = unchecked (((DoubleConstant) left).Value -
581 ((DoubleConstant) right).Value);
583 result = new DoubleConstant (res);
584 } else if (left is FloatConstant){
587 if (ec.ConstantCheckState)
588 res = checked (((FloatConstant) left).Value -
589 ((FloatConstant) right).Value);
591 res = unchecked (((FloatConstant) left).Value -
592 ((FloatConstant) right).Value);
594 result = new FloatConstant (res);
595 } else if (left is ULongConstant){
598 if (ec.ConstantCheckState)
599 res = checked (((ULongConstant) left).Value -
600 ((ULongConstant) right).Value);
602 res = unchecked (((ULongConstant) left).Value -
603 ((ULongConstant) right).Value);
605 result = new ULongConstant (res);
606 } else if (left is LongConstant){
609 if (ec.ConstantCheckState)
610 res = checked (((LongConstant) left).Value -
611 ((LongConstant) right).Value);
613 res = unchecked (((LongConstant) left).Value -
614 ((LongConstant) right).Value);
616 result = new LongConstant (res);
617 } else if (left is UIntConstant){
620 if (ec.ConstantCheckState)
621 res = checked (((UIntConstant) left).Value -
622 ((UIntConstant) right).Value);
624 res = unchecked (((UIntConstant) left).Value -
625 ((UIntConstant) right).Value);
627 result = new UIntConstant (res);
628 } else if (left is IntConstant){
631 if (ec.ConstantCheckState)
632 res = checked (((IntConstant) left).Value -
633 ((IntConstant) right).Value);
635 res = unchecked (((IntConstant) left).Value -
636 ((IntConstant) right).Value);
638 result = new IntConstant (res);
640 throw new Exception ( "Unexepected subtraction input: " + left);
642 } catch (OverflowException){
643 Error_CompileTimeOverflow (loc);
646 return new EnumConstant (result, wrap_as);
650 case Binary.Operator.Multiply:
651 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
652 if (left == null || right == null)
656 if (left is DoubleConstant){
659 if (ec.ConstantCheckState)
660 res = checked (((DoubleConstant) left).Value *
661 ((DoubleConstant) right).Value);
663 res = unchecked (((DoubleConstant) left).Value *
664 ((DoubleConstant) right).Value);
666 return new DoubleConstant (res);
667 } else if (left is FloatConstant){
670 if (ec.ConstantCheckState)
671 res = checked (((FloatConstant) left).Value *
672 ((FloatConstant) right).Value);
674 res = unchecked (((FloatConstant) left).Value *
675 ((FloatConstant) right).Value);
677 return new FloatConstant (res);
678 } else if (left is ULongConstant){
681 if (ec.ConstantCheckState)
682 res = checked (((ULongConstant) left).Value *
683 ((ULongConstant) right).Value);
685 res = unchecked (((ULongConstant) left).Value *
686 ((ULongConstant) right).Value);
688 return new ULongConstant (res);
689 } else if (left is LongConstant){
692 if (ec.ConstantCheckState)
693 res = checked (((LongConstant) left).Value *
694 ((LongConstant) right).Value);
696 res = unchecked (((LongConstant) left).Value *
697 ((LongConstant) right).Value);
699 return new LongConstant (res);
700 } else if (left is UIntConstant){
703 if (ec.ConstantCheckState)
704 res = checked (((UIntConstant) left).Value *
705 ((UIntConstant) right).Value);
707 res = unchecked (((UIntConstant) left).Value *
708 ((UIntConstant) right).Value);
710 return new UIntConstant (res);
711 } else if (left is IntConstant){
714 if (ec.ConstantCheckState)
715 res = checked (((IntConstant) left).Value *
716 ((IntConstant) right).Value);
718 res = unchecked (((IntConstant) left).Value *
719 ((IntConstant) right).Value);
721 return new IntConstant (res);
722 } else if (left is DecimalConstant) {
725 if (ec.ConstantCheckState)
726 res = checked (((DecimalConstant) left).Value *
727 ((DecimalConstant) right).Value);
729 res = unchecked (((DecimalConstant) left).Value *
730 ((DecimalConstant) right).Value);
732 return new DecimalConstant (res);
734 throw new Exception ( "Unexepected multiply input: " + left);
736 } catch (OverflowException){
737 Error_CompileTimeOverflow (loc);
741 case Binary.Operator.Division:
742 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
743 if (left == null || right == null)
747 if (left is DoubleConstant){
750 if (ec.ConstantCheckState)
751 res = checked (((DoubleConstant) left).Value /
752 ((DoubleConstant) right).Value);
754 res = unchecked (((DoubleConstant) left).Value /
755 ((DoubleConstant) right).Value);
757 return new DoubleConstant (res);
758 } else if (left is FloatConstant){
761 if (ec.ConstantCheckState)
762 res = checked (((FloatConstant) left).Value /
763 ((FloatConstant) right).Value);
765 res = unchecked (((FloatConstant) left).Value /
766 ((FloatConstant) right).Value);
768 return new FloatConstant (res);
769 } else if (left is ULongConstant){
772 if (ec.ConstantCheckState)
773 res = checked (((ULongConstant) left).Value /
774 ((ULongConstant) right).Value);
776 res = unchecked (((ULongConstant) left).Value /
777 ((ULongConstant) right).Value);
779 return new ULongConstant (res);
780 } else if (left is LongConstant){
783 if (ec.ConstantCheckState)
784 res = checked (((LongConstant) left).Value /
785 ((LongConstant) right).Value);
787 res = unchecked (((LongConstant) left).Value /
788 ((LongConstant) right).Value);
790 return new LongConstant (res);
791 } else if (left is UIntConstant){
794 if (ec.ConstantCheckState)
795 res = checked (((UIntConstant) left).Value /
796 ((UIntConstant) right).Value);
798 res = unchecked (((UIntConstant) left).Value /
799 ((UIntConstant) right).Value);
801 return new UIntConstant (res);
802 } else if (left is IntConstant){
805 if (ec.ConstantCheckState)
806 res = checked (((IntConstant) left).Value /
807 ((IntConstant) right).Value);
809 res = unchecked (((IntConstant) left).Value /
810 ((IntConstant) right).Value);
812 return new IntConstant (res);
813 } else if (left is DecimalConstant) {
816 if (ec.ConstantCheckState)
817 res = checked (((DecimalConstant) left).Value /
818 ((DecimalConstant) right).Value);
820 res = unchecked (((DecimalConstant) left).Value /
821 ((DecimalConstant) right).Value);
823 return new DecimalConstant (res);
825 throw new Exception ( "Unexepected division input: " + left);
827 } catch (OverflowException){
828 Error_CompileTimeOverflow (loc);
830 } catch (DivideByZeroException) {
831 Report.Error (020, loc, "Division by constant zero");
836 case Binary.Operator.Modulus:
837 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
838 if (left == null || right == null)
842 if (left is DoubleConstant){
845 if (ec.ConstantCheckState)
846 res = checked (((DoubleConstant) left).Value %
847 ((DoubleConstant) right).Value);
849 res = unchecked (((DoubleConstant) left).Value %
850 ((DoubleConstant) right).Value);
852 return new DoubleConstant (res);
853 } else if (left is FloatConstant){
856 if (ec.ConstantCheckState)
857 res = checked (((FloatConstant) left).Value %
858 ((FloatConstant) right).Value);
860 res = unchecked (((FloatConstant) left).Value %
861 ((FloatConstant) right).Value);
863 return new FloatConstant (res);
864 } else if (left is ULongConstant){
867 if (ec.ConstantCheckState)
868 res = checked (((ULongConstant) left).Value %
869 ((ULongConstant) right).Value);
871 res = unchecked (((ULongConstant) left).Value %
872 ((ULongConstant) right).Value);
874 return new ULongConstant (res);
875 } else if (left is LongConstant){
878 if (ec.ConstantCheckState)
879 res = checked (((LongConstant) left).Value %
880 ((LongConstant) right).Value);
882 res = unchecked (((LongConstant) left).Value %
883 ((LongConstant) right).Value);
885 return new LongConstant (res);
886 } else if (left is UIntConstant){
889 if (ec.ConstantCheckState)
890 res = checked (((UIntConstant) left).Value %
891 ((UIntConstant) right).Value);
893 res = unchecked (((UIntConstant) left).Value %
894 ((UIntConstant) right).Value);
896 return new UIntConstant (res);
897 } else if (left is IntConstant){
900 if (ec.ConstantCheckState)
901 res = checked (((IntConstant) left).Value %
902 ((IntConstant) right).Value);
904 res = unchecked (((IntConstant) left).Value %
905 ((IntConstant) right).Value);
907 return new IntConstant (res);
909 throw new Exception ( "Unexepected modulus input: " + left);
911 } catch (DivideByZeroException){
912 Report.Error (020, loc, "Division by constant zero");
913 } catch (OverflowException){
914 Error_CompileTimeOverflow (loc);
919 // There is no overflow checking on left shift
921 case Binary.Operator.LeftShift:
922 IntConstant ic = right.ToInt (loc);
924 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
927 int lshift_val = ic.Value;
930 if ((lic = left.ConvertToInt ()) != null)
931 return new IntConstant (lic.Value << lshift_val);
934 if ((luic = left.ConvertToUInt ()) != null)
935 return new UIntConstant (luic.Value << lshift_val);
938 if ((llc = left.ConvertToLong ()) != null)
939 return new LongConstant (llc.Value << lshift_val);
942 if ((lulc = left.ConvertToULong ()) != null)
943 return new ULongConstant (lulc.Value << lshift_val);
945 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
949 // There is no overflow checking on right shift
951 case Binary.Operator.RightShift:
952 IntConstant sic = right.ToInt (loc);
954 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
957 int rshift_val = sic.Value;
960 if ((ric = left.ConvertToInt ()) != null)
961 return new IntConstant (ric.Value >> rshift_val);
964 if ((ruic = left.ConvertToUInt ()) != null)
965 return new UIntConstant (ruic.Value >> rshift_val);
968 if ((rlc = left.ConvertToLong ()) != null)
969 return new LongConstant (rlc.Value >> rshift_val);
972 if ((rulc = left.ConvertToULong ()) != null)
973 return new ULongConstant (rulc.Value >> rshift_val);
975 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
978 case Binary.Operator.LogicalAnd:
979 if (left is BoolConstant && right is BoolConstant){
980 return new BoolConstant (
981 ((BoolConstant) left).Value &&
982 ((BoolConstant) right).Value);
986 case Binary.Operator.LogicalOr:
987 if (left is BoolConstant && right is BoolConstant){
988 return new BoolConstant (
989 ((BoolConstant) left).Value ||
990 ((BoolConstant) right).Value);
994 case Binary.Operator.Equality:
995 if (left is BoolConstant && right is BoolConstant){
996 return new BoolConstant (
997 ((BoolConstant) left).Value ==
998 ((BoolConstant) right).Value);
1001 if (left is NullLiteral){
1002 if (right is NullLiteral)
1003 return new BoolConstant (true);
1004 else if (right is StringConstant)
1005 return new BoolConstant (
1006 ((StringConstant) right).Value == null);
1007 } else if (right is NullLiteral){
1008 if (left is NullLiteral)
1009 return new BoolConstant (true);
1010 else if (left is StringConstant)
1011 return new BoolConstant (
1012 ((StringConstant) left).Value == null);
1014 if (left is StringConstant && right is StringConstant){
1015 return new BoolConstant (
1016 ((StringConstant) left).Value ==
1017 ((StringConstant) right).Value);
1021 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1022 if (left == null || right == null)
1026 if (left is DoubleConstant)
1027 bool_res = ((DoubleConstant) left).Value ==
1028 ((DoubleConstant) right).Value;
1029 else if (left is FloatConstant)
1030 bool_res = ((FloatConstant) left).Value ==
1031 ((FloatConstant) right).Value;
1032 else if (left is ULongConstant)
1033 bool_res = ((ULongConstant) left).Value ==
1034 ((ULongConstant) right).Value;
1035 else if (left is LongConstant)
1036 bool_res = ((LongConstant) left).Value ==
1037 ((LongConstant) right).Value;
1038 else if (left is UIntConstant)
1039 bool_res = ((UIntConstant) left).Value ==
1040 ((UIntConstant) right).Value;
1041 else if (left is IntConstant)
1042 bool_res = ((IntConstant) left).Value ==
1043 ((IntConstant) right).Value;
1047 return new BoolConstant (bool_res);
1049 case Binary.Operator.Inequality:
1050 if (left is BoolConstant && right is BoolConstant){
1051 return new BoolConstant (
1052 ((BoolConstant) left).Value !=
1053 ((BoolConstant) right).Value);
1055 if (left is NullLiteral){
1056 if (right is NullLiteral)
1057 return new BoolConstant (false);
1058 else if (right is StringConstant)
1059 return new BoolConstant (
1060 ((StringConstant) right).Value != null);
1061 } else if (right is NullLiteral){
1062 if (left is NullLiteral)
1063 return new BoolConstant (false);
1064 else if (left is StringConstant)
1065 return new BoolConstant (
1066 ((StringConstant) left).Value != null);
1068 if (left is StringConstant && right is StringConstant){
1069 return new BoolConstant (
1070 ((StringConstant) left).Value !=
1071 ((StringConstant) right).Value);
1074 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1075 if (left == null || right == null)
1079 if (left is DoubleConstant)
1080 bool_res = ((DoubleConstant) left).Value !=
1081 ((DoubleConstant) right).Value;
1082 else if (left is FloatConstant)
1083 bool_res = ((FloatConstant) left).Value !=
1084 ((FloatConstant) right).Value;
1085 else if (left is ULongConstant)
1086 bool_res = ((ULongConstant) left).Value !=
1087 ((ULongConstant) right).Value;
1088 else if (left is LongConstant)
1089 bool_res = ((LongConstant) left).Value !=
1090 ((LongConstant) right).Value;
1091 else if (left is UIntConstant)
1092 bool_res = ((UIntConstant) left).Value !=
1093 ((UIntConstant) right).Value;
1094 else if (left is IntConstant)
1095 bool_res = ((IntConstant) left).Value !=
1096 ((IntConstant) right).Value;
1100 return new BoolConstant (bool_res);
1102 case Binary.Operator.LessThan:
1103 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1104 if (left == null || right == null)
1108 if (left is DoubleConstant)
1109 bool_res = ((DoubleConstant) left).Value <
1110 ((DoubleConstant) right).Value;
1111 else if (left is FloatConstant)
1112 bool_res = ((FloatConstant) left).Value <
1113 ((FloatConstant) right).Value;
1114 else if (left is ULongConstant)
1115 bool_res = ((ULongConstant) left).Value <
1116 ((ULongConstant) right).Value;
1117 else if (left is LongConstant)
1118 bool_res = ((LongConstant) left).Value <
1119 ((LongConstant) right).Value;
1120 else if (left is UIntConstant)
1121 bool_res = ((UIntConstant) left).Value <
1122 ((UIntConstant) right).Value;
1123 else if (left is IntConstant)
1124 bool_res = ((IntConstant) left).Value <
1125 ((IntConstant) right).Value;
1129 return new BoolConstant (bool_res);
1131 case Binary.Operator.GreaterThan:
1132 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1133 if (left == null || right == null)
1137 if (left is DoubleConstant)
1138 bool_res = ((DoubleConstant) left).Value >
1139 ((DoubleConstant) right).Value;
1140 else if (left is FloatConstant)
1141 bool_res = ((FloatConstant) left).Value >
1142 ((FloatConstant) right).Value;
1143 else if (left is ULongConstant)
1144 bool_res = ((ULongConstant) left).Value >
1145 ((ULongConstant) right).Value;
1146 else if (left is LongConstant)
1147 bool_res = ((LongConstant) left).Value >
1148 ((LongConstant) right).Value;
1149 else if (left is UIntConstant)
1150 bool_res = ((UIntConstant) left).Value >
1151 ((UIntConstant) right).Value;
1152 else if (left is IntConstant)
1153 bool_res = ((IntConstant) left).Value >
1154 ((IntConstant) right).Value;
1158 return new BoolConstant (bool_res);
1160 case Binary.Operator.GreaterThanOrEqual:
1161 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1162 if (left == null || right == null)
1166 if (left is DoubleConstant)
1167 bool_res = ((DoubleConstant) left).Value >=
1168 ((DoubleConstant) right).Value;
1169 else if (left is FloatConstant)
1170 bool_res = ((FloatConstant) left).Value >=
1171 ((FloatConstant) right).Value;
1172 else if (left is ULongConstant)
1173 bool_res = ((ULongConstant) left).Value >=
1174 ((ULongConstant) right).Value;
1175 else if (left is LongConstant)
1176 bool_res = ((LongConstant) left).Value >=
1177 ((LongConstant) right).Value;
1178 else if (left is UIntConstant)
1179 bool_res = ((UIntConstant) left).Value >=
1180 ((UIntConstant) right).Value;
1181 else if (left is IntConstant)
1182 bool_res = ((IntConstant) left).Value >=
1183 ((IntConstant) right).Value;
1187 return new BoolConstant (bool_res);
1189 case Binary.Operator.LessThanOrEqual:
1190 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1191 if (left == null || right == null)
1195 if (left is DoubleConstant)
1196 bool_res = ((DoubleConstant) left).Value <=
1197 ((DoubleConstant) right).Value;
1198 else if (left is FloatConstant)
1199 bool_res = ((FloatConstant) left).Value <=
1200 ((FloatConstant) right).Value;
1201 else if (left is ULongConstant)
1202 bool_res = ((ULongConstant) left).Value <=
1203 ((ULongConstant) right).Value;
1204 else if (left is LongConstant)
1205 bool_res = ((LongConstant) left).Value <=
1206 ((LongConstant) right).Value;
1207 else if (left is UIntConstant)
1208 bool_res = ((UIntConstant) left).Value <=
1209 ((UIntConstant) right).Value;
1210 else if (left is IntConstant)
1211 bool_res = ((IntConstant) left).Value <=
1212 ((IntConstant) right).Value;
1216 return new BoolConstant (bool_res);