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;
175 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
180 // Force conversions to int32
182 if (!(left is IntConstant))
183 left = left.ToInt (loc);
184 if (!(right is IntConstant))
185 right = right.ToInt (loc);
190 static void Error_CompileTimeOverflow (Location loc)
192 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
196 /// Constant expression folder for binary operations.
198 /// Returns null if the expression can not be folded.
200 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
201 Constant left, Constant right, Location loc)
204 Type rt = right.Type;
205 Type result_type = null;
209 // Enumerator folding
211 if (rt == lt && left is EnumConstant)
215 // During an enum evaluation, we need to unwrap enumerations
217 if (ec.InEnumContext){
218 if (left is EnumConstant)
219 left = ((EnumConstant) left).Child;
221 if (right is EnumConstant)
222 right = ((EnumConstant) right).Child;
226 Constant result = null;
228 case Binary.Operator.BitwiseOr:
229 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
230 if (left == null || right == null)
233 if (left is IntConstant){
235 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
237 v = new IntConstant (res);
238 if (result_type == null)
241 return new EnumConstant (v, result_type);
242 } else if (left is UIntConstant){
244 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
246 v = new UIntConstant (res);
247 if (result_type == null)
250 return new EnumConstant (v, result_type);
251 } else if (left is LongConstant){
253 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
255 v = new LongConstant (res);
256 if (result_type == null)
259 return new EnumConstant (v, result_type);
260 } else if (left is ULongConstant){
262 ulong res = ((ULongConstant)left).Value |
263 ((ULongConstant)right).Value;
265 v = new ULongConstant (res);
266 if (result_type == null)
269 return new EnumConstant (v, result_type);
270 } else if (left is UShortConstant){
272 ushort res = (ushort) (((UShortConstant)left).Value |
273 ((UShortConstant)right).Value);
275 v = new UShortConstant (res);
276 if (result_type == null)
279 return new EnumConstant (v, result_type);
280 } else if (left is ShortConstant){
282 short res = (short) (((ShortConstant)left).Value |
283 ((ShortConstant)right).Value);
285 v = new ShortConstant (res);
286 if (result_type == null)
289 return new EnumConstant (v, result_type);
293 case Binary.Operator.BitwiseAnd:
294 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
295 if (left == null || right == null)
298 if (left is IntConstant){
300 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
302 v = new IntConstant (res);
303 if (result_type == null)
306 return new EnumConstant (v, result_type);
307 } else if (left is UIntConstant){
309 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
311 v = new UIntConstant (res);
312 if (result_type == null)
315 return new EnumConstant (v, result_type);
316 } else if (left is LongConstant){
318 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
320 v = new LongConstant (res);
321 if (result_type == null)
324 return new EnumConstant (v, result_type);
325 } else if (left is ULongConstant){
327 ulong res = ((ULongConstant)left).Value &
328 ((ULongConstant)right).Value;
330 v = new ULongConstant (res);
331 if (result_type == null)
334 return new EnumConstant (v, result_type);
335 } else if (left is UShortConstant){
337 ushort res = (ushort) (((UShortConstant)left).Value &
338 ((UShortConstant)right).Value);
340 v = new UShortConstant (res);
341 if (result_type == null)
344 return new EnumConstant (v, result_type);
345 } else if (left is ShortConstant){
347 short res = (short) (((ShortConstant)left).Value &
348 ((ShortConstant)right).Value);
350 v = new ShortConstant (res);
351 if (result_type == null)
354 return new EnumConstant (v, result_type);
358 case Binary.Operator.ExclusiveOr:
359 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
360 if (left == null || right == null)
363 if (left is IntConstant){
365 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
367 v = new IntConstant (res);
368 if (result_type == null)
371 return new EnumConstant (v, result_type);
372 } else if (left is UIntConstant){
374 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
376 v = new UIntConstant (res);
377 if (result_type == null)
380 return new EnumConstant (v, result_type);
381 } else if (left is LongConstant){
383 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
385 v = new LongConstant (res);
386 if (result_type == null)
389 return new EnumConstant (v, result_type);
390 } else if (left is ULongConstant){
392 ulong res = ((ULongConstant)left).Value ^
393 ((ULongConstant)right).Value;
395 v = new ULongConstant (res);
396 if (result_type == null)
399 return new EnumConstant (v, result_type);
400 } else if (left is UShortConstant){
402 ushort res = (ushort) (((UShortConstant)left).Value ^
403 ((UShortConstant)right).Value);
405 v = new UShortConstant (res);
406 if (result_type == null)
409 return new EnumConstant (v, result_type);
410 } else if (left is ShortConstant){
412 short res = (short)(((ShortConstant)left).Value ^
413 ((ShortConstant)right).Value);
415 v = new ShortConstant (res);
416 if (result_type == null)
419 return new EnumConstant (v, result_type);
423 case Binary.Operator.Addition:
424 bool left_is_string = left is StringConstant;
425 bool right_is_string = right is StringConstant;
428 // If both sides are strings, then concatenate, if
429 // one is a string, and the other is not, then defer
430 // to runtime concatenation
433 if (left_is_string || right_is_string){
434 if (left_is_string && right_is_string)
435 return new StringConstant (
436 ((StringConstant) left).Value +
437 ((StringConstant) right).Value);
443 // handle "E operator + (E x, U y)"
444 // handle "E operator + (Y y, E x)"
446 // note that E operator + (E x, E y) is invalid
448 if (left is EnumConstant){
449 if (right is EnumConstant){
452 if (((EnumConstant) left).Child.Type != right.Type)
456 } else if (right is EnumConstant){
457 if (((EnumConstant) right).Child.Type != left.Type)
459 wrap_as = right.Type;
463 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
464 if (left == null || right == null)
468 if (left is DoubleConstant){
471 if (ec.ConstantCheckState)
472 res = checked (((DoubleConstant) left).Value +
473 ((DoubleConstant) right).Value);
475 res = unchecked (((DoubleConstant) left).Value +
476 ((DoubleConstant) right).Value);
478 result = new DoubleConstant (res);
479 } else if (left is FloatConstant){
482 if (ec.ConstantCheckState)
483 res = checked (((FloatConstant) left).Value +
484 ((FloatConstant) right).Value);
486 res = unchecked (((FloatConstant) left).Value +
487 ((FloatConstant) right).Value);
489 result = new FloatConstant (res);
490 } else if (left is ULongConstant){
493 if (ec.ConstantCheckState)
494 res = checked (((ULongConstant) left).Value +
495 ((ULongConstant) right).Value);
497 res = unchecked (((ULongConstant) left).Value +
498 ((ULongConstant) right).Value);
500 result = new ULongConstant (res);
501 } else if (left is LongConstant){
504 if (ec.ConstantCheckState)
505 res = checked (((LongConstant) left).Value +
506 ((LongConstant) right).Value);
508 res = unchecked (((LongConstant) left).Value +
509 ((LongConstant) right).Value);
511 result = new LongConstant (res);
512 } else if (left is UIntConstant){
515 if (ec.ConstantCheckState)
516 res = checked (((UIntConstant) left).Value +
517 ((UIntConstant) right).Value);
519 res = unchecked (((UIntConstant) left).Value +
520 ((UIntConstant) right).Value);
522 result = new UIntConstant (res);
523 } else if (left is IntConstant){
526 if (ec.ConstantCheckState)
527 res = checked (((IntConstant) left).Value +
528 ((IntConstant) right).Value);
530 res = unchecked (((IntConstant) left).Value +
531 ((IntConstant) right).Value);
533 result = new IntConstant (res);
534 } else if (left is DecimalConstant) {
537 if (ec.ConstantCheckState)
538 res = checked (((DecimalConstant) left).Value +
539 ((DecimalConstant) right).Value);
541 res = unchecked (((DecimalConstant) left).Value +
542 ((DecimalConstant) right).Value);
544 result = new DecimalConstant (res);
546 throw new Exception ( "Unexepected addition input: " + left);
548 } catch (OverflowException){
549 Error_CompileTimeOverflow (loc);
553 return new EnumConstant (result, wrap_as);
557 case Binary.Operator.Subtraction:
559 // handle "E operator - (E x, U y)"
560 // handle "E operator - (Y y, E x)"
561 // handle "U operator - (E x, E y)"
564 if (left is EnumConstant){
565 if (right is EnumConstant){
566 if (left.Type == right.Type)
567 wrap_as = TypeManager.EnumToUnderlying (left.Type);
571 if (((EnumConstant) left).Child.Type != right.Type)
575 } else if (right is EnumConstant){
576 if (((EnumConstant) right).Child.Type != left.Type)
578 wrap_as = right.Type;
581 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
582 if (left == null || right == null)
586 if (left is DoubleConstant){
589 if (ec.ConstantCheckState)
590 res = checked (((DoubleConstant) left).Value -
591 ((DoubleConstant) right).Value);
593 res = unchecked (((DoubleConstant) left).Value -
594 ((DoubleConstant) right).Value);
596 result = new DoubleConstant (res);
597 } else if (left is FloatConstant){
600 if (ec.ConstantCheckState)
601 res = checked (((FloatConstant) left).Value -
602 ((FloatConstant) right).Value);
604 res = unchecked (((FloatConstant) left).Value -
605 ((FloatConstant) right).Value);
607 result = new FloatConstant (res);
608 } else if (left is ULongConstant){
611 if (ec.ConstantCheckState)
612 res = checked (((ULongConstant) left).Value -
613 ((ULongConstant) right).Value);
615 res = unchecked (((ULongConstant) left).Value -
616 ((ULongConstant) right).Value);
618 result = new ULongConstant (res);
619 } else if (left is LongConstant){
622 if (ec.ConstantCheckState)
623 res = checked (((LongConstant) left).Value -
624 ((LongConstant) right).Value);
626 res = unchecked (((LongConstant) left).Value -
627 ((LongConstant) right).Value);
629 result = new LongConstant (res);
630 } else if (left is UIntConstant){
633 if (ec.ConstantCheckState)
634 res = checked (((UIntConstant) left).Value -
635 ((UIntConstant) right).Value);
637 res = unchecked (((UIntConstant) left).Value -
638 ((UIntConstant) right).Value);
640 result = new UIntConstant (res);
641 } else if (left is IntConstant){
644 if (ec.ConstantCheckState)
645 res = checked (((IntConstant) left).Value -
646 ((IntConstant) right).Value);
648 res = unchecked (((IntConstant) left).Value -
649 ((IntConstant) right).Value);
651 result = new IntConstant (res);
652 } else if (left is DecimalConstant) {
655 if (ec.ConstantCheckState)
656 res = checked (((DecimalConstant) left).Value -
657 ((DecimalConstant) right).Value);
659 res = unchecked (((DecimalConstant) left).Value -
660 ((DecimalConstant) right).Value);
662 return new DecimalConstant (res);
664 throw new Exception ( "Unexepected subtraction input: " + left);
666 } catch (OverflowException){
667 Error_CompileTimeOverflow (loc);
670 return new EnumConstant (result, wrap_as);
674 case Binary.Operator.Multiply:
675 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
676 if (left == null || right == null)
680 if (left is DoubleConstant){
683 if (ec.ConstantCheckState)
684 res = checked (((DoubleConstant) left).Value *
685 ((DoubleConstant) right).Value);
687 res = unchecked (((DoubleConstant) left).Value *
688 ((DoubleConstant) right).Value);
690 return new DoubleConstant (res);
691 } else if (left is FloatConstant){
694 if (ec.ConstantCheckState)
695 res = checked (((FloatConstant) left).Value *
696 ((FloatConstant) right).Value);
698 res = unchecked (((FloatConstant) left).Value *
699 ((FloatConstant) right).Value);
701 return new FloatConstant (res);
702 } else if (left is ULongConstant){
705 if (ec.ConstantCheckState)
706 res = checked (((ULongConstant) left).Value *
707 ((ULongConstant) right).Value);
709 res = unchecked (((ULongConstant) left).Value *
710 ((ULongConstant) right).Value);
712 return new ULongConstant (res);
713 } else if (left is LongConstant){
716 if (ec.ConstantCheckState)
717 res = checked (((LongConstant) left).Value *
718 ((LongConstant) right).Value);
720 res = unchecked (((LongConstant) left).Value *
721 ((LongConstant) right).Value);
723 return new LongConstant (res);
724 } else if (left is UIntConstant){
727 if (ec.ConstantCheckState)
728 res = checked (((UIntConstant) left).Value *
729 ((UIntConstant) right).Value);
731 res = unchecked (((UIntConstant) left).Value *
732 ((UIntConstant) right).Value);
734 return new UIntConstant (res);
735 } else if (left is IntConstant){
738 if (ec.ConstantCheckState)
739 res = checked (((IntConstant) left).Value *
740 ((IntConstant) right).Value);
742 res = unchecked (((IntConstant) left).Value *
743 ((IntConstant) right).Value);
745 return new IntConstant (res);
746 } else if (left is DecimalConstant) {
749 if (ec.ConstantCheckState)
750 res = checked (((DecimalConstant) left).Value *
751 ((DecimalConstant) right).Value);
753 res = unchecked (((DecimalConstant) left).Value *
754 ((DecimalConstant) right).Value);
756 return new DecimalConstant (res);
758 throw new Exception ( "Unexepected multiply input: " + left);
760 } catch (OverflowException){
761 Error_CompileTimeOverflow (loc);
765 case Binary.Operator.Division:
766 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
767 if (left == null || right == null)
771 if (left is DoubleConstant){
774 if (ec.ConstantCheckState)
775 res = checked (((DoubleConstant) left).Value /
776 ((DoubleConstant) right).Value);
778 res = unchecked (((DoubleConstant) left).Value /
779 ((DoubleConstant) right).Value);
781 return new DoubleConstant (res);
782 } else if (left is FloatConstant){
785 if (ec.ConstantCheckState)
786 res = checked (((FloatConstant) left).Value /
787 ((FloatConstant) right).Value);
789 res = unchecked (((FloatConstant) left).Value /
790 ((FloatConstant) right).Value);
792 return new FloatConstant (res);
793 } else if (left is ULongConstant){
796 if (ec.ConstantCheckState)
797 res = checked (((ULongConstant) left).Value /
798 ((ULongConstant) right).Value);
800 res = unchecked (((ULongConstant) left).Value /
801 ((ULongConstant) right).Value);
803 return new ULongConstant (res);
804 } else if (left is LongConstant){
807 if (ec.ConstantCheckState)
808 res = checked (((LongConstant) left).Value /
809 ((LongConstant) right).Value);
811 res = unchecked (((LongConstant) left).Value /
812 ((LongConstant) right).Value);
814 return new LongConstant (res);
815 } else if (left is UIntConstant){
818 if (ec.ConstantCheckState)
819 res = checked (((UIntConstant) left).Value /
820 ((UIntConstant) right).Value);
822 res = unchecked (((UIntConstant) left).Value /
823 ((UIntConstant) right).Value);
825 return new UIntConstant (res);
826 } else if (left is IntConstant){
829 if (ec.ConstantCheckState)
830 res = checked (((IntConstant) left).Value /
831 ((IntConstant) right).Value);
833 res = unchecked (((IntConstant) left).Value /
834 ((IntConstant) right).Value);
836 return new IntConstant (res);
837 } else if (left is DecimalConstant) {
840 if (ec.ConstantCheckState)
841 res = checked (((DecimalConstant) left).Value /
842 ((DecimalConstant) right).Value);
844 res = unchecked (((DecimalConstant) left).Value /
845 ((DecimalConstant) right).Value);
847 return new DecimalConstant (res);
849 throw new Exception ( "Unexepected division input: " + left);
851 } catch (OverflowException){
852 Error_CompileTimeOverflow (loc);
854 } catch (DivideByZeroException) {
855 Report.Error (020, loc, "Division by constant zero");
860 case Binary.Operator.Modulus:
861 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
862 if (left == null || right == null)
866 if (left is DoubleConstant){
869 if (ec.ConstantCheckState)
870 res = checked (((DoubleConstant) left).Value %
871 ((DoubleConstant) right).Value);
873 res = unchecked (((DoubleConstant) left).Value %
874 ((DoubleConstant) right).Value);
876 return new DoubleConstant (res);
877 } else if (left is FloatConstant){
880 if (ec.ConstantCheckState)
881 res = checked (((FloatConstant) left).Value %
882 ((FloatConstant) right).Value);
884 res = unchecked (((FloatConstant) left).Value %
885 ((FloatConstant) right).Value);
887 return new FloatConstant (res);
888 } else if (left is ULongConstant){
891 if (ec.ConstantCheckState)
892 res = checked (((ULongConstant) left).Value %
893 ((ULongConstant) right).Value);
895 res = unchecked (((ULongConstant) left).Value %
896 ((ULongConstant) right).Value);
898 return new ULongConstant (res);
899 } else if (left is LongConstant){
902 if (ec.ConstantCheckState)
903 res = checked (((LongConstant) left).Value %
904 ((LongConstant) right).Value);
906 res = unchecked (((LongConstant) left).Value %
907 ((LongConstant) right).Value);
909 return new LongConstant (res);
910 } else if (left is UIntConstant){
913 if (ec.ConstantCheckState)
914 res = checked (((UIntConstant) left).Value %
915 ((UIntConstant) right).Value);
917 res = unchecked (((UIntConstant) left).Value %
918 ((UIntConstant) right).Value);
920 return new UIntConstant (res);
921 } else if (left is IntConstant){
924 if (ec.ConstantCheckState)
925 res = checked (((IntConstant) left).Value %
926 ((IntConstant) right).Value);
928 res = unchecked (((IntConstant) left).Value %
929 ((IntConstant) right).Value);
931 return new IntConstant (res);
933 throw new Exception ( "Unexepected modulus input: " + left);
935 } catch (DivideByZeroException){
936 Report.Error (020, loc, "Division by constant zero");
937 } catch (OverflowException){
938 Error_CompileTimeOverflow (loc);
943 // There is no overflow checking on left shift
945 case Binary.Operator.LeftShift:
946 IntConstant ic = right.ToInt (loc);
948 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
951 int lshift_val = ic.Value;
954 if ((lic = left.ConvertToInt ()) != null)
955 return new IntConstant (lic.Value << lshift_val);
958 if ((luic = left.ConvertToUInt ()) != null)
959 return new UIntConstant (luic.Value << lshift_val);
962 if ((llc = left.ConvertToLong ()) != null)
963 return new LongConstant (llc.Value << lshift_val);
966 if ((lulc = left.ConvertToULong ()) != null)
967 return new ULongConstant (lulc.Value << lshift_val);
969 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
973 // There is no overflow checking on right shift
975 case Binary.Operator.RightShift:
976 IntConstant sic = right.ToInt (loc);
978 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
981 int rshift_val = sic.Value;
984 if ((ric = left.ConvertToInt ()) != null)
985 return new IntConstant (ric.Value >> rshift_val);
988 if ((ruic = left.ConvertToUInt ()) != null)
989 return new UIntConstant (ruic.Value >> rshift_val);
992 if ((rlc = left.ConvertToLong ()) != null)
993 return new LongConstant (rlc.Value >> rshift_val);
996 if ((rulc = left.ConvertToULong ()) != null)
997 return new ULongConstant (rulc.Value >> rshift_val);
999 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1002 case Binary.Operator.LogicalAnd:
1003 if (left is BoolConstant && right is BoolConstant){
1004 return new BoolConstant (
1005 ((BoolConstant) left).Value &&
1006 ((BoolConstant) right).Value);
1010 case Binary.Operator.LogicalOr:
1011 if (left is BoolConstant && right is BoolConstant){
1012 return new BoolConstant (
1013 ((BoolConstant) left).Value ||
1014 ((BoolConstant) right).Value);
1018 case Binary.Operator.Equality:
1019 if (left is BoolConstant && right is BoolConstant){
1020 return new BoolConstant (
1021 ((BoolConstant) left).Value ==
1022 ((BoolConstant) right).Value);
1025 if (left is NullLiteral){
1026 if (right is NullLiteral)
1027 return new BoolConstant (true);
1028 else if (right is StringConstant)
1029 return new BoolConstant (
1030 ((StringConstant) right).Value == null);
1031 } else if (right is NullLiteral){
1032 if (left is NullLiteral)
1033 return new BoolConstant (true);
1034 else if (left is StringConstant)
1035 return new BoolConstant (
1036 ((StringConstant) left).Value == null);
1038 if (left is StringConstant && right is StringConstant){
1039 return new BoolConstant (
1040 ((StringConstant) left).Value ==
1041 ((StringConstant) right).Value);
1045 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1046 if (left == null || right == null)
1050 if (left is DoubleConstant)
1051 bool_res = ((DoubleConstant) left).Value ==
1052 ((DoubleConstant) right).Value;
1053 else if (left is FloatConstant)
1054 bool_res = ((FloatConstant) left).Value ==
1055 ((FloatConstant) right).Value;
1056 else if (left is ULongConstant)
1057 bool_res = ((ULongConstant) left).Value ==
1058 ((ULongConstant) right).Value;
1059 else if (left is LongConstant)
1060 bool_res = ((LongConstant) left).Value ==
1061 ((LongConstant) right).Value;
1062 else if (left is UIntConstant)
1063 bool_res = ((UIntConstant) left).Value ==
1064 ((UIntConstant) right).Value;
1065 else if (left is IntConstant)
1066 bool_res = ((IntConstant) left).Value ==
1067 ((IntConstant) right).Value;
1071 return new BoolConstant (bool_res);
1073 case Binary.Operator.Inequality:
1074 if (left is BoolConstant && right is BoolConstant){
1075 return new BoolConstant (
1076 ((BoolConstant) left).Value !=
1077 ((BoolConstant) right).Value);
1079 if (left is NullLiteral){
1080 if (right is NullLiteral)
1081 return new BoolConstant (false);
1082 else if (right is StringConstant)
1083 return new BoolConstant (
1084 ((StringConstant) right).Value != null);
1085 } else if (right is NullLiteral){
1086 if (left is NullLiteral)
1087 return new BoolConstant (false);
1088 else if (left is StringConstant)
1089 return new BoolConstant (
1090 ((StringConstant) left).Value != null);
1092 if (left is StringConstant && right is StringConstant){
1093 return new BoolConstant (
1094 ((StringConstant) left).Value !=
1095 ((StringConstant) right).Value);
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.LessThan:
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);
1155 case Binary.Operator.GreaterThan:
1156 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1157 if (left == null || right == null)
1161 if (left is DoubleConstant)
1162 bool_res = ((DoubleConstant) left).Value >
1163 ((DoubleConstant) right).Value;
1164 else if (left is FloatConstant)
1165 bool_res = ((FloatConstant) left).Value >
1166 ((FloatConstant) right).Value;
1167 else if (left is ULongConstant)
1168 bool_res = ((ULongConstant) left).Value >
1169 ((ULongConstant) right).Value;
1170 else if (left is LongConstant)
1171 bool_res = ((LongConstant) left).Value >
1172 ((LongConstant) right).Value;
1173 else if (left is UIntConstant)
1174 bool_res = ((UIntConstant) left).Value >
1175 ((UIntConstant) right).Value;
1176 else if (left is IntConstant)
1177 bool_res = ((IntConstant) left).Value >
1178 ((IntConstant) right).Value;
1182 return new BoolConstant (bool_res);
1184 case Binary.Operator.GreaterThanOrEqual:
1185 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1186 if (left == null || right == null)
1190 if (left is DoubleConstant)
1191 bool_res = ((DoubleConstant) left).Value >=
1192 ((DoubleConstant) right).Value;
1193 else if (left is FloatConstant)
1194 bool_res = ((FloatConstant) left).Value >=
1195 ((FloatConstant) right).Value;
1196 else if (left is ULongConstant)
1197 bool_res = ((ULongConstant) left).Value >=
1198 ((ULongConstant) right).Value;
1199 else if (left is LongConstant)
1200 bool_res = ((LongConstant) left).Value >=
1201 ((LongConstant) right).Value;
1202 else if (left is UIntConstant)
1203 bool_res = ((UIntConstant) left).Value >=
1204 ((UIntConstant) right).Value;
1205 else if (left is IntConstant)
1206 bool_res = ((IntConstant) left).Value >=
1207 ((IntConstant) right).Value;
1211 return new BoolConstant (bool_res);
1213 case Binary.Operator.LessThanOrEqual:
1214 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1215 if (left == null || right == null)
1219 if (left is DoubleConstant)
1220 bool_res = ((DoubleConstant) left).Value <=
1221 ((DoubleConstant) right).Value;
1222 else if (left is FloatConstant)
1223 bool_res = ((FloatConstant) left).Value <=
1224 ((FloatConstant) right).Value;
1225 else if (left is ULongConstant)
1226 bool_res = ((ULongConstant) left).Value <=
1227 ((ULongConstant) right).Value;
1228 else if (left is LongConstant)
1229 bool_res = ((LongConstant) left).Value <=
1230 ((LongConstant) right).Value;
1231 else if (left is UIntConstant)
1232 bool_res = ((UIntConstant) left).Value <=
1233 ((UIntConstant) right).Value;
1234 else if (left is IntConstant)
1235 bool_res = ((IntConstant) left).Value <=
1236 ((IntConstant) right).Value;
1240 return new BoolConstant (bool_res);