2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2002, 2003 Ximian, Inc.
12 namespace Mono.CSharp {
14 public class ConstantFold {
17 // Performs the numeric promotions on the left and right expresions
18 // and desposits the results on `lc' and `rc'.
20 // On success, the types of `lc' and `rc' on output will always match,
21 // and the pair will be one of:
29 // (short, short) (Happens with enumerations with underlying short type)
30 // (ushort, ushort) (Happens with enumerations with underlying short type)
32 static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
33 ref Constant left, ref Constant right,
36 if (left is DoubleConstant || right is DoubleConstant){
38 // If either side is a double, convert the other to a double
40 if (!(left is DoubleConstant))
41 left = left.ToDouble (loc);
43 if (!(right is DoubleConstant))
44 right = right.ToDouble (loc);
46 } else if (left is FloatConstant || right is FloatConstant) {
48 // If either side is a float, convert the other to a float
50 if (!(left is FloatConstant))
51 left = left.ToFloat (loc);
53 if (!(right is FloatConstant))
54 right = right.ToFloat (loc);
56 } else if (left is ULongConstant || right is ULongConstant){
58 // If either operand is of type ulong, the other operand is
59 // converted to type ulong. or an error ocurrs if the other
60 // operand is of type sbyte, short, int or long
63 Constant match, other;
66 if (left is ULongConstant){
71 if (!(right is ULongConstant))
72 right = right.ToULong (loc);
78 left = left.ToULong (loc);
82 if (other is SByteConstant || other is ShortConstant ||
83 other is IntConstant || other is LongConstant){
84 Binary.Error_OperatorAmbiguous
85 (loc, oper, other.Type, match.Type);
91 } else if (left is LongConstant || right is LongConstant){
93 // If either operand is of type long, the other operand is converted
96 if (!(left is LongConstant))
97 left = left.ToLong (loc);
98 else if (!(right is LongConstant))
99 right = right.ToLong (loc);
101 } else if (left is UIntConstant || right is UIntConstant){
103 // If either operand is of type uint, and the other
104 // operand is of type sbyte, short or int, the operands are
105 // converted to type long.
108 if (left is UIntConstant)
114 if (other is UIntConstant)
117 IntConstant ic = other as IntConstant;
121 left = new UIntConstant ((uint) ic.Value);
123 right = new UIntConstant ((uint) ic.Value);
128 if (other is SByteConstant || other is ShortConstant || ic != null){
129 left = left.ToLong (loc);
130 right = right.ToLong (loc);
132 left = left.ToUInt (loc);
133 right = left.ToUInt (loc);
137 } else if (left is DecimalConstant || right is DecimalConstant) {
138 if (!(left is DecimalConstant))
139 left = left.ToDecimal (loc);
140 else if (!(right is DecimalConstant))
141 right = right.ToDecimal (loc);
143 } else if (left is EnumConstant || right is EnumConstant){
145 // If either operand is an enum constant, the other one must
146 // be implicitly convertable to that enum's underlying type.
150 if (left is EnumConstant){
152 match = (EnumConstant) left;
155 match = (EnumConstant) right;
158 bool need_check = (other is EnumConstant) ||
159 !(oper == Binary.Operator.Addition ||
160 oper == Binary.Operator.Subtraction ||
161 (other.IsZeroInteger && other is IntConstant));
164 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
165 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
171 if (left is EnumConstant)
172 left = ((EnumConstant) left).Child;
173 if (right is EnumConstant)
174 right = ((EnumConstant) right).Child;
176 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
181 // Force conversions to int32
183 if (!(left is IntConstant))
184 left = left.ToInt (loc);
185 if (!(right is IntConstant))
186 right = right.ToInt (loc);
191 static void Error_CompileTimeOverflow (Location loc)
193 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
197 /// Constant expression folder for binary operations.
199 /// Returns null if the expression can not be folded.
201 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
202 Constant left, Constant right, Location loc)
205 Type rt = right.Type;
206 Type result_type = null;
210 // Enumerator folding
212 if (rt == lt && left is EnumConstant)
216 // During an enum evaluation, we need to unwrap enumerations
218 if (ec.InEnumContext){
219 if (left is EnumConstant)
220 left = ((EnumConstant) left).Child;
222 if (right is EnumConstant)
223 right = ((EnumConstant) right).Child;
227 Constant result = null;
229 case Binary.Operator.BitwiseOr:
230 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
231 if (left == null || right == null)
234 if (left is IntConstant){
236 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
238 v = new IntConstant (res);
239 if (result_type == null)
242 return new EnumConstant (v, result_type);
243 } else if (left is UIntConstant){
245 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
247 v = new UIntConstant (res);
248 if (result_type == null)
251 return new EnumConstant (v, result_type);
252 } else if (left is LongConstant){
254 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
256 v = new LongConstant (res);
257 if (result_type == null)
260 return new EnumConstant (v, result_type);
261 } else if (left is ULongConstant){
263 ulong res = ((ULongConstant)left).Value |
264 ((ULongConstant)right).Value;
266 v = new ULongConstant (res);
267 if (result_type == null)
270 return new EnumConstant (v, result_type);
271 } else if (left is UShortConstant){
273 ushort res = (ushort) (((UShortConstant)left).Value |
274 ((UShortConstant)right).Value);
276 v = new UShortConstant (res);
277 if (result_type == null)
280 return new EnumConstant (v, result_type);
281 } else if (left is ShortConstant){
283 short res = (short) (((ShortConstant)left).Value |
284 ((ShortConstant)right).Value);
286 v = new ShortConstant (res);
287 if (result_type == null)
290 return new EnumConstant (v, result_type);
294 case Binary.Operator.BitwiseAnd:
295 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
296 if (left == null || right == null)
299 if (left is IntConstant){
301 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
303 v = new IntConstant (res);
304 if (result_type == null)
307 return new EnumConstant (v, result_type);
308 } else if (left is UIntConstant){
310 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
312 v = new UIntConstant (res);
313 if (result_type == null)
316 return new EnumConstant (v, result_type);
317 } else if (left is LongConstant){
319 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
321 v = new LongConstant (res);
322 if (result_type == null)
325 return new EnumConstant (v, result_type);
326 } else if (left is ULongConstant){
328 ulong res = ((ULongConstant)left).Value &
329 ((ULongConstant)right).Value;
331 v = new ULongConstant (res);
332 if (result_type == null)
335 return new EnumConstant (v, result_type);
336 } else if (left is UShortConstant){
338 ushort res = (ushort) (((UShortConstant)left).Value &
339 ((UShortConstant)right).Value);
341 v = new UShortConstant (res);
342 if (result_type == null)
345 return new EnumConstant (v, result_type);
346 } else if (left is ShortConstant){
348 short res = (short) (((ShortConstant)left).Value &
349 ((ShortConstant)right).Value);
351 v = new ShortConstant (res);
352 if (result_type == null)
355 return new EnumConstant (v, result_type);
359 case Binary.Operator.ExclusiveOr:
360 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
361 if (left == null || right == null)
364 if (left is IntConstant){
366 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
368 v = new IntConstant (res);
369 if (result_type == null)
372 return new EnumConstant (v, result_type);
373 } else if (left is UIntConstant){
375 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
377 v = new UIntConstant (res);
378 if (result_type == null)
381 return new EnumConstant (v, result_type);
382 } else if (left is LongConstant){
384 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
386 v = new LongConstant (res);
387 if (result_type == null)
390 return new EnumConstant (v, result_type);
391 } else if (left is ULongConstant){
393 ulong res = ((ULongConstant)left).Value ^
394 ((ULongConstant)right).Value;
396 v = new ULongConstant (res);
397 if (result_type == null)
400 return new EnumConstant (v, result_type);
401 } else if (left is UShortConstant){
403 ushort res = (ushort) (((UShortConstant)left).Value ^
404 ((UShortConstant)right).Value);
406 v = new UShortConstant (res);
407 if (result_type == null)
410 return new EnumConstant (v, result_type);
411 } else if (left is ShortConstant){
413 short res = (short)(((ShortConstant)left).Value ^
414 ((ShortConstant)right).Value);
416 v = new ShortConstant (res);
417 if (result_type == null)
420 return new EnumConstant (v, result_type);
424 case Binary.Operator.Addition:
425 bool left_is_string = left is StringConstant;
426 bool right_is_string = right is StringConstant;
429 // If both sides are strings, then concatenate, if
430 // one is a string, and the other is not, then defer
431 // to runtime concatenation
434 if (left_is_string || right_is_string){
435 if (left_is_string && right_is_string)
436 return new StringConstant (
437 ((StringConstant) left).Value +
438 ((StringConstant) right).Value);
444 // handle "E operator + (E x, U y)"
445 // handle "E operator + (Y y, E x)"
447 // note that E operator + (E x, E y) is invalid
449 if (left is EnumConstant){
450 if (right is EnumConstant){
454 right = right.ToType (((EnumConstant) left).Child.Type, loc);
459 } else if (right is EnumConstant){
460 left = left.ToType (((EnumConstant) right).Child.Type, loc);
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);
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);
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);
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);
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);
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);
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);
551 throw new Exception ( "Unexepected addition input: " + left);
553 } catch (OverflowException){
554 Error_CompileTimeOverflow (loc);
558 return new EnumConstant (result, wrap_as);
562 case Binary.Operator.Subtraction:
564 // handle "E operator - (E x, U y)"
565 // handle "E operator - (Y y, E x)"
566 // handle "U operator - (E x, E y)"
569 if (left is EnumConstant){
570 if (right is EnumConstant){
571 if (left.Type != right.Type) {
572 Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
576 wrap_as = TypeManager.EnumToUnderlying (left.Type);
577 right = ((EnumConstant) right).Child.ToType (wrap_as, loc);
581 left = ((EnumConstant) left).Child.ToType (wrap_as, loc);
586 right = right.ToType (((EnumConstant) left).Child.Type, loc);
592 } else if (right is EnumConstant){
593 left = left.ToType (((EnumConstant) right).Child.Type, loc);
597 wrap_as = right.Type;
600 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
601 if (left == null || right == null)
605 if (left is DoubleConstant){
608 if (ec.ConstantCheckState)
609 res = checked (((DoubleConstant) left).Value -
610 ((DoubleConstant) right).Value);
612 res = unchecked (((DoubleConstant) left).Value -
613 ((DoubleConstant) right).Value);
615 result = new DoubleConstant (res);
616 } else if (left is FloatConstant){
619 if (ec.ConstantCheckState)
620 res = checked (((FloatConstant) left).Value -
621 ((FloatConstant) right).Value);
623 res = unchecked (((FloatConstant) left).Value -
624 ((FloatConstant) right).Value);
626 result = new FloatConstant (res);
627 } else if (left is ULongConstant){
630 if (ec.ConstantCheckState)
631 res = checked (((ULongConstant) left).Value -
632 ((ULongConstant) right).Value);
634 res = unchecked (((ULongConstant) left).Value -
635 ((ULongConstant) right).Value);
637 result = new ULongConstant (res);
638 } else if (left is LongConstant){
641 if (ec.ConstantCheckState)
642 res = checked (((LongConstant) left).Value -
643 ((LongConstant) right).Value);
645 res = unchecked (((LongConstant) left).Value -
646 ((LongConstant) right).Value);
648 result = new LongConstant (res);
649 } else if (left is UIntConstant){
652 if (ec.ConstantCheckState)
653 res = checked (((UIntConstant) left).Value -
654 ((UIntConstant) right).Value);
656 res = unchecked (((UIntConstant) left).Value -
657 ((UIntConstant) right).Value);
659 result = new UIntConstant (res);
660 } else if (left is IntConstant){
663 if (ec.ConstantCheckState)
664 res = checked (((IntConstant) left).Value -
665 ((IntConstant) right).Value);
667 res = unchecked (((IntConstant) left).Value -
668 ((IntConstant) right).Value);
670 result = new IntConstant (res);
671 } else if (left is DecimalConstant) {
674 if (ec.ConstantCheckState)
675 res = checked (((DecimalConstant) left).Value -
676 ((DecimalConstant) right).Value);
678 res = unchecked (((DecimalConstant) left).Value -
679 ((DecimalConstant) right).Value);
681 return new DecimalConstant (res);
683 throw new Exception ( "Unexepected subtraction input: " + left);
685 } catch (OverflowException){
686 Error_CompileTimeOverflow (loc);
689 return new EnumConstant (result, wrap_as);
693 case Binary.Operator.Multiply:
694 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
695 if (left == null || right == null)
699 if (left is DoubleConstant){
702 if (ec.ConstantCheckState)
703 res = checked (((DoubleConstant) left).Value *
704 ((DoubleConstant) right).Value);
706 res = unchecked (((DoubleConstant) left).Value *
707 ((DoubleConstant) right).Value);
709 return new DoubleConstant (res);
710 } else if (left is FloatConstant){
713 if (ec.ConstantCheckState)
714 res = checked (((FloatConstant) left).Value *
715 ((FloatConstant) right).Value);
717 res = unchecked (((FloatConstant) left).Value *
718 ((FloatConstant) right).Value);
720 return new FloatConstant (res);
721 } else if (left is ULongConstant){
724 if (ec.ConstantCheckState)
725 res = checked (((ULongConstant) left).Value *
726 ((ULongConstant) right).Value);
728 res = unchecked (((ULongConstant) left).Value *
729 ((ULongConstant) right).Value);
731 return new ULongConstant (res);
732 } else if (left is LongConstant){
735 if (ec.ConstantCheckState)
736 res = checked (((LongConstant) left).Value *
737 ((LongConstant) right).Value);
739 res = unchecked (((LongConstant) left).Value *
740 ((LongConstant) right).Value);
742 return new LongConstant (res);
743 } else if (left is UIntConstant){
746 if (ec.ConstantCheckState)
747 res = checked (((UIntConstant) left).Value *
748 ((UIntConstant) right).Value);
750 res = unchecked (((UIntConstant) left).Value *
751 ((UIntConstant) right).Value);
753 return new UIntConstant (res);
754 } else if (left is IntConstant){
757 if (ec.ConstantCheckState)
758 res = checked (((IntConstant) left).Value *
759 ((IntConstant) right).Value);
761 res = unchecked (((IntConstant) left).Value *
762 ((IntConstant) right).Value);
764 return new IntConstant (res);
765 } else if (left is DecimalConstant) {
768 if (ec.ConstantCheckState)
769 res = checked (((DecimalConstant) left).Value *
770 ((DecimalConstant) right).Value);
772 res = unchecked (((DecimalConstant) left).Value *
773 ((DecimalConstant) right).Value);
775 return new DecimalConstant (res);
777 throw new Exception ( "Unexepected multiply input: " + left);
779 } catch (OverflowException){
780 Error_CompileTimeOverflow (loc);
784 case Binary.Operator.Division:
785 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
786 if (left == null || right == null)
790 if (left is DoubleConstant){
793 if (ec.ConstantCheckState)
794 res = checked (((DoubleConstant) left).Value /
795 ((DoubleConstant) right).Value);
797 res = unchecked (((DoubleConstant) left).Value /
798 ((DoubleConstant) right).Value);
800 return new DoubleConstant (res);
801 } else if (left is FloatConstant){
804 if (ec.ConstantCheckState)
805 res = checked (((FloatConstant) left).Value /
806 ((FloatConstant) right).Value);
808 res = unchecked (((FloatConstant) left).Value /
809 ((FloatConstant) right).Value);
811 return new FloatConstant (res);
812 } else if (left is ULongConstant){
815 if (ec.ConstantCheckState)
816 res = checked (((ULongConstant) left).Value /
817 ((ULongConstant) right).Value);
819 res = unchecked (((ULongConstant) left).Value /
820 ((ULongConstant) right).Value);
822 return new ULongConstant (res);
823 } else if (left is LongConstant){
826 if (ec.ConstantCheckState)
827 res = checked (((LongConstant) left).Value /
828 ((LongConstant) right).Value);
830 res = unchecked (((LongConstant) left).Value /
831 ((LongConstant) right).Value);
833 return new LongConstant (res);
834 } else if (left is UIntConstant){
837 if (ec.ConstantCheckState)
838 res = checked (((UIntConstant) left).Value /
839 ((UIntConstant) right).Value);
841 res = unchecked (((UIntConstant) left).Value /
842 ((UIntConstant) right).Value);
844 return new UIntConstant (res);
845 } else if (left is IntConstant){
848 if (ec.ConstantCheckState)
849 res = checked (((IntConstant) left).Value /
850 ((IntConstant) right).Value);
852 res = unchecked (((IntConstant) left).Value /
853 ((IntConstant) right).Value);
855 return new IntConstant (res);
856 } else if (left is DecimalConstant) {
859 if (ec.ConstantCheckState)
860 res = checked (((DecimalConstant) left).Value /
861 ((DecimalConstant) right).Value);
863 res = unchecked (((DecimalConstant) left).Value /
864 ((DecimalConstant) right).Value);
866 return new DecimalConstant (res);
868 throw new Exception ( "Unexepected division input: " + left);
870 } catch (OverflowException){
871 Error_CompileTimeOverflow (loc);
873 } catch (DivideByZeroException) {
874 Report.Error (020, loc, "Division by constant zero");
879 case Binary.Operator.Modulus:
880 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
881 if (left == null || right == null)
885 if (left is DoubleConstant){
888 if (ec.ConstantCheckState)
889 res = checked (((DoubleConstant) left).Value %
890 ((DoubleConstant) right).Value);
892 res = unchecked (((DoubleConstant) left).Value %
893 ((DoubleConstant) right).Value);
895 return new DoubleConstant (res);
896 } else if (left is FloatConstant){
899 if (ec.ConstantCheckState)
900 res = checked (((FloatConstant) left).Value %
901 ((FloatConstant) right).Value);
903 res = unchecked (((FloatConstant) left).Value %
904 ((FloatConstant) right).Value);
906 return new FloatConstant (res);
907 } else if (left is ULongConstant){
910 if (ec.ConstantCheckState)
911 res = checked (((ULongConstant) left).Value %
912 ((ULongConstant) right).Value);
914 res = unchecked (((ULongConstant) left).Value %
915 ((ULongConstant) right).Value);
917 return new ULongConstant (res);
918 } else if (left is LongConstant){
921 if (ec.ConstantCheckState)
922 res = checked (((LongConstant) left).Value %
923 ((LongConstant) right).Value);
925 res = unchecked (((LongConstant) left).Value %
926 ((LongConstant) right).Value);
928 return new LongConstant (res);
929 } else if (left is UIntConstant){
932 if (ec.ConstantCheckState)
933 res = checked (((UIntConstant) left).Value %
934 ((UIntConstant) right).Value);
936 res = unchecked (((UIntConstant) left).Value %
937 ((UIntConstant) right).Value);
939 return new UIntConstant (res);
940 } else if (left is IntConstant){
943 if (ec.ConstantCheckState)
944 res = checked (((IntConstant) left).Value %
945 ((IntConstant) right).Value);
947 res = unchecked (((IntConstant) left).Value %
948 ((IntConstant) right).Value);
950 return new IntConstant (res);
952 throw new Exception ( "Unexepected modulus input: " + left);
954 } catch (DivideByZeroException){
955 Report.Error (020, loc, "Division by constant zero");
956 } catch (OverflowException){
957 Error_CompileTimeOverflow (loc);
962 // There is no overflow checking on left shift
964 case Binary.Operator.LeftShift:
965 IntConstant ic = right.ToInt (loc);
967 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
970 int lshift_val = ic.Value;
973 if ((lic = left.ConvertToInt ()) != null)
974 return new IntConstant (lic.Value << lshift_val);
977 if ((luic = left.ConvertToUInt ()) != null)
978 return new UIntConstant (luic.Value << lshift_val);
981 if ((llc = left.ConvertToLong ()) != null)
982 return new LongConstant (llc.Value << lshift_val);
985 if ((lulc = left.ConvertToULong ()) != null)
986 return new ULongConstant (lulc.Value << lshift_val);
988 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
992 // There is no overflow checking on right shift
994 case Binary.Operator.RightShift:
995 IntConstant sic = right.ToInt (loc);
997 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1000 int rshift_val = sic.Value;
1003 if ((ric = left.ConvertToInt ()) != null)
1004 return new IntConstant (ric.Value >> rshift_val);
1007 if ((ruic = left.ConvertToUInt ()) != null)
1008 return new UIntConstant (ruic.Value >> rshift_val);
1011 if ((rlc = left.ConvertToLong ()) != null)
1012 return new LongConstant (rlc.Value >> rshift_val);
1015 if ((rulc = left.ConvertToULong ()) != null)
1016 return new ULongConstant (rulc.Value >> rshift_val);
1018 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
1021 case Binary.Operator.LogicalAnd:
1022 if (left is BoolConstant && right is BoolConstant){
1023 return new BoolConstant (
1024 ((BoolConstant) left).Value &&
1025 ((BoolConstant) right).Value);
1029 case Binary.Operator.LogicalOr:
1030 if (left is BoolConstant && right is BoolConstant){
1031 return new BoolConstant (
1032 ((BoolConstant) left).Value ||
1033 ((BoolConstant) right).Value);
1037 case Binary.Operator.Equality:
1038 if (left is BoolConstant && right is BoolConstant){
1039 return new BoolConstant (
1040 ((BoolConstant) left).Value ==
1041 ((BoolConstant) right).Value);
1044 if (left is NullLiteral){
1045 if (right is NullLiteral)
1046 return new BoolConstant (true);
1047 else if (right is StringConstant)
1048 return new BoolConstant (
1049 ((StringConstant) right).Value == null);
1050 } else if (right is NullLiteral){
1051 if (left is NullLiteral)
1052 return new BoolConstant (true);
1053 else if (left is StringConstant)
1054 return new BoolConstant (
1055 ((StringConstant) left).Value == null);
1057 if (left is StringConstant && right is StringConstant){
1058 return new BoolConstant (
1059 ((StringConstant) left).Value ==
1060 ((StringConstant) right).Value);
1064 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1065 if (left == null || right == null)
1069 if (left is DoubleConstant)
1070 bool_res = ((DoubleConstant) left).Value ==
1071 ((DoubleConstant) right).Value;
1072 else if (left is FloatConstant)
1073 bool_res = ((FloatConstant) left).Value ==
1074 ((FloatConstant) right).Value;
1075 else if (left is ULongConstant)
1076 bool_res = ((ULongConstant) left).Value ==
1077 ((ULongConstant) right).Value;
1078 else if (left is LongConstant)
1079 bool_res = ((LongConstant) left).Value ==
1080 ((LongConstant) right).Value;
1081 else if (left is UIntConstant)
1082 bool_res = ((UIntConstant) left).Value ==
1083 ((UIntConstant) right).Value;
1084 else if (left is IntConstant)
1085 bool_res = ((IntConstant) left).Value ==
1086 ((IntConstant) right).Value;
1090 return new BoolConstant (bool_res);
1092 case Binary.Operator.Inequality:
1093 if (left is BoolConstant && right is BoolConstant){
1094 return new BoolConstant (
1095 ((BoolConstant) left).Value !=
1096 ((BoolConstant) right).Value);
1098 if (left is NullLiteral){
1099 if (right is NullLiteral)
1100 return new BoolConstant (false);
1101 else if (right is StringConstant)
1102 return new BoolConstant (
1103 ((StringConstant) right).Value != null);
1104 } else if (right is NullLiteral){
1105 if (left is NullLiteral)
1106 return new BoolConstant (false);
1107 else if (left is StringConstant)
1108 return new BoolConstant (
1109 ((StringConstant) left).Value != null);
1111 if (left is StringConstant && right is StringConstant){
1112 return new BoolConstant (
1113 ((StringConstant) left).Value !=
1114 ((StringConstant) right).Value);
1117 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1118 if (left == null || right == null)
1122 if (left is DoubleConstant)
1123 bool_res = ((DoubleConstant) left).Value !=
1124 ((DoubleConstant) right).Value;
1125 else if (left is FloatConstant)
1126 bool_res = ((FloatConstant) left).Value !=
1127 ((FloatConstant) right).Value;
1128 else if (left is ULongConstant)
1129 bool_res = ((ULongConstant) left).Value !=
1130 ((ULongConstant) right).Value;
1131 else if (left is LongConstant)
1132 bool_res = ((LongConstant) left).Value !=
1133 ((LongConstant) right).Value;
1134 else if (left is UIntConstant)
1135 bool_res = ((UIntConstant) left).Value !=
1136 ((UIntConstant) right).Value;
1137 else if (left is IntConstant)
1138 bool_res = ((IntConstant) left).Value !=
1139 ((IntConstant) right).Value;
1143 return new BoolConstant (bool_res);
1145 case Binary.Operator.LessThan:
1146 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1147 if (left == null || right == null)
1151 if (left is DoubleConstant)
1152 bool_res = ((DoubleConstant) left).Value <
1153 ((DoubleConstant) right).Value;
1154 else if (left is FloatConstant)
1155 bool_res = ((FloatConstant) left).Value <
1156 ((FloatConstant) right).Value;
1157 else if (left is ULongConstant)
1158 bool_res = ((ULongConstant) left).Value <
1159 ((ULongConstant) right).Value;
1160 else if (left is LongConstant)
1161 bool_res = ((LongConstant) left).Value <
1162 ((LongConstant) right).Value;
1163 else if (left is UIntConstant)
1164 bool_res = ((UIntConstant) left).Value <
1165 ((UIntConstant) right).Value;
1166 else if (left is IntConstant)
1167 bool_res = ((IntConstant) left).Value <
1168 ((IntConstant) right).Value;
1172 return new BoolConstant (bool_res);
1174 case Binary.Operator.GreaterThan:
1175 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1176 if (left == null || right == null)
1180 if (left is DoubleConstant)
1181 bool_res = ((DoubleConstant) left).Value >
1182 ((DoubleConstant) right).Value;
1183 else if (left is FloatConstant)
1184 bool_res = ((FloatConstant) left).Value >
1185 ((FloatConstant) right).Value;
1186 else if (left is ULongConstant)
1187 bool_res = ((ULongConstant) left).Value >
1188 ((ULongConstant) right).Value;
1189 else if (left is LongConstant)
1190 bool_res = ((LongConstant) left).Value >
1191 ((LongConstant) right).Value;
1192 else if (left is UIntConstant)
1193 bool_res = ((UIntConstant) left).Value >
1194 ((UIntConstant) right).Value;
1195 else if (left is IntConstant)
1196 bool_res = ((IntConstant) left).Value >
1197 ((IntConstant) right).Value;
1201 return new BoolConstant (bool_res);
1203 case Binary.Operator.GreaterThanOrEqual:
1204 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1205 if (left == null || right == null)
1209 if (left is DoubleConstant)
1210 bool_res = ((DoubleConstant) left).Value >=
1211 ((DoubleConstant) right).Value;
1212 else if (left is FloatConstant)
1213 bool_res = ((FloatConstant) left).Value >=
1214 ((FloatConstant) right).Value;
1215 else if (left is ULongConstant)
1216 bool_res = ((ULongConstant) left).Value >=
1217 ((ULongConstant) right).Value;
1218 else if (left is LongConstant)
1219 bool_res = ((LongConstant) left).Value >=
1220 ((LongConstant) right).Value;
1221 else if (left is UIntConstant)
1222 bool_res = ((UIntConstant) left).Value >=
1223 ((UIntConstant) right).Value;
1224 else if (left is IntConstant)
1225 bool_res = ((IntConstant) left).Value >=
1226 ((IntConstant) right).Value;
1230 return new BoolConstant (bool_res);
1232 case Binary.Operator.LessThanOrEqual:
1233 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1234 if (left == null || right == null)
1238 if (left is DoubleConstant)
1239 bool_res = ((DoubleConstant) left).Value <=
1240 ((DoubleConstant) right).Value;
1241 else if (left is FloatConstant)
1242 bool_res = ((FloatConstant) left).Value <=
1243 ((FloatConstant) right).Value;
1244 else if (left is ULongConstant)
1245 bool_res = ((ULongConstant) left).Value <=
1246 ((ULongConstant) right).Value;
1247 else if (left is LongConstant)
1248 bool_res = ((LongConstant) left).Value <=
1249 ((LongConstant) right).Value;
1250 else if (left is UIntConstant)
1251 bool_res = ((UIntConstant) left).Value <=
1252 ((UIntConstant) right).Value;
1253 else if (left is IntConstant)
1254 bool_res = ((IntConstant) left).Value <=
1255 ((IntConstant) right).Value;
1259 return new BoolConstant (bool_res);