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, ic.Location);
123 right = new UIntConstant ((uint) ic.Value, ic.Location);
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){
144 if (left is EnumConstant)
145 left = ((EnumConstant) left).Child;
146 if (right is EnumConstant)
147 right = ((EnumConstant) right).Child;
149 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
154 // Force conversions to int32
156 if (!(left is IntConstant))
157 left = left.ToInt (loc);
158 if (!(right is IntConstant))
159 right = right.ToInt (loc);
164 static void Error_CompileTimeOverflow (Location loc)
166 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
170 /// Constant expression folder for binary operations.
172 /// Returns null if the expression can not be folded.
174 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
175 Constant left, Constant right, Location loc)
177 if (left is NullCast)
178 return BinaryFold (ec, oper, ((NullCast)left).child, right, loc);
180 if (right is NullCast)
181 return BinaryFold (ec, oper, left, ((NullCast)right).child, loc);
184 Type rt = right.Type;
185 Type result_type = null;
189 // Enumerator folding
191 if (rt == lt && left is EnumConstant)
195 // During an enum evaluation, we need to unwrap enumerations
197 if (ec.InEnumContext){
198 if (left is EnumConstant)
199 left = ((EnumConstant) left).Child;
201 if (right is EnumConstant)
202 right = ((EnumConstant) right).Child;
206 Constant result = null;
208 case Binary.Operator.BitwiseOr:
209 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
210 if (left == null || right == null)
213 if (left is IntConstant){
215 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
217 v = new IntConstant (res, left.Location);
218 if (result_type == null)
221 return new EnumConstant (v, result_type);
222 } else if (left is UIntConstant){
224 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
226 v = new UIntConstant (res, left.Location);
227 if (result_type == null)
230 return new EnumConstant (v, result_type);
231 } else if (left is LongConstant){
233 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
235 v = new LongConstant (res, left.Location);
236 if (result_type == null)
239 return new EnumConstant (v, result_type);
240 } else if (left is ULongConstant){
242 ulong res = ((ULongConstant)left).Value |
243 ((ULongConstant)right).Value;
245 v = new ULongConstant (res, left.Location);
246 if (result_type == null)
249 return new EnumConstant (v, result_type);
250 } else if (left is UShortConstant){
252 ushort res = (ushort) (((UShortConstant)left).Value |
253 ((UShortConstant)right).Value);
255 v = new UShortConstant (res, left.Location);
256 if (result_type == null)
259 return new EnumConstant (v, result_type);
260 } else if (left is ShortConstant){
262 short res = (short) (((ShortConstant)left).Value |
263 ((ShortConstant)right).Value);
265 v = new ShortConstant (res, left.Location);
266 if (result_type == null)
269 return new EnumConstant (v, result_type);
273 case Binary.Operator.BitwiseAnd:
274 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
275 if (left == null || right == null)
278 if (left is IntConstant){
280 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
282 v = new IntConstant (res, left.Location);
283 if (result_type == null)
286 return new EnumConstant (v, result_type);
287 } else if (left is UIntConstant){
289 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
291 v = new UIntConstant (res, left.Location);
292 if (result_type == null)
295 return new EnumConstant (v, result_type);
296 } else if (left is LongConstant){
298 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
300 v = new LongConstant (res, left.Location);
301 if (result_type == null)
304 return new EnumConstant (v, result_type);
305 } else if (left is ULongConstant){
307 ulong res = ((ULongConstant)left).Value &
308 ((ULongConstant)right).Value;
310 v = new ULongConstant (res, left.Location);
311 if (result_type == null)
314 return new EnumConstant (v, result_type);
315 } else if (left is UShortConstant){
317 ushort res = (ushort) (((UShortConstant)left).Value &
318 ((UShortConstant)right).Value);
320 v = new UShortConstant (res, left.Location);
321 if (result_type == null)
324 return new EnumConstant (v, result_type);
325 } else if (left is ShortConstant){
327 short res = (short) (((ShortConstant)left).Value &
328 ((ShortConstant)right).Value);
330 v = new ShortConstant (res, left.Location);
331 if (result_type == null)
334 return new EnumConstant (v, result_type);
338 case Binary.Operator.ExclusiveOr:
339 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
340 if (left == null || right == null)
343 if (left is IntConstant){
345 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
347 v = new IntConstant (res, left.Location);
348 if (result_type == null)
351 return new EnumConstant (v, result_type);
352 } else if (left is UIntConstant){
354 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
356 v = new UIntConstant (res, left.Location);
357 if (result_type == null)
360 return new EnumConstant (v, result_type);
361 } else if (left is LongConstant){
363 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
365 v = new LongConstant (res, left.Location);
366 if (result_type == null)
369 return new EnumConstant (v, result_type);
370 } else if (left is ULongConstant){
372 ulong res = ((ULongConstant)left).Value ^
373 ((ULongConstant)right).Value;
375 v = new ULongConstant (res, left.Location);
376 if (result_type == null)
379 return new EnumConstant (v, result_type);
380 } else if (left is UShortConstant){
382 ushort res = (ushort) (((UShortConstant)left).Value ^
383 ((UShortConstant)right).Value);
385 v = new UShortConstant (res, left.Location);
386 if (result_type == null)
389 return new EnumConstant (v, result_type);
390 } else if (left is ShortConstant){
392 short res = (short)(((ShortConstant)left).Value ^
393 ((ShortConstant)right).Value);
395 v = new ShortConstant (res, left.Location);
396 if (result_type == null)
399 return new EnumConstant (v, result_type);
403 case Binary.Operator.Addition:
404 bool left_is_string = left is StringConstant;
405 bool right_is_string = right is StringConstant;
408 // If both sides are strings, then concatenate, if
409 // one is a string, and the other is not, then defer
410 // to runtime concatenation
413 if (left_is_string || right_is_string){
414 if (left_is_string && right_is_string)
415 return new StringConstant (
416 ((StringConstant) left).Value +
417 ((StringConstant) right).Value, left.Location);
423 // handle "E operator + (E x, U y)"
424 // handle "E operator + (Y y, E x)"
426 // note that E operator + (E x, E y) is invalid
428 if (left is EnumConstant){
429 if (right is EnumConstant){
433 right = right.ToType (((EnumConstant) left).Child.Type, loc);
438 } else if (right is EnumConstant){
439 left = left.ToType (((EnumConstant) right).Child.Type, loc);
443 wrap_as = right.Type;
447 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
448 if (left == null || right == null)
452 if (left is DoubleConstant){
455 if (ec.ConstantCheckState)
456 res = checked (((DoubleConstant) left).Value +
457 ((DoubleConstant) right).Value);
459 res = unchecked (((DoubleConstant) left).Value +
460 ((DoubleConstant) right).Value);
462 result = new DoubleConstant (res, left.Location);
463 } else if (left is FloatConstant){
466 if (ec.ConstantCheckState)
467 res = checked (((FloatConstant) left).Value +
468 ((FloatConstant) right).Value);
470 res = unchecked (((FloatConstant) left).Value +
471 ((FloatConstant) right).Value);
473 result = new FloatConstant (res, left.Location);
474 } else if (left is ULongConstant){
477 if (ec.ConstantCheckState)
478 res = checked (((ULongConstant) left).Value +
479 ((ULongConstant) right).Value);
481 res = unchecked (((ULongConstant) left).Value +
482 ((ULongConstant) right).Value);
484 result = new ULongConstant (res, left.Location);
485 } else if (left is LongConstant){
488 if (ec.ConstantCheckState)
489 res = checked (((LongConstant) left).Value +
490 ((LongConstant) right).Value);
492 res = unchecked (((LongConstant) left).Value +
493 ((LongConstant) right).Value);
495 result = new LongConstant (res, left.Location);
496 } else if (left is UIntConstant){
499 if (ec.ConstantCheckState)
500 res = checked (((UIntConstant) left).Value +
501 ((UIntConstant) right).Value);
503 res = unchecked (((UIntConstant) left).Value +
504 ((UIntConstant) right).Value);
506 result = new UIntConstant (res, left.Location);
507 } else if (left is IntConstant){
510 if (ec.ConstantCheckState)
511 res = checked (((IntConstant) left).Value +
512 ((IntConstant) right).Value);
514 res = unchecked (((IntConstant) left).Value +
515 ((IntConstant) right).Value);
517 result = new IntConstant (res, left.Location);
518 } else if (left is DecimalConstant) {
521 if (ec.ConstantCheckState)
522 res = checked (((DecimalConstant) left).Value +
523 ((DecimalConstant) right).Value);
525 res = unchecked (((DecimalConstant) left).Value +
526 ((DecimalConstant) right).Value);
528 result = new DecimalConstant (res, left.Location);
530 throw new Exception ( "Unexepected addition input: " + left);
532 } catch (OverflowException){
533 Error_CompileTimeOverflow (loc);
537 return result.TryReduce (ec, wrap_as, loc);
541 case Binary.Operator.Subtraction:
543 // handle "E operator - (E x, U y)"
544 // handle "E operator - (Y y, E x)"
545 // handle "U operator - (E x, E y)"
548 if (left is EnumConstant){
549 if (right is EnumConstant){
550 if (left.Type != right.Type) {
551 Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
555 wrap_as = TypeManager.EnumToUnderlying (left.Type);
556 right = ((EnumConstant) right).Child.ToType (wrap_as, loc);
560 left = ((EnumConstant) left).Child.ToType (wrap_as, loc);
565 right = right.ToType (((EnumConstant) left).Child.Type, loc);
571 } else if (right is EnumConstant){
572 left = left.ToType (((EnumConstant) right).Child.Type, loc);
576 wrap_as = right.Type;
579 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
580 if (left == null || right == null)
584 if (left is DoubleConstant){
587 if (ec.ConstantCheckState)
588 res = checked (((DoubleConstant) left).Value -
589 ((DoubleConstant) right).Value);
591 res = unchecked (((DoubleConstant) left).Value -
592 ((DoubleConstant) right).Value);
594 result = new DoubleConstant (res, left.Location);
595 } else if (left is FloatConstant){
598 if (ec.ConstantCheckState)
599 res = checked (((FloatConstant) left).Value -
600 ((FloatConstant) right).Value);
602 res = unchecked (((FloatConstant) left).Value -
603 ((FloatConstant) right).Value);
605 result = new FloatConstant (res, left.Location);
606 } else if (left is ULongConstant){
609 if (ec.ConstantCheckState)
610 res = checked (((ULongConstant) left).Value -
611 ((ULongConstant) right).Value);
613 res = unchecked (((ULongConstant) left).Value -
614 ((ULongConstant) right).Value);
616 result = new ULongConstant (res, left.Location);
617 } else if (left is LongConstant){
620 if (ec.ConstantCheckState)
621 res = checked (((LongConstant) left).Value -
622 ((LongConstant) right).Value);
624 res = unchecked (((LongConstant) left).Value -
625 ((LongConstant) right).Value);
627 result = new LongConstant (res, left.Location);
628 } else if (left is UIntConstant){
631 if (ec.ConstantCheckState)
632 res = checked (((UIntConstant) left).Value -
633 ((UIntConstant) right).Value);
635 res = unchecked (((UIntConstant) left).Value -
636 ((UIntConstant) right).Value);
638 result = new UIntConstant (res, left.Location);
639 } else if (left is IntConstant){
642 if (ec.ConstantCheckState)
643 res = checked (((IntConstant) left).Value -
644 ((IntConstant) right).Value);
646 res = unchecked (((IntConstant) left).Value -
647 ((IntConstant) right).Value);
649 result = new IntConstant (res, left.Location);
650 } else if (left is DecimalConstant) {
653 if (ec.ConstantCheckState)
654 res = checked (((DecimalConstant) left).Value -
655 ((DecimalConstant) right).Value);
657 res = unchecked (((DecimalConstant) left).Value -
658 ((DecimalConstant) right).Value);
660 return new DecimalConstant (res, left.Location);
662 throw new Exception ( "Unexepected subtraction input: " + left);
664 } catch (OverflowException){
665 Error_CompileTimeOverflow (loc);
669 return result.TryReduce (ec, wrap_as, loc);
673 case Binary.Operator.Multiply:
674 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
675 if (left == null || right == null)
679 if (left is DoubleConstant){
682 if (ec.ConstantCheckState)
683 res = checked (((DoubleConstant) left).Value *
684 ((DoubleConstant) right).Value);
686 res = unchecked (((DoubleConstant) left).Value *
687 ((DoubleConstant) right).Value);
689 return new DoubleConstant (res, left.Location);
690 } else if (left is FloatConstant){
693 if (ec.ConstantCheckState)
694 res = checked (((FloatConstant) left).Value *
695 ((FloatConstant) right).Value);
697 res = unchecked (((FloatConstant) left).Value *
698 ((FloatConstant) right).Value);
700 return new FloatConstant (res, left.Location);
701 } else if (left is ULongConstant){
704 if (ec.ConstantCheckState)
705 res = checked (((ULongConstant) left).Value *
706 ((ULongConstant) right).Value);
708 res = unchecked (((ULongConstant) left).Value *
709 ((ULongConstant) right).Value);
711 return new ULongConstant (res, left.Location);
712 } else if (left is LongConstant){
715 if (ec.ConstantCheckState)
716 res = checked (((LongConstant) left).Value *
717 ((LongConstant) right).Value);
719 res = unchecked (((LongConstant) left).Value *
720 ((LongConstant) right).Value);
722 return new LongConstant (res, left.Location);
723 } else if (left is UIntConstant){
726 if (ec.ConstantCheckState)
727 res = checked (((UIntConstant) left).Value *
728 ((UIntConstant) right).Value);
730 res = unchecked (((UIntConstant) left).Value *
731 ((UIntConstant) right).Value);
733 return new UIntConstant (res, left.Location);
734 } else if (left is IntConstant){
737 if (ec.ConstantCheckState)
738 res = checked (((IntConstant) left).Value *
739 ((IntConstant) right).Value);
741 res = unchecked (((IntConstant) left).Value *
742 ((IntConstant) right).Value);
744 return new IntConstant (res, left.Location);
745 } else if (left is DecimalConstant) {
748 if (ec.ConstantCheckState)
749 res = checked (((DecimalConstant) left).Value *
750 ((DecimalConstant) right).Value);
752 res = unchecked (((DecimalConstant) left).Value *
753 ((DecimalConstant) right).Value);
755 return new DecimalConstant (res, left.Location);
757 throw new Exception ( "Unexepected multiply input: " + left);
759 } catch (OverflowException){
760 Error_CompileTimeOverflow (loc);
764 case Binary.Operator.Division:
765 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
766 if (left == null || right == null)
770 if (left is DoubleConstant){
773 if (ec.ConstantCheckState)
774 res = checked (((DoubleConstant) left).Value /
775 ((DoubleConstant) right).Value);
777 res = unchecked (((DoubleConstant) left).Value /
778 ((DoubleConstant) right).Value);
780 return new DoubleConstant (res, left.Location);
781 } else if (left is FloatConstant){
784 if (ec.ConstantCheckState)
785 res = checked (((FloatConstant) left).Value /
786 ((FloatConstant) right).Value);
788 res = unchecked (((FloatConstant) left).Value /
789 ((FloatConstant) right).Value);
791 return new FloatConstant (res, left.Location);
792 } else if (left is ULongConstant){
795 if (ec.ConstantCheckState)
796 res = checked (((ULongConstant) left).Value /
797 ((ULongConstant) right).Value);
799 res = unchecked (((ULongConstant) left).Value /
800 ((ULongConstant) right).Value);
802 return new ULongConstant (res, left.Location);
803 } else if (left is LongConstant){
806 if (ec.ConstantCheckState)
807 res = checked (((LongConstant) left).Value /
808 ((LongConstant) right).Value);
810 res = unchecked (((LongConstant) left).Value /
811 ((LongConstant) right).Value);
813 return new LongConstant (res, left.Location);
814 } else if (left is UIntConstant){
817 if (ec.ConstantCheckState)
818 res = checked (((UIntConstant) left).Value /
819 ((UIntConstant) right).Value);
821 res = unchecked (((UIntConstant) left).Value /
822 ((UIntConstant) right).Value);
824 return new UIntConstant (res, left.Location);
825 } else if (left is IntConstant){
828 if (ec.ConstantCheckState)
829 res = checked (((IntConstant) left).Value /
830 ((IntConstant) right).Value);
832 res = unchecked (((IntConstant) left).Value /
833 ((IntConstant) right).Value);
835 return new IntConstant (res, left.Location);
836 } else if (left is DecimalConstant) {
839 if (ec.ConstantCheckState)
840 res = checked (((DecimalConstant) left).Value /
841 ((DecimalConstant) right).Value);
843 res = unchecked (((DecimalConstant) left).Value /
844 ((DecimalConstant) right).Value);
846 return new DecimalConstant (res, left.Location);
848 throw new Exception ( "Unexepected division input: " + left);
850 } catch (OverflowException){
851 Error_CompileTimeOverflow (loc);
853 } catch (DivideByZeroException) {
854 Report.Error (020, loc, "Division by constant zero");
859 case Binary.Operator.Modulus:
860 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
861 if (left == null || right == null)
865 if (left is DoubleConstant){
868 if (ec.ConstantCheckState)
869 res = checked (((DoubleConstant) left).Value %
870 ((DoubleConstant) right).Value);
872 res = unchecked (((DoubleConstant) left).Value %
873 ((DoubleConstant) right).Value);
875 return new DoubleConstant (res, left.Location);
876 } else if (left is FloatConstant){
879 if (ec.ConstantCheckState)
880 res = checked (((FloatConstant) left).Value %
881 ((FloatConstant) right).Value);
883 res = unchecked (((FloatConstant) left).Value %
884 ((FloatConstant) right).Value);
886 return new FloatConstant (res, left.Location);
887 } else if (left is ULongConstant){
890 if (ec.ConstantCheckState)
891 res = checked (((ULongConstant) left).Value %
892 ((ULongConstant) right).Value);
894 res = unchecked (((ULongConstant) left).Value %
895 ((ULongConstant) right).Value);
897 return new ULongConstant (res, left.Location);
898 } else if (left is LongConstant){
901 if (ec.ConstantCheckState)
902 res = checked (((LongConstant) left).Value %
903 ((LongConstant) right).Value);
905 res = unchecked (((LongConstant) left).Value %
906 ((LongConstant) right).Value);
908 return new LongConstant (res, left.Location);
909 } else if (left is UIntConstant){
912 if (ec.ConstantCheckState)
913 res = checked (((UIntConstant) left).Value %
914 ((UIntConstant) right).Value);
916 res = unchecked (((UIntConstant) left).Value %
917 ((UIntConstant) right).Value);
919 return new UIntConstant (res, left.Location);
920 } else if (left is IntConstant){
923 if (ec.ConstantCheckState)
924 res = checked (((IntConstant) left).Value %
925 ((IntConstant) right).Value);
927 res = unchecked (((IntConstant) left).Value %
928 ((IntConstant) right).Value);
930 return new IntConstant (res, left.Location);
932 throw new Exception ( "Unexepected modulus input: " + left);
934 } catch (DivideByZeroException){
935 Report.Error (020, loc, "Division by constant zero");
936 } catch (OverflowException){
937 Error_CompileTimeOverflow (loc);
942 // There is no overflow checking on left shift
944 case Binary.Operator.LeftShift:
945 IntConstant ic = right.ToInt (loc);
947 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
950 int lshift_val = ic.Value;
953 if ((lic = left.ConvertToInt ()) != null)
954 return new IntConstant (lic.Value << lshift_val, left.Location);
957 if ((luic = left.ConvertToUInt ()) != null)
958 return new UIntConstant (luic.Value << lshift_val, left.Location);
961 if ((llc = left.ConvertToLong ()) != null)
962 return new LongConstant (llc.Value << lshift_val, left.Location);
965 if ((lulc = left.ConvertToULong ()) != null)
966 return new ULongConstant (lulc.Value << lshift_val, left.Location);
968 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
972 // There is no overflow checking on right shift
974 case Binary.Operator.RightShift:
975 IntConstant sic = right.ToInt (loc);
977 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
980 int rshift_val = sic.Value;
983 if ((ric = left.ConvertToInt ()) != null)
984 return new IntConstant (ric.Value >> rshift_val, left.Location);
987 if ((ruic = left.ConvertToUInt ()) != null)
988 return new UIntConstant (ruic.Value >> rshift_val, left.Location);
991 if ((rlc = left.ConvertToLong ()) != null)
992 return new LongConstant (rlc.Value >> rshift_val, left.Location);
995 if ((rulc = left.ConvertToULong ()) != null)
996 return new ULongConstant (rulc.Value >> rshift_val, left.Location);
998 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1001 case Binary.Operator.LogicalAnd:
1002 if (left is BoolConstant && right is BoolConstant){
1003 return new BoolConstant (
1004 ((BoolConstant) left).Value &&
1005 ((BoolConstant) right).Value, left.Location);
1009 case Binary.Operator.LogicalOr:
1010 if (left is BoolConstant && right is BoolConstant){
1011 return new BoolConstant (
1012 ((BoolConstant) left).Value ||
1013 ((BoolConstant) right).Value, left.Location);
1017 case Binary.Operator.Equality:
1018 if (left is BoolConstant && right is BoolConstant){
1019 return new BoolConstant (
1020 ((BoolConstant) left).Value ==
1021 ((BoolConstant) right).Value, left.Location);
1024 if (left is NullLiteral){
1025 if (right is NullLiteral)
1026 return new BoolConstant (true, left.Location);
1027 else if (right is StringConstant)
1028 return new BoolConstant (
1029 ((StringConstant) right).Value == null, left.Location);
1030 } else if (right is NullLiteral){
1031 if (left is NullLiteral)
1032 return new BoolConstant (true, left.Location);
1033 else if (left is StringConstant)
1034 return new BoolConstant (
1035 ((StringConstant) left).Value == null, left.Location);
1037 if (left is StringConstant && right is StringConstant){
1038 return new BoolConstant (
1039 ((StringConstant) left).Value ==
1040 ((StringConstant) right).Value, left.Location);
1044 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1045 if (left == null || right == null)
1049 if (left is DoubleConstant)
1050 bool_res = ((DoubleConstant) left).Value ==
1051 ((DoubleConstant) right).Value;
1052 else if (left is FloatConstant)
1053 bool_res = ((FloatConstant) left).Value ==
1054 ((FloatConstant) right).Value;
1055 else if (left is ULongConstant)
1056 bool_res = ((ULongConstant) left).Value ==
1057 ((ULongConstant) right).Value;
1058 else if (left is LongConstant)
1059 bool_res = ((LongConstant) left).Value ==
1060 ((LongConstant) right).Value;
1061 else if (left is UIntConstant)
1062 bool_res = ((UIntConstant) left).Value ==
1063 ((UIntConstant) right).Value;
1064 else if (left is IntConstant)
1065 bool_res = ((IntConstant) left).Value ==
1066 ((IntConstant) right).Value;
1070 return new BoolConstant (bool_res, left.Location);
1072 case Binary.Operator.Inequality:
1073 if (left is BoolConstant && right is BoolConstant){
1074 return new BoolConstant (
1075 ((BoolConstant) left).Value !=
1076 ((BoolConstant) right).Value, left.Location);
1078 if (left is NullLiteral){
1079 if (right is NullLiteral)
1080 return new BoolConstant (false, left.Location);
1081 else if (right is StringConstant)
1082 return new BoolConstant (
1083 ((StringConstant) right).Value != null, left.Location);
1084 } else if (right is NullLiteral){
1085 if (left is NullLiteral)
1086 return new BoolConstant (false, left.Location);
1087 else if (left is StringConstant)
1088 return new BoolConstant (
1089 ((StringConstant) left).Value != null, left.Location);
1091 if (left is StringConstant && right is StringConstant){
1092 return new BoolConstant (
1093 ((StringConstant) left).Value !=
1094 ((StringConstant) right).Value, left.Location);
1097 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1098 if (left == null || right == null)
1102 if (left is DoubleConstant)
1103 bool_res = ((DoubleConstant) left).Value !=
1104 ((DoubleConstant) right).Value;
1105 else if (left is FloatConstant)
1106 bool_res = ((FloatConstant) left).Value !=
1107 ((FloatConstant) right).Value;
1108 else if (left is ULongConstant)
1109 bool_res = ((ULongConstant) left).Value !=
1110 ((ULongConstant) right).Value;
1111 else if (left is LongConstant)
1112 bool_res = ((LongConstant) left).Value !=
1113 ((LongConstant) right).Value;
1114 else if (left is UIntConstant)
1115 bool_res = ((UIntConstant) left).Value !=
1116 ((UIntConstant) right).Value;
1117 else if (left is IntConstant)
1118 bool_res = ((IntConstant) left).Value !=
1119 ((IntConstant) right).Value;
1123 return new BoolConstant (bool_res, left.Location);
1125 case Binary.Operator.LessThan:
1126 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1127 if (left == null || right == null)
1131 if (left is DoubleConstant)
1132 bool_res = ((DoubleConstant) left).Value <
1133 ((DoubleConstant) right).Value;
1134 else if (left is FloatConstant)
1135 bool_res = ((FloatConstant) left).Value <
1136 ((FloatConstant) right).Value;
1137 else if (left is ULongConstant)
1138 bool_res = ((ULongConstant) left).Value <
1139 ((ULongConstant) right).Value;
1140 else if (left is LongConstant)
1141 bool_res = ((LongConstant) left).Value <
1142 ((LongConstant) right).Value;
1143 else if (left is UIntConstant)
1144 bool_res = ((UIntConstant) left).Value <
1145 ((UIntConstant) right).Value;
1146 else if (left is IntConstant)
1147 bool_res = ((IntConstant) left).Value <
1148 ((IntConstant) right).Value;
1152 return new BoolConstant (bool_res, left.Location);
1154 case Binary.Operator.GreaterThan:
1155 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1156 if (left == null || right == null)
1160 if (left is DoubleConstant)
1161 bool_res = ((DoubleConstant) left).Value >
1162 ((DoubleConstant) right).Value;
1163 else if (left is FloatConstant)
1164 bool_res = ((FloatConstant) left).Value >
1165 ((FloatConstant) right).Value;
1166 else if (left is ULongConstant)
1167 bool_res = ((ULongConstant) left).Value >
1168 ((ULongConstant) right).Value;
1169 else if (left is LongConstant)
1170 bool_res = ((LongConstant) left).Value >
1171 ((LongConstant) right).Value;
1172 else if (left is UIntConstant)
1173 bool_res = ((UIntConstant) left).Value >
1174 ((UIntConstant) right).Value;
1175 else if (left is IntConstant)
1176 bool_res = ((IntConstant) left).Value >
1177 ((IntConstant) right).Value;
1181 return new BoolConstant (bool_res, left.Location);
1183 case Binary.Operator.GreaterThanOrEqual:
1184 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1185 if (left == null || right == null)
1189 if (left is DoubleConstant)
1190 bool_res = ((DoubleConstant) left).Value >=
1191 ((DoubleConstant) right).Value;
1192 else if (left is FloatConstant)
1193 bool_res = ((FloatConstant) left).Value >=
1194 ((FloatConstant) right).Value;
1195 else if (left is ULongConstant)
1196 bool_res = ((ULongConstant) left).Value >=
1197 ((ULongConstant) right).Value;
1198 else if (left is LongConstant)
1199 bool_res = ((LongConstant) left).Value >=
1200 ((LongConstant) right).Value;
1201 else if (left is UIntConstant)
1202 bool_res = ((UIntConstant) left).Value >=
1203 ((UIntConstant) right).Value;
1204 else if (left is IntConstant)
1205 bool_res = ((IntConstant) left).Value >=
1206 ((IntConstant) right).Value;
1210 return new BoolConstant (bool_res, left.Location);
1212 case Binary.Operator.LessThanOrEqual:
1213 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1214 if (left == null || right == null)
1218 if (left is DoubleConstant)
1219 bool_res = ((DoubleConstant) left).Value <=
1220 ((DoubleConstant) right).Value;
1221 else if (left is FloatConstant)
1222 bool_res = ((FloatConstant) left).Value <=
1223 ((FloatConstant) right).Value;
1224 else if (left is ULongConstant)
1225 bool_res = ((ULongConstant) left).Value <=
1226 ((ULongConstant) right).Value;
1227 else if (left is LongConstant)
1228 bool_res = ((LongConstant) left).Value <=
1229 ((LongConstant) right).Value;
1230 else if (left is UIntConstant)
1231 bool_res = ((UIntConstant) left).Value <=
1232 ((UIntConstant) right).Value;
1233 else if (left is IntConstant)
1234 bool_res = ((IntConstant) left).Value <=
1235 ((IntConstant) right).Value;
1239 return new BoolConstant (bool_res, left.Location);