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 ||
161 (other.IsZeroInteger && other is IntConstant));
164 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
165 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
171 if (left is EnumConstant)
172 left = ((EnumConstant) left).Child;
173 if (right is EnumConstant)
174 right = ((EnumConstant) right).Child;
176 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
181 // Force conversions to int32
183 if (!(left is IntConstant))
184 left = left.ToInt (loc);
185 if (!(right is IntConstant))
186 right = right.ToInt (loc);
191 static void Error_CompileTimeOverflow (Location loc)
193 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
197 /// Constant expression folder for binary operations.
199 /// Returns null if the expression can not be folded.
201 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
202 Constant left, Constant right, Location loc)
205 Type rt = right.Type;
206 Type result_type = null;
210 // Enumerator folding
212 if (rt == lt && left is EnumConstant)
216 // During an enum evaluation, we need to unwrap enumerations
218 if (ec.InEnumContext){
219 if (left is EnumConstant)
220 left = ((EnumConstant) left).Child;
222 if (right is EnumConstant)
223 right = ((EnumConstant) right).Child;
227 Constant result = null;
229 case Binary.Operator.BitwiseOr:
230 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
231 if (left == null || right == null)
234 if (left is IntConstant){
236 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
238 v = new IntConstant (res);
239 if (result_type == null)
242 return new EnumConstant (v, result_type);
243 } else if (left is UIntConstant){
245 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
247 v = new UIntConstant (res);
248 if (result_type == null)
251 return new EnumConstant (v, result_type);
252 } else if (left is LongConstant){
254 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
256 v = new LongConstant (res);
257 if (result_type == null)
260 return new EnumConstant (v, result_type);
261 } else if (left is ULongConstant){
263 ulong res = ((ULongConstant)left).Value |
264 ((ULongConstant)right).Value;
266 v = new ULongConstant (res);
267 if (result_type == null)
270 return new EnumConstant (v, result_type);
271 } else if (left is UShortConstant){
273 ushort res = (ushort) (((UShortConstant)left).Value |
274 ((UShortConstant)right).Value);
276 v = new UShortConstant (res);
277 if (result_type == null)
280 return new EnumConstant (v, result_type);
281 } else if (left is ShortConstant){
283 short res = (short) (((ShortConstant)left).Value |
284 ((ShortConstant)right).Value);
286 v = new ShortConstant (res);
287 if (result_type == null)
290 return new EnumConstant (v, result_type);
294 case Binary.Operator.BitwiseAnd:
295 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
296 if (left == null || right == null)
299 if (left is IntConstant){
301 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
303 v = new IntConstant (res);
304 if (result_type == null)
307 return new EnumConstant (v, result_type);
308 } else if (left is UIntConstant){
310 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
312 v = new UIntConstant (res);
313 if (result_type == null)
316 return new EnumConstant (v, result_type);
317 } else if (left is LongConstant){
319 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
321 v = new LongConstant (res);
322 if (result_type == null)
325 return new EnumConstant (v, result_type);
326 } else if (left is ULongConstant){
328 ulong res = ((ULongConstant)left).Value &
329 ((ULongConstant)right).Value;
331 v = new ULongConstant (res);
332 if (result_type == null)
335 return new EnumConstant (v, result_type);
336 } else if (left is UShortConstant){
338 ushort res = (ushort) (((UShortConstant)left).Value &
339 ((UShortConstant)right).Value);
341 v = new UShortConstant (res);
342 if (result_type == null)
345 return new EnumConstant (v, result_type);
346 } else if (left is ShortConstant){
348 short res = (short) (((ShortConstant)left).Value &
349 ((ShortConstant)right).Value);
351 v = new ShortConstant (res);
352 if (result_type == null)
355 return new EnumConstant (v, result_type);
359 case Binary.Operator.ExclusiveOr:
360 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
361 if (left == null || right == null)
364 if (left is IntConstant){
366 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
368 v = new IntConstant (res);
369 if (result_type == null)
372 return new EnumConstant (v, result_type);
373 } else if (left is UIntConstant){
375 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
377 v = new UIntConstant (res);
378 if (result_type == null)
381 return new EnumConstant (v, result_type);
382 } else if (left is LongConstant){
384 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
386 v = new LongConstant (res);
387 if (result_type == null)
390 return new EnumConstant (v, result_type);
391 } else if (left is ULongConstant){
393 ulong res = ((ULongConstant)left).Value ^
394 ((ULongConstant)right).Value;
396 v = new ULongConstant (res);
397 if (result_type == null)
400 return new EnumConstant (v, result_type);
401 } else if (left is UShortConstant){
403 ushort res = (ushort) (((UShortConstant)left).Value ^
404 ((UShortConstant)right).Value);
406 v = new UShortConstant (res);
407 if (result_type == null)
410 return new EnumConstant (v, result_type);
411 } else if (left is ShortConstant){
413 short res = (short)(((ShortConstant)left).Value ^
414 ((ShortConstant)right).Value);
416 v = new ShortConstant (res);
417 if (result_type == null)
420 return new EnumConstant (v, result_type);
424 case Binary.Operator.Addition:
425 bool left_is_string = left is StringConstant;
426 bool right_is_string = right is StringConstant;
429 // If both sides are strings, then concatenate, if
430 // one is a string, and the other is not, then defer
431 // to runtime concatenation
434 if (left_is_string || right_is_string){
435 if (left_is_string && right_is_string)
436 return new StringConstant (
437 ((StringConstant) left).Value +
438 ((StringConstant) right).Value);
444 // handle "E operator + (E x, U y)"
445 // handle "E operator + (Y y, E x)"
447 // note that E operator + (E x, E y) is invalid
449 if (left is EnumConstant){
450 if (right is EnumConstant){
453 if (((EnumConstant) left).Child.Type != right.Type)
457 } else if (right is EnumConstant){
458 if (((EnumConstant) right).Child.Type != left.Type)
460 wrap_as = right.Type;
464 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
465 if (left == null || right == null)
469 if (left is DoubleConstant){
472 if (ec.ConstantCheckState)
473 res = checked (((DoubleConstant) left).Value +
474 ((DoubleConstant) right).Value);
476 res = unchecked (((DoubleConstant) left).Value +
477 ((DoubleConstant) right).Value);
479 result = new DoubleConstant (res);
480 } else if (left is FloatConstant){
483 if (ec.ConstantCheckState)
484 res = checked (((FloatConstant) left).Value +
485 ((FloatConstant) right).Value);
487 res = unchecked (((FloatConstant) left).Value +
488 ((FloatConstant) right).Value);
490 result = new FloatConstant (res);
491 } else if (left is ULongConstant){
494 if (ec.ConstantCheckState)
495 res = checked (((ULongConstant) left).Value +
496 ((ULongConstant) right).Value);
498 res = unchecked (((ULongConstant) left).Value +
499 ((ULongConstant) right).Value);
501 result = new ULongConstant (res);
502 } else if (left is LongConstant){
505 if (ec.ConstantCheckState)
506 res = checked (((LongConstant) left).Value +
507 ((LongConstant) right).Value);
509 res = unchecked (((LongConstant) left).Value +
510 ((LongConstant) right).Value);
512 result = new LongConstant (res);
513 } else if (left is UIntConstant){
516 if (ec.ConstantCheckState)
517 res = checked (((UIntConstant) left).Value +
518 ((UIntConstant) right).Value);
520 res = unchecked (((UIntConstant) left).Value +
521 ((UIntConstant) right).Value);
523 result = new UIntConstant (res);
524 } else if (left is IntConstant){
527 if (ec.ConstantCheckState)
528 res = checked (((IntConstant) left).Value +
529 ((IntConstant) right).Value);
531 res = unchecked (((IntConstant) left).Value +
532 ((IntConstant) right).Value);
534 result = new IntConstant (res);
535 } else if (left is DecimalConstant) {
538 if (ec.ConstantCheckState)
539 res = checked (((DecimalConstant) left).Value +
540 ((DecimalConstant) right).Value);
542 res = unchecked (((DecimalConstant) left).Value +
543 ((DecimalConstant) right).Value);
545 result = new DecimalConstant (res);
547 throw new Exception ( "Unexepected addition input: " + left);
549 } catch (OverflowException){
550 Error_CompileTimeOverflow (loc);
554 return new EnumConstant (result, wrap_as);
558 case Binary.Operator.Subtraction:
560 // handle "E operator - (E x, U y)"
561 // handle "E operator - (Y y, E x)"
562 // handle "U operator - (E x, E y)"
565 if (left is EnumConstant){
566 if (right is EnumConstant){
567 if (left.Type == right.Type)
568 wrap_as = TypeManager.EnumToUnderlying (left.Type);
572 if (((EnumConstant) left).Child.Type != right.Type)
576 } else if (right is EnumConstant){
577 if (((EnumConstant) right).Child.Type != left.Type)
579 wrap_as = right.Type;
582 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
583 if (left == null || right == null)
587 if (left is DoubleConstant){
590 if (ec.ConstantCheckState)
591 res = checked (((DoubleConstant) left).Value -
592 ((DoubleConstant) right).Value);
594 res = unchecked (((DoubleConstant) left).Value -
595 ((DoubleConstant) right).Value);
597 result = new DoubleConstant (res);
598 } else if (left is FloatConstant){
601 if (ec.ConstantCheckState)
602 res = checked (((FloatConstant) left).Value -
603 ((FloatConstant) right).Value);
605 res = unchecked (((FloatConstant) left).Value -
606 ((FloatConstant) right).Value);
608 result = new FloatConstant (res);
609 } else if (left is ULongConstant){
612 if (ec.ConstantCheckState)
613 res = checked (((ULongConstant) left).Value -
614 ((ULongConstant) right).Value);
616 res = unchecked (((ULongConstant) left).Value -
617 ((ULongConstant) right).Value);
619 result = new ULongConstant (res);
620 } else if (left is LongConstant){
623 if (ec.ConstantCheckState)
624 res = checked (((LongConstant) left).Value -
625 ((LongConstant) right).Value);
627 res = unchecked (((LongConstant) left).Value -
628 ((LongConstant) right).Value);
630 result = new LongConstant (res);
631 } else if (left is UIntConstant){
634 if (ec.ConstantCheckState)
635 res = checked (((UIntConstant) left).Value -
636 ((UIntConstant) right).Value);
638 res = unchecked (((UIntConstant) left).Value -
639 ((UIntConstant) right).Value);
641 result = new UIntConstant (res);
642 } else if (left is IntConstant){
645 if (ec.ConstantCheckState)
646 res = checked (((IntConstant) left).Value -
647 ((IntConstant) right).Value);
649 res = unchecked (((IntConstant) left).Value -
650 ((IntConstant) right).Value);
652 result = new IntConstant (res);
653 } else if (left is DecimalConstant) {
656 if (ec.ConstantCheckState)
657 res = checked (((DecimalConstant) left).Value -
658 ((DecimalConstant) right).Value);
660 res = unchecked (((DecimalConstant) left).Value -
661 ((DecimalConstant) right).Value);
663 return new DecimalConstant (res);
665 throw new Exception ( "Unexepected subtraction input: " + left);
667 } catch (OverflowException){
668 Error_CompileTimeOverflow (loc);
671 return new EnumConstant (result, wrap_as);
675 case Binary.Operator.Multiply:
676 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
677 if (left == null || right == null)
681 if (left is DoubleConstant){
684 if (ec.ConstantCheckState)
685 res = checked (((DoubleConstant) left).Value *
686 ((DoubleConstant) right).Value);
688 res = unchecked (((DoubleConstant) left).Value *
689 ((DoubleConstant) right).Value);
691 return new DoubleConstant (res);
692 } else if (left is FloatConstant){
695 if (ec.ConstantCheckState)
696 res = checked (((FloatConstant) left).Value *
697 ((FloatConstant) right).Value);
699 res = unchecked (((FloatConstant) left).Value *
700 ((FloatConstant) right).Value);
702 return new FloatConstant (res);
703 } else if (left is ULongConstant){
706 if (ec.ConstantCheckState)
707 res = checked (((ULongConstant) left).Value *
708 ((ULongConstant) right).Value);
710 res = unchecked (((ULongConstant) left).Value *
711 ((ULongConstant) right).Value);
713 return new ULongConstant (res);
714 } else if (left is LongConstant){
717 if (ec.ConstantCheckState)
718 res = checked (((LongConstant) left).Value *
719 ((LongConstant) right).Value);
721 res = unchecked (((LongConstant) left).Value *
722 ((LongConstant) right).Value);
724 return new LongConstant (res);
725 } else if (left is UIntConstant){
728 if (ec.ConstantCheckState)
729 res = checked (((UIntConstant) left).Value *
730 ((UIntConstant) right).Value);
732 res = unchecked (((UIntConstant) left).Value *
733 ((UIntConstant) right).Value);
735 return new UIntConstant (res);
736 } else if (left is IntConstant){
739 if (ec.ConstantCheckState)
740 res = checked (((IntConstant) left).Value *
741 ((IntConstant) right).Value);
743 res = unchecked (((IntConstant) left).Value *
744 ((IntConstant) right).Value);
746 return new IntConstant (res);
747 } else if (left is DecimalConstant) {
750 if (ec.ConstantCheckState)
751 res = checked (((DecimalConstant) left).Value *
752 ((DecimalConstant) right).Value);
754 res = unchecked (((DecimalConstant) left).Value *
755 ((DecimalConstant) right).Value);
757 return new DecimalConstant (res);
759 throw new Exception ( "Unexepected multiply input: " + left);
761 } catch (OverflowException){
762 Error_CompileTimeOverflow (loc);
766 case Binary.Operator.Division:
767 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
768 if (left == null || right == null)
772 if (left is DoubleConstant){
775 if (ec.ConstantCheckState)
776 res = checked (((DoubleConstant) left).Value /
777 ((DoubleConstant) right).Value);
779 res = unchecked (((DoubleConstant) left).Value /
780 ((DoubleConstant) right).Value);
782 return new DoubleConstant (res);
783 } else if (left is FloatConstant){
786 if (ec.ConstantCheckState)
787 res = checked (((FloatConstant) left).Value /
788 ((FloatConstant) right).Value);
790 res = unchecked (((FloatConstant) left).Value /
791 ((FloatConstant) right).Value);
793 return new FloatConstant (res);
794 } else if (left is ULongConstant){
797 if (ec.ConstantCheckState)
798 res = checked (((ULongConstant) left).Value /
799 ((ULongConstant) right).Value);
801 res = unchecked (((ULongConstant) left).Value /
802 ((ULongConstant) right).Value);
804 return new ULongConstant (res);
805 } else if (left is LongConstant){
808 if (ec.ConstantCheckState)
809 res = checked (((LongConstant) left).Value /
810 ((LongConstant) right).Value);
812 res = unchecked (((LongConstant) left).Value /
813 ((LongConstant) right).Value);
815 return new LongConstant (res);
816 } else if (left is UIntConstant){
819 if (ec.ConstantCheckState)
820 res = checked (((UIntConstant) left).Value /
821 ((UIntConstant) right).Value);
823 res = unchecked (((UIntConstant) left).Value /
824 ((UIntConstant) right).Value);
826 return new UIntConstant (res);
827 } else if (left is IntConstant){
830 if (ec.ConstantCheckState)
831 res = checked (((IntConstant) left).Value /
832 ((IntConstant) right).Value);
834 res = unchecked (((IntConstant) left).Value /
835 ((IntConstant) right).Value);
837 return new IntConstant (res);
838 } else if (left is DecimalConstant) {
841 if (ec.ConstantCheckState)
842 res = checked (((DecimalConstant) left).Value /
843 ((DecimalConstant) right).Value);
845 res = unchecked (((DecimalConstant) left).Value /
846 ((DecimalConstant) right).Value);
848 return new DecimalConstant (res);
850 throw new Exception ( "Unexepected division input: " + left);
852 } catch (OverflowException){
853 Error_CompileTimeOverflow (loc);
855 } catch (DivideByZeroException) {
856 Report.Error (020, loc, "Division by constant zero");
861 case Binary.Operator.Modulus:
862 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
863 if (left == null || right == null)
867 if (left is DoubleConstant){
870 if (ec.ConstantCheckState)
871 res = checked (((DoubleConstant) left).Value %
872 ((DoubleConstant) right).Value);
874 res = unchecked (((DoubleConstant) left).Value %
875 ((DoubleConstant) right).Value);
877 return new DoubleConstant (res);
878 } else if (left is FloatConstant){
881 if (ec.ConstantCheckState)
882 res = checked (((FloatConstant) left).Value %
883 ((FloatConstant) right).Value);
885 res = unchecked (((FloatConstant) left).Value %
886 ((FloatConstant) right).Value);
888 return new FloatConstant (res);
889 } else if (left is ULongConstant){
892 if (ec.ConstantCheckState)
893 res = checked (((ULongConstant) left).Value %
894 ((ULongConstant) right).Value);
896 res = unchecked (((ULongConstant) left).Value %
897 ((ULongConstant) right).Value);
899 return new ULongConstant (res);
900 } else if (left is LongConstant){
903 if (ec.ConstantCheckState)
904 res = checked (((LongConstant) left).Value %
905 ((LongConstant) right).Value);
907 res = unchecked (((LongConstant) left).Value %
908 ((LongConstant) right).Value);
910 return new LongConstant (res);
911 } else if (left is UIntConstant){
914 if (ec.ConstantCheckState)
915 res = checked (((UIntConstant) left).Value %
916 ((UIntConstant) right).Value);
918 res = unchecked (((UIntConstant) left).Value %
919 ((UIntConstant) right).Value);
921 return new UIntConstant (res);
922 } else if (left is IntConstant){
925 if (ec.ConstantCheckState)
926 res = checked (((IntConstant) left).Value %
927 ((IntConstant) right).Value);
929 res = unchecked (((IntConstant) left).Value %
930 ((IntConstant) right).Value);
932 return new IntConstant (res);
934 throw new Exception ( "Unexepected modulus input: " + left);
936 } catch (DivideByZeroException){
937 Report.Error (020, loc, "Division by constant zero");
938 } catch (OverflowException){
939 Error_CompileTimeOverflow (loc);
944 // There is no overflow checking on left shift
946 case Binary.Operator.LeftShift:
947 IntConstant ic = right.ToInt (loc);
949 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
952 int lshift_val = ic.Value;
955 if ((lic = left.ConvertToInt ()) != null)
956 return new IntConstant (lic.Value << lshift_val);
959 if ((luic = left.ConvertToUInt ()) != null)
960 return new UIntConstant (luic.Value << lshift_val);
963 if ((llc = left.ConvertToLong ()) != null)
964 return new LongConstant (llc.Value << lshift_val);
967 if ((lulc = left.ConvertToULong ()) != null)
968 return new ULongConstant (lulc.Value << lshift_val);
970 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
974 // There is no overflow checking on right shift
976 case Binary.Operator.RightShift:
977 IntConstant sic = right.ToInt (loc);
979 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
982 int rshift_val = sic.Value;
985 if ((ric = left.ConvertToInt ()) != null)
986 return new IntConstant (ric.Value >> rshift_val);
989 if ((ruic = left.ConvertToUInt ()) != null)
990 return new UIntConstant (ruic.Value >> rshift_val);
993 if ((rlc = left.ConvertToLong ()) != null)
994 return new LongConstant (rlc.Value >> rshift_val);
997 if ((rulc = left.ConvertToULong ()) != null)
998 return new ULongConstant (rulc.Value >> rshift_val);
1000 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1003 case Binary.Operator.LogicalAnd:
1004 if (left is BoolConstant && right is BoolConstant){
1005 return new BoolConstant (
1006 ((BoolConstant) left).Value &&
1007 ((BoolConstant) right).Value);
1011 case Binary.Operator.LogicalOr:
1012 if (left is BoolConstant && right is BoolConstant){
1013 return new BoolConstant (
1014 ((BoolConstant) left).Value ||
1015 ((BoolConstant) right).Value);
1019 case Binary.Operator.Equality:
1020 if (left is BoolConstant && right is BoolConstant){
1021 return new BoolConstant (
1022 ((BoolConstant) left).Value ==
1023 ((BoolConstant) right).Value);
1026 if (left is NullLiteral){
1027 if (right is NullLiteral)
1028 return new BoolConstant (true);
1029 else if (right is StringConstant)
1030 return new BoolConstant (
1031 ((StringConstant) right).Value == null);
1032 } else if (right is NullLiteral){
1033 if (left is NullLiteral)
1034 return new BoolConstant (true);
1035 else if (left is StringConstant)
1036 return new BoolConstant (
1037 ((StringConstant) left).Value == null);
1039 if (left is StringConstant && right is StringConstant){
1040 return new BoolConstant (
1041 ((StringConstant) left).Value ==
1042 ((StringConstant) right).Value);
1046 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1047 if (left == null || right == null)
1051 if (left is DoubleConstant)
1052 bool_res = ((DoubleConstant) left).Value ==
1053 ((DoubleConstant) right).Value;
1054 else if (left is FloatConstant)
1055 bool_res = ((FloatConstant) left).Value ==
1056 ((FloatConstant) right).Value;
1057 else if (left is ULongConstant)
1058 bool_res = ((ULongConstant) left).Value ==
1059 ((ULongConstant) right).Value;
1060 else if (left is LongConstant)
1061 bool_res = ((LongConstant) left).Value ==
1062 ((LongConstant) right).Value;
1063 else if (left is UIntConstant)
1064 bool_res = ((UIntConstant) left).Value ==
1065 ((UIntConstant) right).Value;
1066 else if (left is IntConstant)
1067 bool_res = ((IntConstant) left).Value ==
1068 ((IntConstant) right).Value;
1072 return new BoolConstant (bool_res);
1074 case Binary.Operator.Inequality:
1075 if (left is BoolConstant && right is BoolConstant){
1076 return new BoolConstant (
1077 ((BoolConstant) left).Value !=
1078 ((BoolConstant) right).Value);
1080 if (left is NullLiteral){
1081 if (right is NullLiteral)
1082 return new BoolConstant (false);
1083 else if (right is StringConstant)
1084 return new BoolConstant (
1085 ((StringConstant) right).Value != null);
1086 } else if (right is NullLiteral){
1087 if (left is NullLiteral)
1088 return new BoolConstant (false);
1089 else if (left is StringConstant)
1090 return new BoolConstant (
1091 ((StringConstant) left).Value != null);
1093 if (left is StringConstant && right is StringConstant){
1094 return new BoolConstant (
1095 ((StringConstant) left).Value !=
1096 ((StringConstant) right).Value);
1099 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1100 if (left == null || right == null)
1104 if (left is DoubleConstant)
1105 bool_res = ((DoubleConstant) left).Value !=
1106 ((DoubleConstant) right).Value;
1107 else if (left is FloatConstant)
1108 bool_res = ((FloatConstant) left).Value !=
1109 ((FloatConstant) right).Value;
1110 else if (left is ULongConstant)
1111 bool_res = ((ULongConstant) left).Value !=
1112 ((ULongConstant) right).Value;
1113 else if (left is LongConstant)
1114 bool_res = ((LongConstant) left).Value !=
1115 ((LongConstant) right).Value;
1116 else if (left is UIntConstant)
1117 bool_res = ((UIntConstant) left).Value !=
1118 ((UIntConstant) right).Value;
1119 else if (left is IntConstant)
1120 bool_res = ((IntConstant) left).Value !=
1121 ((IntConstant) right).Value;
1125 return new BoolConstant (bool_res);
1127 case Binary.Operator.LessThan:
1128 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1129 if (left == null || right == null)
1133 if (left is DoubleConstant)
1134 bool_res = ((DoubleConstant) left).Value <
1135 ((DoubleConstant) right).Value;
1136 else if (left is FloatConstant)
1137 bool_res = ((FloatConstant) left).Value <
1138 ((FloatConstant) right).Value;
1139 else if (left is ULongConstant)
1140 bool_res = ((ULongConstant) left).Value <
1141 ((ULongConstant) right).Value;
1142 else if (left is LongConstant)
1143 bool_res = ((LongConstant) left).Value <
1144 ((LongConstant) right).Value;
1145 else if (left is UIntConstant)
1146 bool_res = ((UIntConstant) left).Value <
1147 ((UIntConstant) right).Value;
1148 else if (left is IntConstant)
1149 bool_res = ((IntConstant) left).Value <
1150 ((IntConstant) right).Value;
1154 return new BoolConstant (bool_res);
1156 case Binary.Operator.GreaterThan:
1157 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1158 if (left == null || right == null)
1162 if (left is DoubleConstant)
1163 bool_res = ((DoubleConstant) left).Value >
1164 ((DoubleConstant) right).Value;
1165 else if (left is FloatConstant)
1166 bool_res = ((FloatConstant) left).Value >
1167 ((FloatConstant) right).Value;
1168 else if (left is ULongConstant)
1169 bool_res = ((ULongConstant) left).Value >
1170 ((ULongConstant) right).Value;
1171 else if (left is LongConstant)
1172 bool_res = ((LongConstant) left).Value >
1173 ((LongConstant) right).Value;
1174 else if (left is UIntConstant)
1175 bool_res = ((UIntConstant) left).Value >
1176 ((UIntConstant) right).Value;
1177 else if (left is IntConstant)
1178 bool_res = ((IntConstant) left).Value >
1179 ((IntConstant) right).Value;
1183 return new BoolConstant (bool_res);
1185 case Binary.Operator.GreaterThanOrEqual:
1186 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1187 if (left == null || right == null)
1191 if (left is DoubleConstant)
1192 bool_res = ((DoubleConstant) left).Value >=
1193 ((DoubleConstant) right).Value;
1194 else if (left is FloatConstant)
1195 bool_res = ((FloatConstant) left).Value >=
1196 ((FloatConstant) right).Value;
1197 else if (left is ULongConstant)
1198 bool_res = ((ULongConstant) left).Value >=
1199 ((ULongConstant) right).Value;
1200 else if (left is LongConstant)
1201 bool_res = ((LongConstant) left).Value >=
1202 ((LongConstant) right).Value;
1203 else if (left is UIntConstant)
1204 bool_res = ((UIntConstant) left).Value >=
1205 ((UIntConstant) right).Value;
1206 else if (left is IntConstant)
1207 bool_res = ((IntConstant) left).Value >=
1208 ((IntConstant) right).Value;
1212 return new BoolConstant (bool_res);
1214 case Binary.Operator.LessThanOrEqual:
1215 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1216 if (left == null || right == null)
1220 if (left is DoubleConstant)
1221 bool_res = ((DoubleConstant) left).Value <=
1222 ((DoubleConstant) right).Value;
1223 else if (left is FloatConstant)
1224 bool_res = ((FloatConstant) left).Value <=
1225 ((FloatConstant) right).Value;
1226 else if (left is ULongConstant)
1227 bool_res = ((ULongConstant) left).Value <=
1228 ((ULongConstant) right).Value;
1229 else if (left is LongConstant)
1230 bool_res = ((LongConstant) left).Value <=
1231 ((LongConstant) right).Value;
1232 else if (left is UIntConstant)
1233 bool_res = ((UIntConstant) left).Value <=
1234 ((UIntConstant) right).Value;
1235 else if (left is IntConstant)
1236 bool_res = ((IntConstant) left).Value <=
1237 ((IntConstant) right).Value;
1241 return new BoolConstant (bool_res);