2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // (C) 2002, 2003 Ximian, Inc.
13 namespace Mono.CSharp {
15 public class ConstantFold {
18 // Performs the numeric promotions on the left and right expresions
19 // and desposits the results on `lc' and `rc'.
21 // On success, the types of `lc' and `rc' on output will always match,
22 // and the pair will be one of:
30 // (short, short) (Happens with enumerations with underlying short type)
31 // (ushort, ushort) (Happens with enumerations with underlying short type)
33 static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
34 ref Constant left, ref Constant right,
37 if (left is DoubleConstant || right is DoubleConstant){
39 // If either side is a double, convert the other to a double
41 if (!(left is DoubleConstant))
42 left = left.ToDouble (loc);
44 if (!(right is DoubleConstant))
45 right = right.ToDouble (loc);
47 } else if (left is FloatConstant || right is FloatConstant) {
49 // If either side is a float, convert the other to a float
51 if (!(left is FloatConstant))
52 left = left.ToFloat (loc);
54 if (!(right is FloatConstant))
55 right = right.ToFloat (loc);
57 } else if (left is ULongConstant || right is ULongConstant){
59 // If either operand is of type ulong, the other operand is
60 // converted to type ulong. or an error ocurrs if the other
61 // operand is of type sbyte, short, int or long
64 Constant match, other;
67 if (left is ULongConstant){
72 if (!(right is ULongConstant))
73 right = right.ToULong (loc);
79 left = left.ToULong (loc);
83 if (other is SByteConstant || other is ShortConstant ||
84 other is IntConstant || other is LongConstant){
85 Binary.Error_OperatorAmbiguous
86 (loc, oper, other.Type, match.Type);
92 } else if (left is LongConstant || right is LongConstant){
94 // If either operand is of type long, the other operand is converted
97 if (!(left is LongConstant))
98 left = left.ToLong (loc);
99 else if (!(right is LongConstant))
100 right = right.ToLong (loc);
102 } else if (left is UIntConstant || right is UIntConstant){
104 // If either operand is of type uint, and the other
105 // operand is of type sbyte, short or int, the operands are
106 // converted to type long.
109 if (left is UIntConstant)
115 if (other is UIntConstant)
118 IntConstant ic = other as IntConstant;
122 left = new UIntConstant ((uint) ic.Value, ic.Location);
124 right = new UIntConstant ((uint) ic.Value, ic.Location);
129 if (other is SByteConstant || other is ShortConstant || ic != null){
130 left = left.ToLong (loc);
131 right = right.ToLong (loc);
133 left = left.ToUInt (loc);
134 right = left.ToUInt (loc);
138 } else if (left is DecimalConstant || right is DecimalConstant) {
139 if (!(left is DecimalConstant))
140 left = left.ToDecimal (loc);
141 else if (!(right is DecimalConstant))
142 right = right.ToDecimal (loc);
144 } else if (left is EnumConstant || right is EnumConstant){
145 if (left is EnumConstant)
146 left = ((EnumConstant) left).Child;
147 if (right is EnumConstant)
148 right = ((EnumConstant) right).Child;
150 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
155 // Force conversions to int32
157 if (!(left is IntConstant))
158 left = left.ToInt (loc);
159 if (!(right is IntConstant))
160 right = right.ToInt (loc);
165 internal static void Error_CompileTimeOverflow (Location loc)
167 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
171 /// Constant expression folder for binary operations.
173 /// Returns null if the expression can not be folded.
175 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
176 Constant left, Constant right, Location loc)
178 if (left is EmptyConstantCast)
179 return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);
181 if (right is EmptyConstantCast)
182 return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);
185 Type rt = right.Type;
186 Type result_type = null;
190 // Enumerator folding
192 if (rt == lt && left is EnumConstant)
196 // During an enum evaluation, we need to unwrap enumerations
198 if (ec.InEnumContext){
199 if (left is EnumConstant)
200 left = ((EnumConstant) left).Child;
202 if (right is EnumConstant)
203 right = ((EnumConstant) right).Child;
206 if (left is BoolConstant && right is BoolConstant) {
207 bool lv = ((BoolConstant) left ).Value;
208 bool rv = ((BoolConstant) right).Value;
210 case Binary.Operator.BitwiseAnd:
211 case Binary.Operator.LogicalAnd:
212 return new BoolConstant (lv && rv, left.Location);
213 case Binary.Operator.BitwiseOr:
214 case Binary.Operator.LogicalOr:
215 return new BoolConstant (lv || rv, left.Location);
216 case Binary.Operator.ExclusiveOr:
217 return new BoolConstant (lv ^ rv, left.Location);
218 case Binary.Operator.Equality:
219 return new BoolConstant (lv == rv, left.Location);
220 case Binary.Operator.Inequality:
221 return new BoolConstant (lv != rv, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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, left.Location);
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){
454 right = right.ToType (((EnumConstant) left).Child.Type);
459 } else if (right is EnumConstant){
460 left = left.ToType (((EnumConstant) right).Child.Type);
464 wrap_as = right.Type;
468 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
469 if (left == null || right == null)
473 if (left is DoubleConstant){
476 if (ec.ConstantCheckState)
477 res = checked (((DoubleConstant) left).Value +
478 ((DoubleConstant) right).Value);
480 res = unchecked (((DoubleConstant) left).Value +
481 ((DoubleConstant) right).Value);
483 result = new DoubleConstant (res, left.Location);
484 } else if (left is FloatConstant){
487 if (ec.ConstantCheckState)
488 res = checked (((FloatConstant) left).Value +
489 ((FloatConstant) right).Value);
491 res = unchecked (((FloatConstant) left).Value +
492 ((FloatConstant) right).Value);
494 result = new FloatConstant (res, left.Location);
495 } else if (left is ULongConstant){
498 if (ec.ConstantCheckState)
499 res = checked (((ULongConstant) left).Value +
500 ((ULongConstant) right).Value);
502 res = unchecked (((ULongConstant) left).Value +
503 ((ULongConstant) right).Value);
505 result = new ULongConstant (res, left.Location);
506 } else if (left is LongConstant){
509 if (ec.ConstantCheckState)
510 res = checked (((LongConstant) left).Value +
511 ((LongConstant) right).Value);
513 res = unchecked (((LongConstant) left).Value +
514 ((LongConstant) right).Value);
516 result = new LongConstant (res, left.Location);
517 } else if (left is UIntConstant){
520 if (ec.ConstantCheckState)
521 res = checked (((UIntConstant) left).Value +
522 ((UIntConstant) right).Value);
524 res = unchecked (((UIntConstant) left).Value +
525 ((UIntConstant) right).Value);
527 result = new UIntConstant (res, left.Location);
528 } else if (left is IntConstant){
531 if (ec.ConstantCheckState)
532 res = checked (((IntConstant) left).Value +
533 ((IntConstant) right).Value);
535 res = unchecked (((IntConstant) left).Value +
536 ((IntConstant) right).Value);
538 result = new IntConstant (res, left.Location);
539 } else if (left is DecimalConstant) {
542 if (ec.ConstantCheckState)
543 res = checked (((DecimalConstant) left).Value +
544 ((DecimalConstant) right).Value);
546 res = unchecked (((DecimalConstant) left).Value +
547 ((DecimalConstant) right).Value);
549 result = new DecimalConstant (res, left.Location);
551 throw new Exception ( "Unexepected addition input: " + left);
553 } catch (OverflowException){
554 Error_CompileTimeOverflow (loc);
557 if (wrap_as != null) {
559 return result.TryReduce (ec, wrap_as, loc);
561 catch (OverflowException) {
568 case Binary.Operator.Subtraction:
570 // handle "E operator - (E x, U y)"
571 // handle "E operator - (Y y, E x)"
572 // handle "U operator - (E x, E y)"
575 if (left is EnumConstant){
576 if (right is EnumConstant){
577 if (left.Type != right.Type) {
578 Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
582 wrap_as = TypeManager.EnumToUnderlying (left.Type);
583 right = ((EnumConstant) right).Child.ToType (wrap_as);
587 left = ((EnumConstant) left).Child.ToType (wrap_as);
592 right = right.ToType (((EnumConstant) left).Child.Type);
598 } else if (right is EnumConstant){
599 left = left.ToType (((EnumConstant) right).Child.Type);
603 wrap_as = right.Type;
606 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
607 if (left == null || right == null)
611 if (left is DoubleConstant){
614 if (ec.ConstantCheckState)
615 res = checked (((DoubleConstant) left).Value -
616 ((DoubleConstant) right).Value);
618 res = unchecked (((DoubleConstant) left).Value -
619 ((DoubleConstant) right).Value);
621 result = new DoubleConstant (res, left.Location);
622 } else if (left is FloatConstant){
625 if (ec.ConstantCheckState)
626 res = checked (((FloatConstant) left).Value -
627 ((FloatConstant) right).Value);
629 res = unchecked (((FloatConstant) left).Value -
630 ((FloatConstant) right).Value);
632 result = new FloatConstant (res, left.Location);
633 } else if (left is ULongConstant){
636 if (ec.ConstantCheckState)
637 res = checked (((ULongConstant) left).Value -
638 ((ULongConstant) right).Value);
640 res = unchecked (((ULongConstant) left).Value -
641 ((ULongConstant) right).Value);
643 result = new ULongConstant (res, left.Location);
644 } else if (left is LongConstant){
647 if (ec.ConstantCheckState)
648 res = checked (((LongConstant) left).Value -
649 ((LongConstant) right).Value);
651 res = unchecked (((LongConstant) left).Value -
652 ((LongConstant) right).Value);
654 result = new LongConstant (res, left.Location);
655 } else if (left is UIntConstant){
658 if (ec.ConstantCheckState)
659 res = checked (((UIntConstant) left).Value -
660 ((UIntConstant) right).Value);
662 res = unchecked (((UIntConstant) left).Value -
663 ((UIntConstant) right).Value);
665 result = new UIntConstant (res, left.Location);
666 } else if (left is IntConstant){
669 if (ec.ConstantCheckState)
670 res = checked (((IntConstant) left).Value -
671 ((IntConstant) right).Value);
673 res = unchecked (((IntConstant) left).Value -
674 ((IntConstant) right).Value);
676 result = new IntConstant (res, left.Location);
677 } else if (left is DecimalConstant) {
680 if (ec.ConstantCheckState)
681 res = checked (((DecimalConstant) left).Value -
682 ((DecimalConstant) right).Value);
684 res = unchecked (((DecimalConstant) left).Value -
685 ((DecimalConstant) right).Value);
687 return new DecimalConstant (res, left.Location);
689 throw new Exception ( "Unexepected subtraction input: " + left);
691 } catch (OverflowException){
692 Error_CompileTimeOverflow (loc);
695 if (wrap_as != null) {
697 return result.TryReduce (ec, wrap_as, loc);
699 catch (OverflowException) {
706 case Binary.Operator.Multiply:
707 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
708 if (left == null || right == null)
712 if (left is DoubleConstant){
715 if (ec.ConstantCheckState)
716 res = checked (((DoubleConstant) left).Value *
717 ((DoubleConstant) right).Value);
719 res = unchecked (((DoubleConstant) left).Value *
720 ((DoubleConstant) right).Value);
722 return new DoubleConstant (res, left.Location);
723 } else if (left is FloatConstant){
726 if (ec.ConstantCheckState)
727 res = checked (((FloatConstant) left).Value *
728 ((FloatConstant) right).Value);
730 res = unchecked (((FloatConstant) left).Value *
731 ((FloatConstant) right).Value);
733 return new FloatConstant (res, left.Location);
734 } else if (left is ULongConstant){
737 if (ec.ConstantCheckState)
738 res = checked (((ULongConstant) left).Value *
739 ((ULongConstant) right).Value);
741 res = unchecked (((ULongConstant) left).Value *
742 ((ULongConstant) right).Value);
744 return new ULongConstant (res, left.Location);
745 } else if (left is LongConstant){
748 if (ec.ConstantCheckState)
749 res = checked (((LongConstant) left).Value *
750 ((LongConstant) right).Value);
752 res = unchecked (((LongConstant) left).Value *
753 ((LongConstant) right).Value);
755 return new LongConstant (res, left.Location);
756 } else if (left is UIntConstant){
759 if (ec.ConstantCheckState)
760 res = checked (((UIntConstant) left).Value *
761 ((UIntConstant) right).Value);
763 res = unchecked (((UIntConstant) left).Value *
764 ((UIntConstant) right).Value);
766 return new UIntConstant (res, left.Location);
767 } else if (left is IntConstant){
770 if (ec.ConstantCheckState)
771 res = checked (((IntConstant) left).Value *
772 ((IntConstant) right).Value);
774 res = unchecked (((IntConstant) left).Value *
775 ((IntConstant) right).Value);
777 return new IntConstant (res, left.Location);
778 } else if (left is DecimalConstant) {
781 if (ec.ConstantCheckState)
782 res = checked (((DecimalConstant) left).Value *
783 ((DecimalConstant) right).Value);
785 res = unchecked (((DecimalConstant) left).Value *
786 ((DecimalConstant) right).Value);
788 return new DecimalConstant (res, left.Location);
790 throw new Exception ( "Unexepected multiply input: " + left);
792 } catch (OverflowException){
793 Error_CompileTimeOverflow (loc);
797 case Binary.Operator.Division:
798 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
799 if (left == null || right == null)
803 if (left is DoubleConstant){
806 if (ec.ConstantCheckState)
807 res = checked (((DoubleConstant) left).Value /
808 ((DoubleConstant) right).Value);
810 res = unchecked (((DoubleConstant) left).Value /
811 ((DoubleConstant) right).Value);
813 return new DoubleConstant (res, left.Location);
814 } else if (left is FloatConstant){
817 if (ec.ConstantCheckState)
818 res = checked (((FloatConstant) left).Value /
819 ((FloatConstant) right).Value);
821 res = unchecked (((FloatConstant) left).Value /
822 ((FloatConstant) right).Value);
824 return new FloatConstant (res, left.Location);
825 } else if (left is ULongConstant){
828 if (ec.ConstantCheckState)
829 res = checked (((ULongConstant) left).Value /
830 ((ULongConstant) right).Value);
832 res = unchecked (((ULongConstant) left).Value /
833 ((ULongConstant) right).Value);
835 return new ULongConstant (res, left.Location);
836 } else if (left is LongConstant){
839 if (ec.ConstantCheckState)
840 res = checked (((LongConstant) left).Value /
841 ((LongConstant) right).Value);
843 res = unchecked (((LongConstant) left).Value /
844 ((LongConstant) right).Value);
846 return new LongConstant (res, left.Location);
847 } else if (left is UIntConstant){
850 if (ec.ConstantCheckState)
851 res = checked (((UIntConstant) left).Value /
852 ((UIntConstant) right).Value);
854 res = unchecked (((UIntConstant) left).Value /
855 ((UIntConstant) right).Value);
857 return new UIntConstant (res, left.Location);
858 } else if (left is IntConstant){
861 if (ec.ConstantCheckState)
862 res = checked (((IntConstant) left).Value /
863 ((IntConstant) right).Value);
865 res = unchecked (((IntConstant) left).Value /
866 ((IntConstant) right).Value);
868 return new IntConstant (res, left.Location);
869 } else if (left is DecimalConstant) {
872 if (ec.ConstantCheckState)
873 res = checked (((DecimalConstant) left).Value /
874 ((DecimalConstant) right).Value);
876 res = unchecked (((DecimalConstant) left).Value /
877 ((DecimalConstant) right).Value);
879 return new DecimalConstant (res, left.Location);
881 throw new Exception ( "Unexepected division input: " + left);
883 } catch (OverflowException){
884 Error_CompileTimeOverflow (loc);
886 } catch (DivideByZeroException) {
887 Report.Error (020, loc, "Division by constant zero");
892 case Binary.Operator.Modulus:
893 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
894 if (left == null || right == null)
898 if (left is DoubleConstant){
901 if (ec.ConstantCheckState)
902 res = checked (((DoubleConstant) left).Value %
903 ((DoubleConstant) right).Value);
905 res = unchecked (((DoubleConstant) left).Value %
906 ((DoubleConstant) right).Value);
908 return new DoubleConstant (res, left.Location);
909 } else if (left is FloatConstant){
912 if (ec.ConstantCheckState)
913 res = checked (((FloatConstant) left).Value %
914 ((FloatConstant) right).Value);
916 res = unchecked (((FloatConstant) left).Value %
917 ((FloatConstant) right).Value);
919 return new FloatConstant (res, left.Location);
920 } else if (left is ULongConstant){
923 if (ec.ConstantCheckState)
924 res = checked (((ULongConstant) left).Value %
925 ((ULongConstant) right).Value);
927 res = unchecked (((ULongConstant) left).Value %
928 ((ULongConstant) right).Value);
930 return new ULongConstant (res, left.Location);
931 } else if (left is LongConstant){
934 if (ec.ConstantCheckState)
935 res = checked (((LongConstant) left).Value %
936 ((LongConstant) right).Value);
938 res = unchecked (((LongConstant) left).Value %
939 ((LongConstant) right).Value);
941 return new LongConstant (res, left.Location);
942 } else if (left is UIntConstant){
945 if (ec.ConstantCheckState)
946 res = checked (((UIntConstant) left).Value %
947 ((UIntConstant) right).Value);
949 res = unchecked (((UIntConstant) left).Value %
950 ((UIntConstant) right).Value);
952 return new UIntConstant (res, left.Location);
953 } else if (left is IntConstant){
956 if (ec.ConstantCheckState)
957 res = checked (((IntConstant) left).Value %
958 ((IntConstant) right).Value);
960 res = unchecked (((IntConstant) left).Value %
961 ((IntConstant) right).Value);
963 return new IntConstant (res, left.Location);
965 throw new Exception ( "Unexepected modulus input: " + left);
967 } catch (DivideByZeroException){
968 Report.Error (020, loc, "Division by constant zero");
969 } catch (OverflowException){
970 Error_CompileTimeOverflow (loc);
975 // There is no overflow checking on left shift
977 case Binary.Operator.LeftShift:
978 IntConstant ic = right.ToInt (loc);
980 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
983 int lshift_val = ic.Value;
986 if ((lic = left.ConvertToInt ()) != null)
987 return new IntConstant (lic.Value << lshift_val, left.Location);
990 if ((luic = left.ConvertToUInt ()) != null)
991 return new UIntConstant (luic.Value << lshift_val, left.Location);
994 if ((llc = left.ConvertToLong ()) != null)
995 return new LongConstant (llc.Value << lshift_val, left.Location);
998 if ((lulc = left.ConvertToULong ()) != null)
999 return new ULongConstant (lulc.Value << lshift_val, left.Location);
1001 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
1005 // There is no overflow checking on right shift
1007 case Binary.Operator.RightShift:
1008 IntConstant sic = right.ToInt (loc);
1010 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1013 int rshift_val = sic.Value;
1016 if ((ric = left.ConvertToInt ()) != null)
1017 return new IntConstant (ric.Value >> rshift_val, left.Location);
1020 if ((ruic = left.ConvertToUInt ()) != null)
1021 return new UIntConstant (ruic.Value >> rshift_val, left.Location);
1024 if ((rlc = left.ConvertToLong ()) != null)
1025 return new LongConstant (rlc.Value >> rshift_val, left.Location);
1028 if ((rulc = left.ConvertToULong ()) != null)
1029 return new ULongConstant (rulc.Value >> rshift_val, left.Location);
1031 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1034 case Binary.Operator.Equality:
1035 if (left is NullConstant){
1036 if (right is NullConstant)
1037 return new BoolConstant (true, left.Location);
1038 else if (right is StringConstant)
1039 return new BoolConstant (
1040 ((StringConstant) right).Value == null, left.Location);
1041 } else if (right is NullConstant){
1042 if (left is NullConstant)
1043 return new BoolConstant (true, left.Location);
1044 else if (left is StringConstant)
1045 return new BoolConstant (
1046 ((StringConstant) left).Value == null, left.Location);
1048 if (left is StringConstant && right is StringConstant){
1049 return new BoolConstant (
1050 ((StringConstant) left).Value ==
1051 ((StringConstant) right).Value, left.Location);
1055 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1056 if (left == null || right == null)
1060 if (left is DoubleConstant)
1061 bool_res = ((DoubleConstant) left).Value ==
1062 ((DoubleConstant) right).Value;
1063 else if (left is FloatConstant)
1064 bool_res = ((FloatConstant) left).Value ==
1065 ((FloatConstant) right).Value;
1066 else if (left is ULongConstant)
1067 bool_res = ((ULongConstant) left).Value ==
1068 ((ULongConstant) right).Value;
1069 else if (left is LongConstant)
1070 bool_res = ((LongConstant) left).Value ==
1071 ((LongConstant) right).Value;
1072 else if (left is UIntConstant)
1073 bool_res = ((UIntConstant) left).Value ==
1074 ((UIntConstant) right).Value;
1075 else if (left is IntConstant)
1076 bool_res = ((IntConstant) left).Value ==
1077 ((IntConstant) right).Value;
1081 return new BoolConstant (bool_res, left.Location);
1083 case Binary.Operator.Inequality:
1084 if (left is NullConstant){
1085 if (right is NullConstant)
1086 return new BoolConstant (false, left.Location);
1087 else if (right is StringConstant)
1088 return new BoolConstant (
1089 ((StringConstant) right).Value != null, left.Location);
1090 } else if (right is NullConstant){
1091 if (left is NullConstant)
1092 return new BoolConstant (false, left.Location);
1093 else if (left is StringConstant)
1094 return new BoolConstant (
1095 ((StringConstant) left).Value != null, left.Location);
1097 if (left is StringConstant && right is StringConstant){
1098 return new BoolConstant (
1099 ((StringConstant) left).Value !=
1100 ((StringConstant) right).Value, left.Location);
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, left.Location);
1131 case Binary.Operator.LessThan:
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, left.Location);
1160 case Binary.Operator.GreaterThan:
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, left.Location);
1189 case Binary.Operator.GreaterThanOrEqual:
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, left.Location);
1218 case Binary.Operator.LessThanOrEqual:
1219 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1220 if (left == null || right == null)
1224 if (left is DoubleConstant)
1225 bool_res = ((DoubleConstant) left).Value <=
1226 ((DoubleConstant) right).Value;
1227 else if (left is FloatConstant)
1228 bool_res = ((FloatConstant) left).Value <=
1229 ((FloatConstant) right).Value;
1230 else if (left is ULongConstant)
1231 bool_res = ((ULongConstant) left).Value <=
1232 ((ULongConstant) right).Value;
1233 else if (left is LongConstant)
1234 bool_res = ((LongConstant) left).Value <=
1235 ((LongConstant) right).Value;
1236 else if (left is UIntConstant)
1237 bool_res = ((UIntConstant) left).Value <=
1238 ((UIntConstant) right).Value;
1239 else if (left is IntConstant)
1240 bool_res = ((IntConstant) left).Value <=
1241 ((IntConstant) right).Value;
1245 return new BoolConstant (bool_res, left.Location);