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)
178 Type rt = right.Type;
179 Type result_type = null;
183 // Enumerator folding
185 if (rt == lt && left is EnumConstant)
189 // During an enum evaluation, we need to unwrap enumerations
191 if (ec.InEnumContext){
192 if (left is EnumConstant)
193 left = ((EnumConstant) left).Child;
195 if (right is EnumConstant)
196 right = ((EnumConstant) right).Child;
200 Constant result = null;
202 case Binary.Operator.BitwiseOr:
203 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
204 if (left == null || right == null)
207 if (left is IntConstant){
209 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
211 v = new IntConstant (res, left.Location);
212 if (result_type == null)
215 return new EnumConstant (v, result_type);
216 } else if (left is UIntConstant){
218 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
220 v = new UIntConstant (res, left.Location);
221 if (result_type == null)
224 return new EnumConstant (v, result_type);
225 } else if (left is LongConstant){
227 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
229 v = new LongConstant (res, left.Location);
230 if (result_type == null)
233 return new EnumConstant (v, result_type);
234 } else if (left is ULongConstant){
236 ulong res = ((ULongConstant)left).Value |
237 ((ULongConstant)right).Value;
239 v = new ULongConstant (res, left.Location);
240 if (result_type == null)
243 return new EnumConstant (v, result_type);
244 } else if (left is UShortConstant){
246 ushort res = (ushort) (((UShortConstant)left).Value |
247 ((UShortConstant)right).Value);
249 v = new UShortConstant (res, left.Location);
250 if (result_type == null)
253 return new EnumConstant (v, result_type);
254 } else if (left is ShortConstant){
256 short res = (short) (((ShortConstant)left).Value |
257 ((ShortConstant)right).Value);
259 v = new ShortConstant (res, left.Location);
260 if (result_type == null)
263 return new EnumConstant (v, result_type);
267 case Binary.Operator.BitwiseAnd:
268 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
269 if (left == null || right == null)
272 if (left is IntConstant){
274 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
276 v = new IntConstant (res, left.Location);
277 if (result_type == null)
280 return new EnumConstant (v, result_type);
281 } else if (left is UIntConstant){
283 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
285 v = new UIntConstant (res, left.Location);
286 if (result_type == null)
289 return new EnumConstant (v, result_type);
290 } else if (left is LongConstant){
292 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
294 v = new LongConstant (res, left.Location);
295 if (result_type == null)
298 return new EnumConstant (v, result_type);
299 } else if (left is ULongConstant){
301 ulong res = ((ULongConstant)left).Value &
302 ((ULongConstant)right).Value;
304 v = new ULongConstant (res, left.Location);
305 if (result_type == null)
308 return new EnumConstant (v, result_type);
309 } else if (left is UShortConstant){
311 ushort res = (ushort) (((UShortConstant)left).Value &
312 ((UShortConstant)right).Value);
314 v = new UShortConstant (res, left.Location);
315 if (result_type == null)
318 return new EnumConstant (v, result_type);
319 } else if (left is ShortConstant){
321 short res = (short) (((ShortConstant)left).Value &
322 ((ShortConstant)right).Value);
324 v = new ShortConstant (res, left.Location);
325 if (result_type == null)
328 return new EnumConstant (v, result_type);
332 case Binary.Operator.ExclusiveOr:
333 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
334 if (left == null || right == null)
337 if (left is IntConstant){
339 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
341 v = new IntConstant (res, left.Location);
342 if (result_type == null)
345 return new EnumConstant (v, result_type);
346 } else if (left is UIntConstant){
348 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
350 v = new UIntConstant (res, left.Location);
351 if (result_type == null)
354 return new EnumConstant (v, result_type);
355 } else if (left is LongConstant){
357 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
359 v = new LongConstant (res, left.Location);
360 if (result_type == null)
363 return new EnumConstant (v, result_type);
364 } else if (left is ULongConstant){
366 ulong res = ((ULongConstant)left).Value ^
367 ((ULongConstant)right).Value;
369 v = new ULongConstant (res, left.Location);
370 if (result_type == null)
373 return new EnumConstant (v, result_type);
374 } else if (left is UShortConstant){
376 ushort res = (ushort) (((UShortConstant)left).Value ^
377 ((UShortConstant)right).Value);
379 v = new UShortConstant (res, left.Location);
380 if (result_type == null)
383 return new EnumConstant (v, result_type);
384 } else if (left is ShortConstant){
386 short res = (short)(((ShortConstant)left).Value ^
387 ((ShortConstant)right).Value);
389 v = new ShortConstant (res, left.Location);
390 if (result_type == null)
393 return new EnumConstant (v, result_type);
397 case Binary.Operator.Addition:
398 bool left_is_string = left is StringConstant;
399 bool right_is_string = right is StringConstant;
402 // If both sides are strings, then concatenate, if
403 // one is a string, and the other is not, then defer
404 // to runtime concatenation
407 if (left_is_string || right_is_string){
408 if (left_is_string && right_is_string)
409 return new StringConstant (
410 ((StringConstant) left).Value +
411 ((StringConstant) right).Value, left.Location);
417 // handle "E operator + (E x, U y)"
418 // handle "E operator + (Y y, E x)"
420 // note that E operator + (E x, E y) is invalid
422 if (left is EnumConstant){
423 if (right is EnumConstant){
427 right = right.ToType (((EnumConstant) left).Child.Type, loc);
432 } else if (right is EnumConstant){
433 left = left.ToType (((EnumConstant) right).Child.Type, loc);
437 wrap_as = right.Type;
441 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
442 if (left == null || right == null)
446 if (left is DoubleConstant){
449 if (ec.ConstantCheckState)
450 res = checked (((DoubleConstant) left).Value +
451 ((DoubleConstant) right).Value);
453 res = unchecked (((DoubleConstant) left).Value +
454 ((DoubleConstant) right).Value);
456 result = new DoubleConstant (res, left.Location);
457 } else if (left is FloatConstant){
460 if (ec.ConstantCheckState)
461 res = checked (((FloatConstant) left).Value +
462 ((FloatConstant) right).Value);
464 res = unchecked (((FloatConstant) left).Value +
465 ((FloatConstant) right).Value);
467 result = new FloatConstant (res, left.Location);
468 } else if (left is ULongConstant){
471 if (ec.ConstantCheckState)
472 res = checked (((ULongConstant) left).Value +
473 ((ULongConstant) right).Value);
475 res = unchecked (((ULongConstant) left).Value +
476 ((ULongConstant) right).Value);
478 result = new ULongConstant (res, left.Location);
479 } else if (left is LongConstant){
482 if (ec.ConstantCheckState)
483 res = checked (((LongConstant) left).Value +
484 ((LongConstant) right).Value);
486 res = unchecked (((LongConstant) left).Value +
487 ((LongConstant) right).Value);
489 result = new LongConstant (res, left.Location);
490 } else if (left is UIntConstant){
493 if (ec.ConstantCheckState)
494 res = checked (((UIntConstant) left).Value +
495 ((UIntConstant) right).Value);
497 res = unchecked (((UIntConstant) left).Value +
498 ((UIntConstant) right).Value);
500 result = new UIntConstant (res, left.Location);
501 } else if (left is IntConstant){
504 if (ec.ConstantCheckState)
505 res = checked (((IntConstant) left).Value +
506 ((IntConstant) right).Value);
508 res = unchecked (((IntConstant) left).Value +
509 ((IntConstant) right).Value);
511 result = new IntConstant (res, left.Location);
512 } else if (left is DecimalConstant) {
515 if (ec.ConstantCheckState)
516 res = checked (((DecimalConstant) left).Value +
517 ((DecimalConstant) right).Value);
519 res = unchecked (((DecimalConstant) left).Value +
520 ((DecimalConstant) right).Value);
522 result = new DecimalConstant (res, left.Location);
524 throw new Exception ( "Unexepected addition input: " + left);
526 } catch (OverflowException){
527 Error_CompileTimeOverflow (loc);
531 return result.TryReduce (ec, wrap_as, loc);
535 case Binary.Operator.Subtraction:
537 // handle "E operator - (E x, U y)"
538 // handle "E operator - (Y y, E x)"
539 // handle "U operator - (E x, E y)"
542 if (left is EnumConstant){
543 if (right is EnumConstant){
544 if (left.Type != right.Type) {
545 Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
549 wrap_as = TypeManager.EnumToUnderlying (left.Type);
550 right = ((EnumConstant) right).Child.ToType (wrap_as, loc);
554 left = ((EnumConstant) left).Child.ToType (wrap_as, loc);
559 right = right.ToType (((EnumConstant) left).Child.Type, loc);
565 } else if (right is EnumConstant){
566 left = left.ToType (((EnumConstant) right).Child.Type, loc);
570 wrap_as = right.Type;
573 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
574 if (left == null || right == null)
578 if (left is DoubleConstant){
581 if (ec.ConstantCheckState)
582 res = checked (((DoubleConstant) left).Value -
583 ((DoubleConstant) right).Value);
585 res = unchecked (((DoubleConstant) left).Value -
586 ((DoubleConstant) right).Value);
588 result = new DoubleConstant (res, left.Location);
589 } else if (left is FloatConstant){
592 if (ec.ConstantCheckState)
593 res = checked (((FloatConstant) left).Value -
594 ((FloatConstant) right).Value);
596 res = unchecked (((FloatConstant) left).Value -
597 ((FloatConstant) right).Value);
599 result = new FloatConstant (res, left.Location);
600 } else if (left is ULongConstant){
603 if (ec.ConstantCheckState)
604 res = checked (((ULongConstant) left).Value -
605 ((ULongConstant) right).Value);
607 res = unchecked (((ULongConstant) left).Value -
608 ((ULongConstant) right).Value);
610 result = new ULongConstant (res, left.Location);
611 } else if (left is LongConstant){
614 if (ec.ConstantCheckState)
615 res = checked (((LongConstant) left).Value -
616 ((LongConstant) right).Value);
618 res = unchecked (((LongConstant) left).Value -
619 ((LongConstant) right).Value);
621 result = new LongConstant (res, left.Location);
622 } else if (left is UIntConstant){
625 if (ec.ConstantCheckState)
626 res = checked (((UIntConstant) left).Value -
627 ((UIntConstant) right).Value);
629 res = unchecked (((UIntConstant) left).Value -
630 ((UIntConstant) right).Value);
632 result = new UIntConstant (res, left.Location);
633 } else if (left is IntConstant){
636 if (ec.ConstantCheckState)
637 res = checked (((IntConstant) left).Value -
638 ((IntConstant) right).Value);
640 res = unchecked (((IntConstant) left).Value -
641 ((IntConstant) right).Value);
643 result = new IntConstant (res, left.Location);
644 } else if (left is DecimalConstant) {
647 if (ec.ConstantCheckState)
648 res = checked (((DecimalConstant) left).Value -
649 ((DecimalConstant) right).Value);
651 res = unchecked (((DecimalConstant) left).Value -
652 ((DecimalConstant) right).Value);
654 return new DecimalConstant (res, left.Location);
656 throw new Exception ( "Unexepected subtraction input: " + left);
658 } catch (OverflowException){
659 Error_CompileTimeOverflow (loc);
663 return result.TryReduce (ec, wrap_as, loc);
667 case Binary.Operator.Multiply:
668 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
669 if (left == null || right == null)
673 if (left is DoubleConstant){
676 if (ec.ConstantCheckState)
677 res = checked (((DoubleConstant) left).Value *
678 ((DoubleConstant) right).Value);
680 res = unchecked (((DoubleConstant) left).Value *
681 ((DoubleConstant) right).Value);
683 return new DoubleConstant (res, left.Location);
684 } else if (left is FloatConstant){
687 if (ec.ConstantCheckState)
688 res = checked (((FloatConstant) left).Value *
689 ((FloatConstant) right).Value);
691 res = unchecked (((FloatConstant) left).Value *
692 ((FloatConstant) right).Value);
694 return new FloatConstant (res, left.Location);
695 } else if (left is ULongConstant){
698 if (ec.ConstantCheckState)
699 res = checked (((ULongConstant) left).Value *
700 ((ULongConstant) right).Value);
702 res = unchecked (((ULongConstant) left).Value *
703 ((ULongConstant) right).Value);
705 return new ULongConstant (res, left.Location);
706 } else if (left is LongConstant){
709 if (ec.ConstantCheckState)
710 res = checked (((LongConstant) left).Value *
711 ((LongConstant) right).Value);
713 res = unchecked (((LongConstant) left).Value *
714 ((LongConstant) right).Value);
716 return new LongConstant (res, left.Location);
717 } else if (left is UIntConstant){
720 if (ec.ConstantCheckState)
721 res = checked (((UIntConstant) left).Value *
722 ((UIntConstant) right).Value);
724 res = unchecked (((UIntConstant) left).Value *
725 ((UIntConstant) right).Value);
727 return new UIntConstant (res, left.Location);
728 } else if (left is IntConstant){
731 if (ec.ConstantCheckState)
732 res = checked (((IntConstant) left).Value *
733 ((IntConstant) right).Value);
735 res = unchecked (((IntConstant) left).Value *
736 ((IntConstant) right).Value);
738 return new IntConstant (res, left.Location);
739 } else if (left is DecimalConstant) {
742 if (ec.ConstantCheckState)
743 res = checked (((DecimalConstant) left).Value *
744 ((DecimalConstant) right).Value);
746 res = unchecked (((DecimalConstant) left).Value *
747 ((DecimalConstant) right).Value);
749 return new DecimalConstant (res, left.Location);
751 throw new Exception ( "Unexepected multiply input: " + left);
753 } catch (OverflowException){
754 Error_CompileTimeOverflow (loc);
758 case Binary.Operator.Division:
759 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
760 if (left == null || right == null)
764 if (left is DoubleConstant){
767 if (ec.ConstantCheckState)
768 res = checked (((DoubleConstant) left).Value /
769 ((DoubleConstant) right).Value);
771 res = unchecked (((DoubleConstant) left).Value /
772 ((DoubleConstant) right).Value);
774 return new DoubleConstant (res, left.Location);
775 } else if (left is FloatConstant){
778 if (ec.ConstantCheckState)
779 res = checked (((FloatConstant) left).Value /
780 ((FloatConstant) right).Value);
782 res = unchecked (((FloatConstant) left).Value /
783 ((FloatConstant) right).Value);
785 return new FloatConstant (res, left.Location);
786 } else if (left is ULongConstant){
789 if (ec.ConstantCheckState)
790 res = checked (((ULongConstant) left).Value /
791 ((ULongConstant) right).Value);
793 res = unchecked (((ULongConstant) left).Value /
794 ((ULongConstant) right).Value);
796 return new ULongConstant (res, left.Location);
797 } else if (left is LongConstant){
800 if (ec.ConstantCheckState)
801 res = checked (((LongConstant) left).Value /
802 ((LongConstant) right).Value);
804 res = unchecked (((LongConstant) left).Value /
805 ((LongConstant) right).Value);
807 return new LongConstant (res, left.Location);
808 } else if (left is UIntConstant){
811 if (ec.ConstantCheckState)
812 res = checked (((UIntConstant) left).Value /
813 ((UIntConstant) right).Value);
815 res = unchecked (((UIntConstant) left).Value /
816 ((UIntConstant) right).Value);
818 return new UIntConstant (res, left.Location);
819 } else if (left is IntConstant){
822 if (ec.ConstantCheckState)
823 res = checked (((IntConstant) left).Value /
824 ((IntConstant) right).Value);
826 res = unchecked (((IntConstant) left).Value /
827 ((IntConstant) right).Value);
829 return new IntConstant (res, left.Location);
830 } else if (left is DecimalConstant) {
833 if (ec.ConstantCheckState)
834 res = checked (((DecimalConstant) left).Value /
835 ((DecimalConstant) right).Value);
837 res = unchecked (((DecimalConstant) left).Value /
838 ((DecimalConstant) right).Value);
840 return new DecimalConstant (res, left.Location);
842 throw new Exception ( "Unexepected division input: " + left);
844 } catch (OverflowException){
845 Error_CompileTimeOverflow (loc);
847 } catch (DivideByZeroException) {
848 Report.Error (020, loc, "Division by constant zero");
853 case Binary.Operator.Modulus:
854 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
855 if (left == null || right == null)
859 if (left is DoubleConstant){
862 if (ec.ConstantCheckState)
863 res = checked (((DoubleConstant) left).Value %
864 ((DoubleConstant) right).Value);
866 res = unchecked (((DoubleConstant) left).Value %
867 ((DoubleConstant) right).Value);
869 return new DoubleConstant (res, left.Location);
870 } else if (left is FloatConstant){
873 if (ec.ConstantCheckState)
874 res = checked (((FloatConstant) left).Value %
875 ((FloatConstant) right).Value);
877 res = unchecked (((FloatConstant) left).Value %
878 ((FloatConstant) right).Value);
880 return new FloatConstant (res, left.Location);
881 } else if (left is ULongConstant){
884 if (ec.ConstantCheckState)
885 res = checked (((ULongConstant) left).Value %
886 ((ULongConstant) right).Value);
888 res = unchecked (((ULongConstant) left).Value %
889 ((ULongConstant) right).Value);
891 return new ULongConstant (res, left.Location);
892 } else if (left is LongConstant){
895 if (ec.ConstantCheckState)
896 res = checked (((LongConstant) left).Value %
897 ((LongConstant) right).Value);
899 res = unchecked (((LongConstant) left).Value %
900 ((LongConstant) right).Value);
902 return new LongConstant (res, left.Location);
903 } else if (left is UIntConstant){
906 if (ec.ConstantCheckState)
907 res = checked (((UIntConstant) left).Value %
908 ((UIntConstant) right).Value);
910 res = unchecked (((UIntConstant) left).Value %
911 ((UIntConstant) right).Value);
913 return new UIntConstant (res, left.Location);
914 } else if (left is IntConstant){
917 if (ec.ConstantCheckState)
918 res = checked (((IntConstant) left).Value %
919 ((IntConstant) right).Value);
921 res = unchecked (((IntConstant) left).Value %
922 ((IntConstant) right).Value);
924 return new IntConstant (res, left.Location);
926 throw new Exception ( "Unexepected modulus input: " + left);
928 } catch (DivideByZeroException){
929 Report.Error (020, loc, "Division by constant zero");
930 } catch (OverflowException){
931 Error_CompileTimeOverflow (loc);
936 // There is no overflow checking on left shift
938 case Binary.Operator.LeftShift:
939 IntConstant ic = right.ToInt (loc);
941 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
944 int lshift_val = ic.Value;
947 if ((lic = left.ConvertToInt ()) != null)
948 return new IntConstant (lic.Value << lshift_val, left.Location);
951 if ((luic = left.ConvertToUInt ()) != null)
952 return new UIntConstant (luic.Value << lshift_val, left.Location);
955 if ((llc = left.ConvertToLong ()) != null)
956 return new LongConstant (llc.Value << lshift_val, left.Location);
959 if ((lulc = left.ConvertToULong ()) != null)
960 return new ULongConstant (lulc.Value << lshift_val, left.Location);
962 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
966 // There is no overflow checking on right shift
968 case Binary.Operator.RightShift:
969 IntConstant sic = right.ToInt (loc);
971 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
974 int rshift_val = sic.Value;
977 if ((ric = left.ConvertToInt ()) != null)
978 return new IntConstant (ric.Value >> rshift_val, left.Location);
981 if ((ruic = left.ConvertToUInt ()) != null)
982 return new UIntConstant (ruic.Value >> rshift_val, left.Location);
985 if ((rlc = left.ConvertToLong ()) != null)
986 return new LongConstant (rlc.Value >> rshift_val, left.Location);
989 if ((rulc = left.ConvertToULong ()) != null)
990 return new ULongConstant (rulc.Value >> rshift_val, left.Location);
992 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
995 case Binary.Operator.LogicalAnd:
996 if (left is BoolConstant && right is BoolConstant){
997 return new BoolConstant (
998 ((BoolConstant) left).Value &&
999 ((BoolConstant) right).Value, left.Location);
1003 case Binary.Operator.LogicalOr:
1004 if (left is BoolConstant && right is BoolConstant){
1005 return new BoolConstant (
1006 ((BoolConstant) left).Value ||
1007 ((BoolConstant) right).Value, left.Location);
1011 case Binary.Operator.Equality:
1012 if (left is BoolConstant && right is BoolConstant){
1013 return new BoolConstant (
1014 ((BoolConstant) left).Value ==
1015 ((BoolConstant) right).Value, left.Location);
1018 if (left is NullLiteral){
1019 if (right is NullLiteral)
1020 return new BoolConstant (true, left.Location);
1021 else if (right is StringConstant)
1022 return new BoolConstant (
1023 ((StringConstant) right).Value == null, left.Location);
1024 } else if (right is NullLiteral){
1025 if (left is NullLiteral)
1026 return new BoolConstant (true, left.Location);
1027 else if (left is StringConstant)
1028 return new BoolConstant (
1029 ((StringConstant) left).Value == null, left.Location);
1031 if (left is StringConstant && right is StringConstant){
1032 return new BoolConstant (
1033 ((StringConstant) left).Value ==
1034 ((StringConstant) right).Value, left.Location);
1038 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1039 if (left == null || right == null)
1043 if (left is DoubleConstant)
1044 bool_res = ((DoubleConstant) left).Value ==
1045 ((DoubleConstant) right).Value;
1046 else if (left is FloatConstant)
1047 bool_res = ((FloatConstant) left).Value ==
1048 ((FloatConstant) right).Value;
1049 else if (left is ULongConstant)
1050 bool_res = ((ULongConstant) left).Value ==
1051 ((ULongConstant) right).Value;
1052 else if (left is LongConstant)
1053 bool_res = ((LongConstant) left).Value ==
1054 ((LongConstant) right).Value;
1055 else if (left is UIntConstant)
1056 bool_res = ((UIntConstant) left).Value ==
1057 ((UIntConstant) right).Value;
1058 else if (left is IntConstant)
1059 bool_res = ((IntConstant) left).Value ==
1060 ((IntConstant) right).Value;
1064 return new BoolConstant (bool_res, left.Location);
1066 case Binary.Operator.Inequality:
1067 if (left is BoolConstant && right is BoolConstant){
1068 return new BoolConstant (
1069 ((BoolConstant) left).Value !=
1070 ((BoolConstant) right).Value, left.Location);
1072 if (left is NullLiteral){
1073 if (right is NullLiteral)
1074 return new BoolConstant (false, left.Location);
1075 else if (right is StringConstant)
1076 return new BoolConstant (
1077 ((StringConstant) right).Value != null, left.Location);
1078 } else if (right is NullLiteral){
1079 if (left is NullLiteral)
1080 return new BoolConstant (false, left.Location);
1081 else if (left is StringConstant)
1082 return new BoolConstant (
1083 ((StringConstant) left).Value != null, left.Location);
1085 if (left is StringConstant && right is StringConstant){
1086 return new BoolConstant (
1087 ((StringConstant) left).Value !=
1088 ((StringConstant) right).Value, left.Location);
1091 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1092 if (left == null || right == null)
1096 if (left is DoubleConstant)
1097 bool_res = ((DoubleConstant) left).Value !=
1098 ((DoubleConstant) right).Value;
1099 else if (left is FloatConstant)
1100 bool_res = ((FloatConstant) left).Value !=
1101 ((FloatConstant) right).Value;
1102 else if (left is ULongConstant)
1103 bool_res = ((ULongConstant) left).Value !=
1104 ((ULongConstant) right).Value;
1105 else if (left is LongConstant)
1106 bool_res = ((LongConstant) left).Value !=
1107 ((LongConstant) right).Value;
1108 else if (left is UIntConstant)
1109 bool_res = ((UIntConstant) left).Value !=
1110 ((UIntConstant) right).Value;
1111 else if (left is IntConstant)
1112 bool_res = ((IntConstant) left).Value !=
1113 ((IntConstant) right).Value;
1117 return new BoolConstant (bool_res, left.Location);
1119 case Binary.Operator.LessThan:
1120 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1121 if (left == null || right == null)
1125 if (left is DoubleConstant)
1126 bool_res = ((DoubleConstant) left).Value <
1127 ((DoubleConstant) right).Value;
1128 else if (left is FloatConstant)
1129 bool_res = ((FloatConstant) left).Value <
1130 ((FloatConstant) right).Value;
1131 else if (left is ULongConstant)
1132 bool_res = ((ULongConstant) left).Value <
1133 ((ULongConstant) right).Value;
1134 else if (left is LongConstant)
1135 bool_res = ((LongConstant) left).Value <
1136 ((LongConstant) right).Value;
1137 else if (left is UIntConstant)
1138 bool_res = ((UIntConstant) left).Value <
1139 ((UIntConstant) right).Value;
1140 else if (left is IntConstant)
1141 bool_res = ((IntConstant) left).Value <
1142 ((IntConstant) right).Value;
1146 return new BoolConstant (bool_res, left.Location);
1148 case Binary.Operator.GreaterThan:
1149 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1150 if (left == null || right == null)
1154 if (left is DoubleConstant)
1155 bool_res = ((DoubleConstant) left).Value >
1156 ((DoubleConstant) right).Value;
1157 else if (left is FloatConstant)
1158 bool_res = ((FloatConstant) left).Value >
1159 ((FloatConstant) right).Value;
1160 else if (left is ULongConstant)
1161 bool_res = ((ULongConstant) left).Value >
1162 ((ULongConstant) right).Value;
1163 else if (left is LongConstant)
1164 bool_res = ((LongConstant) left).Value >
1165 ((LongConstant) right).Value;
1166 else if (left is UIntConstant)
1167 bool_res = ((UIntConstant) left).Value >
1168 ((UIntConstant) right).Value;
1169 else if (left is IntConstant)
1170 bool_res = ((IntConstant) left).Value >
1171 ((IntConstant) right).Value;
1175 return new BoolConstant (bool_res, left.Location);
1177 case Binary.Operator.GreaterThanOrEqual:
1178 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1179 if (left == null || right == null)
1183 if (left is DoubleConstant)
1184 bool_res = ((DoubleConstant) left).Value >=
1185 ((DoubleConstant) right).Value;
1186 else if (left is FloatConstant)
1187 bool_res = ((FloatConstant) left).Value >=
1188 ((FloatConstant) right).Value;
1189 else if (left is ULongConstant)
1190 bool_res = ((ULongConstant) left).Value >=
1191 ((ULongConstant) right).Value;
1192 else if (left is LongConstant)
1193 bool_res = ((LongConstant) left).Value >=
1194 ((LongConstant) right).Value;
1195 else if (left is UIntConstant)
1196 bool_res = ((UIntConstant) left).Value >=
1197 ((UIntConstant) right).Value;
1198 else if (left is IntConstant)
1199 bool_res = ((IntConstant) left).Value >=
1200 ((IntConstant) right).Value;
1204 return new BoolConstant (bool_res, left.Location);
1206 case Binary.Operator.LessThanOrEqual:
1207 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1208 if (left == null || right == null)
1212 if (left is DoubleConstant)
1213 bool_res = ((DoubleConstant) left).Value <=
1214 ((DoubleConstant) right).Value;
1215 else if (left is FloatConstant)
1216 bool_res = ((FloatConstant) left).Value <=
1217 ((FloatConstant) right).Value;
1218 else if (left is ULongConstant)
1219 bool_res = ((ULongConstant) left).Value <=
1220 ((ULongConstant) right).Value;
1221 else if (left is LongConstant)
1222 bool_res = ((LongConstant) left).Value <=
1223 ((LongConstant) right).Value;
1224 else if (left is UIntConstant)
1225 bool_res = ((UIntConstant) left).Value <=
1226 ((UIntConstant) right).Value;
1227 else if (left is IntConstant)
1228 bool_res = ((IntConstant) left).Value <=
1229 ((IntConstant) right).Value;
1233 return new BoolConstant (bool_res, left.Location);