2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2002, 2003 Ximian, Inc.
12 namespace Mono.CSharp {
14 public class ConstantFold {
17 // Performs the numeric promotions on the left and right expresions
18 // and desposits the results on `lc' and `rc'.
20 // On success, the types of `lc' and `rc' on output will always match,
21 // and the pair will be one of:
29 // (short, short) (Happens with enumerations with underlying short type)
30 // (ushort, ushort) (Happens with enumerations with underlying short type)
32 static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
33 ref Constant left, ref Constant right,
36 if (left is DoubleConstant || right is DoubleConstant){
38 // If either side is a double, convert the other to a double
40 if (!(left is DoubleConstant))
41 left = left.ToDouble (loc);
43 if (!(right is DoubleConstant))
44 right = right.ToDouble (loc);
46 } else if (left is FloatConstant || right is FloatConstant) {
48 // If either side is a float, convert the other to a float
50 if (!(left is FloatConstant))
51 left = left.ToFloat (loc);
53 if (!(right is FloatConstant))
54 right = right.ToFloat (loc);
56 } else if (left is ULongConstant || right is ULongConstant){
58 // If either operand is of type ulong, the other operand is
59 // converted to type ulong. or an error ocurrs if the other
60 // operand is of type sbyte, short, int or long
63 Constant match, other;
66 if (left is ULongConstant){
71 if (!(right is ULongConstant))
72 right = right.ToULong (loc);
78 left = left.ToULong (loc);
82 if (other is SByteConstant || other is ShortConstant ||
83 other is IntConstant || other is LongConstant){
84 Binary.Error_OperatorAmbiguous
85 (loc, oper, other.Type, match.Type);
91 } else if (left is LongConstant || right is LongConstant){
93 // If either operand is of type long, the other operand is converted
96 if (!(left is LongConstant))
97 left = left.ToLong (loc);
98 else if (!(right is LongConstant))
99 right = right.ToLong (loc);
101 } else if (left is UIntConstant || right is UIntConstant){
103 // If either operand is of type uint, and the other
104 // operand is of type sbyte, short or int, the operands are
105 // converted to type long.
108 if (left is UIntConstant)
114 if (other is UIntConstant)
117 IntConstant ic = other as IntConstant;
121 left = new UIntConstant ((uint) ic.Value);
123 right = new UIntConstant ((uint) ic.Value);
128 if (other is SByteConstant || other is ShortConstant || ic != null){
129 left = left.ToLong (loc);
130 right = right.ToLong (loc);
132 left = left.ToUInt (loc);
133 right = left.ToUInt (loc);
137 } else if (left is DecimalConstant || right is DecimalConstant) {
138 if (!(left is DecimalConstant))
139 left = left.ToDecimal (loc);
140 else if (!(right is DecimalConstant))
141 right = right.ToDecimal (loc);
143 } else if (left is EnumConstant || right is EnumConstant){
145 // If either operand is an enum constant, the other one must
146 // be implicitly convertable to that enum's underlying type.
150 if (left is EnumConstant){
152 match = (EnumConstant) left;
155 match = (EnumConstant) right;
158 bool need_check = (other is EnumConstant) ||
159 ((oper != Binary.Operator.Addition) &&
160 (oper != Binary.Operator.Subtraction));
163 !Convert.ImplicitConversionExists (ec, match, other.Type)) {
164 Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
170 if (left is EnumConstant)
171 left = ((EnumConstant) left).Child;
172 if (right is EnumConstant)
173 right = ((EnumConstant) right).Child;
178 // Force conversions to int32
180 if (!(left is IntConstant))
181 left = left.ToInt (loc);
182 if (!(right is IntConstant))
183 right = right.ToInt (loc);
188 static void Error_CompileTimeOverflow (Location loc)
190 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
194 /// Constant expression folder for binary operations.
196 /// Returns null if the expression can not be folded.
198 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
199 Constant left, Constant right, Location loc)
202 Type rt = right.Type;
203 Type result_type = null;
207 // Enumerator folding
209 if (rt == lt && left is EnumConstant)
213 // During an enum evaluation, we need to unwrap enumerations
215 if (ec.InEnumContext){
216 if (left is EnumConstant)
217 left = ((EnumConstant) left).Child;
219 if (right is EnumConstant)
220 right = ((EnumConstant) right).Child;
224 Constant result = null;
226 case Binary.Operator.BitwiseOr:
227 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
228 if (left == null || right == null)
231 if (left is IntConstant){
233 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
235 v = new IntConstant (res);
236 if (result_type == null)
239 return new EnumConstant (v, result_type);
240 } else if (left is UIntConstant){
242 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
244 v = new UIntConstant (res);
245 if (result_type == null)
248 return new EnumConstant (v, result_type);
249 } else if (left is LongConstant){
251 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
253 v = new LongConstant (res);
254 if (result_type == null)
257 return new EnumConstant (v, result_type);
258 } else if (left is ULongConstant){
260 ulong res = ((ULongConstant)left).Value |
261 ((ULongConstant)right).Value;
263 v = new ULongConstant (res);
264 if (result_type == null)
267 return new EnumConstant (v, result_type);
268 } else if (left is UShortConstant){
270 ushort res = (ushort) (((UShortConstant)left).Value |
271 ((UShortConstant)right).Value);
273 v = new UShortConstant (res);
274 if (result_type == null)
277 return new EnumConstant (v, result_type);
278 } else if (left is ShortConstant){
280 short res = (short) (((ShortConstant)left).Value |
281 ((ShortConstant)right).Value);
283 v = new ShortConstant (res);
284 if (result_type == null)
287 return new EnumConstant (v, result_type);
291 case Binary.Operator.BitwiseAnd:
292 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
293 if (left == null || right == null)
296 if (left is IntConstant){
298 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
300 v = new IntConstant (res);
301 if (result_type == null)
304 return new EnumConstant (v, result_type);
305 } else if (left is UIntConstant){
307 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
309 v = new UIntConstant (res);
310 if (result_type == null)
313 return new EnumConstant (v, result_type);
314 } else if (left is LongConstant){
316 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
318 v = new LongConstant (res);
319 if (result_type == null)
322 return new EnumConstant (v, result_type);
323 } else if (left is ULongConstant){
325 ulong res = ((ULongConstant)left).Value &
326 ((ULongConstant)right).Value;
328 v = new ULongConstant (res);
329 if (result_type == null)
332 return new EnumConstant (v, result_type);
333 } else if (left is UShortConstant){
335 ushort res = (ushort) (((UShortConstant)left).Value &
336 ((UShortConstant)right).Value);
338 v = new UShortConstant (res);
339 if (result_type == null)
342 return new EnumConstant (v, result_type);
343 } else if (left is ShortConstant){
345 short res = (short) (((ShortConstant)left).Value &
346 ((ShortConstant)right).Value);
348 v = new ShortConstant (res);
349 if (result_type == null)
352 return new EnumConstant (v, result_type);
356 case Binary.Operator.ExclusiveOr:
357 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
358 if (left == null || right == null)
361 if (left is IntConstant){
363 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
365 v = new IntConstant (res);
366 if (result_type == null)
369 return new EnumConstant (v, result_type);
370 } else if (left is UIntConstant){
372 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
374 v = new UIntConstant (res);
375 if (result_type == null)
378 return new EnumConstant (v, result_type);
379 } else if (left is LongConstant){
381 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
383 v = new LongConstant (res);
384 if (result_type == null)
387 return new EnumConstant (v, result_type);
388 } else if (left is ULongConstant){
390 ulong res = ((ULongConstant)left).Value ^
391 ((ULongConstant)right).Value;
393 v = new ULongConstant (res);
394 if (result_type == null)
397 return new EnumConstant (v, result_type);
398 } else if (left is UShortConstant){
400 ushort res = (ushort) (((UShortConstant)left).Value ^
401 ((UShortConstant)right).Value);
403 v = new UShortConstant (res);
404 if (result_type == null)
407 return new EnumConstant (v, result_type);
408 } else if (left is ShortConstant){
410 short res = (short)(((ShortConstant)left).Value ^
411 ((ShortConstant)right).Value);
413 v = new ShortConstant (res);
414 if (result_type == null)
417 return new EnumConstant (v, result_type);
421 case Binary.Operator.Addition:
422 bool left_is_string = left is StringConstant;
423 bool right_is_string = right is StringConstant;
426 // If both sides are strings, then concatenate, if
427 // one is a string, and the other is not, then defer
428 // to runtime concatenation
431 if (left_is_string || right_is_string){
432 if (left_is_string && right_is_string)
433 return new StringConstant (
434 ((StringConstant) left).Value +
435 ((StringConstant) right).Value);
441 // handle "E operator + (E x, U y)"
442 // handle "E operator + (Y y, E x)"
444 // note that E operator + (E x, E y) is invalid
446 if (left is EnumConstant){
447 if (right is EnumConstant){
450 if (((EnumConstant) left).Child.Type != right.Type)
454 } else if (right is EnumConstant){
455 if (((EnumConstant) right).Child.Type != left.Type)
457 wrap_as = right.Type;
461 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
462 if (left == null || right == null)
466 if (left is DoubleConstant){
469 if (ec.ConstantCheckState)
470 res = checked (((DoubleConstant) left).Value +
471 ((DoubleConstant) right).Value);
473 res = unchecked (((DoubleConstant) left).Value +
474 ((DoubleConstant) right).Value);
476 result = new DoubleConstant (res);
477 } else if (left is FloatConstant){
480 if (ec.ConstantCheckState)
481 res = checked (((FloatConstant) left).Value +
482 ((FloatConstant) right).Value);
484 res = unchecked (((FloatConstant) left).Value +
485 ((FloatConstant) right).Value);
487 result = new FloatConstant (res);
488 } else if (left is ULongConstant){
491 if (ec.ConstantCheckState)
492 res = checked (((ULongConstant) left).Value +
493 ((ULongConstant) right).Value);
495 res = unchecked (((ULongConstant) left).Value +
496 ((ULongConstant) right).Value);
498 result = new ULongConstant (res);
499 } else if (left is LongConstant){
502 if (ec.ConstantCheckState)
503 res = checked (((LongConstant) left).Value +
504 ((LongConstant) right).Value);
506 res = unchecked (((LongConstant) left).Value +
507 ((LongConstant) right).Value);
509 result = new LongConstant (res);
510 } else if (left is UIntConstant){
513 if (ec.ConstantCheckState)
514 res = checked (((UIntConstant) left).Value +
515 ((UIntConstant) right).Value);
517 res = unchecked (((UIntConstant) left).Value +
518 ((UIntConstant) right).Value);
520 result = new UIntConstant (res);
521 } else if (left is IntConstant){
524 if (ec.ConstantCheckState)
525 res = checked (((IntConstant) left).Value +
526 ((IntConstant) right).Value);
528 res = unchecked (((IntConstant) left).Value +
529 ((IntConstant) right).Value);
531 result = new IntConstant (res);
532 } else if (left is DecimalConstant) {
535 if (ec.ConstantCheckState)
536 res = checked (((DecimalConstant) left).Value +
537 ((DecimalConstant) right).Value);
539 res = unchecked (((DecimalConstant) left).Value +
540 ((DecimalConstant) right).Value);
542 result = new DecimalConstant (res);
544 throw new Exception ( "Unexepected addition input: " + left);
546 } catch (OverflowException){
547 Error_CompileTimeOverflow (loc);
551 return new EnumConstant (result, wrap_as);
555 case Binary.Operator.Subtraction:
557 // handle "E operator - (E x, U y)"
558 // handle "E operator - (Y y, E x)"
559 // handle "U operator - (E x, E y)"
562 if (left is EnumConstant){
563 if (right is EnumConstant){
564 if (left.Type == right.Type)
565 wrap_as = TypeManager.EnumToUnderlying (left.Type);
569 if (((EnumConstant) left).Child.Type != right.Type)
573 } else if (right is EnumConstant){
574 if (((EnumConstant) right).Child.Type != left.Type)
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);
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);
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);
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);
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);
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);
651 throw new Exception ( "Unexepected subtraction input: " + left);
653 } catch (OverflowException){
654 Error_CompileTimeOverflow (loc);
657 return new EnumConstant (result, wrap_as);
661 case Binary.Operator.Multiply:
662 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
663 if (left == null || right == null)
667 if (left is DoubleConstant){
670 if (ec.ConstantCheckState)
671 res = checked (((DoubleConstant) left).Value *
672 ((DoubleConstant) right).Value);
674 res = unchecked (((DoubleConstant) left).Value *
675 ((DoubleConstant) right).Value);
677 return new DoubleConstant (res);
678 } else if (left is FloatConstant){
681 if (ec.ConstantCheckState)
682 res = checked (((FloatConstant) left).Value *
683 ((FloatConstant) right).Value);
685 res = unchecked (((FloatConstant) left).Value *
686 ((FloatConstant) right).Value);
688 return new FloatConstant (res);
689 } else if (left is ULongConstant){
692 if (ec.ConstantCheckState)
693 res = checked (((ULongConstant) left).Value *
694 ((ULongConstant) right).Value);
696 res = unchecked (((ULongConstant) left).Value *
697 ((ULongConstant) right).Value);
699 return new ULongConstant (res);
700 } else if (left is LongConstant){
703 if (ec.ConstantCheckState)
704 res = checked (((LongConstant) left).Value *
705 ((LongConstant) right).Value);
707 res = unchecked (((LongConstant) left).Value *
708 ((LongConstant) right).Value);
710 return new LongConstant (res);
711 } else if (left is UIntConstant){
714 if (ec.ConstantCheckState)
715 res = checked (((UIntConstant) left).Value *
716 ((UIntConstant) right).Value);
718 res = unchecked (((UIntConstant) left).Value *
719 ((UIntConstant) right).Value);
721 return new UIntConstant (res);
722 } else if (left is IntConstant){
725 if (ec.ConstantCheckState)
726 res = checked (((IntConstant) left).Value *
727 ((IntConstant) right).Value);
729 res = unchecked (((IntConstant) left).Value *
730 ((IntConstant) right).Value);
732 return new IntConstant (res);
733 } else if (left is DecimalConstant) {
736 if (ec.ConstantCheckState)
737 res = checked (((DecimalConstant) left).Value *
738 ((DecimalConstant) right).Value);
740 res = unchecked (((DecimalConstant) left).Value *
741 ((DecimalConstant) right).Value);
743 return new DecimalConstant (res);
745 throw new Exception ( "Unexepected multiply input: " + left);
747 } catch (OverflowException){
748 Error_CompileTimeOverflow (loc);
752 case Binary.Operator.Division:
753 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
754 if (left == null || right == null)
758 if (left is DoubleConstant){
761 if (ec.ConstantCheckState)
762 res = checked (((DoubleConstant) left).Value /
763 ((DoubleConstant) right).Value);
765 res = unchecked (((DoubleConstant) left).Value /
766 ((DoubleConstant) right).Value);
768 return new DoubleConstant (res);
769 } else if (left is FloatConstant){
772 if (ec.ConstantCheckState)
773 res = checked (((FloatConstant) left).Value /
774 ((FloatConstant) right).Value);
776 res = unchecked (((FloatConstant) left).Value /
777 ((FloatConstant) right).Value);
779 return new FloatConstant (res);
780 } else if (left is ULongConstant){
783 if (ec.ConstantCheckState)
784 res = checked (((ULongConstant) left).Value /
785 ((ULongConstant) right).Value);
787 res = unchecked (((ULongConstant) left).Value /
788 ((ULongConstant) right).Value);
790 return new ULongConstant (res);
791 } else if (left is LongConstant){
794 if (ec.ConstantCheckState)
795 res = checked (((LongConstant) left).Value /
796 ((LongConstant) right).Value);
798 res = unchecked (((LongConstant) left).Value /
799 ((LongConstant) right).Value);
801 return new LongConstant (res);
802 } else if (left is UIntConstant){
805 if (ec.ConstantCheckState)
806 res = checked (((UIntConstant) left).Value /
807 ((UIntConstant) right).Value);
809 res = unchecked (((UIntConstant) left).Value /
810 ((UIntConstant) right).Value);
812 return new UIntConstant (res);
813 } else if (left is IntConstant){
816 if (ec.ConstantCheckState)
817 res = checked (((IntConstant) left).Value /
818 ((IntConstant) right).Value);
820 res = unchecked (((IntConstant) left).Value /
821 ((IntConstant) right).Value);
823 return new IntConstant (res);
824 } else if (left is DecimalConstant) {
827 if (ec.ConstantCheckState)
828 res = checked (((DecimalConstant) left).Value /
829 ((DecimalConstant) right).Value);
831 res = unchecked (((DecimalConstant) left).Value /
832 ((DecimalConstant) right).Value);
834 return new DecimalConstant (res);
836 throw new Exception ( "Unexepected division input: " + left);
838 } catch (OverflowException){
839 Error_CompileTimeOverflow (loc);
841 } catch (DivideByZeroException) {
842 Report.Error (020, loc, "Division by constant zero");
847 case Binary.Operator.Modulus:
848 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
849 if (left == null || right == null)
853 if (left is DoubleConstant){
856 if (ec.ConstantCheckState)
857 res = checked (((DoubleConstant) left).Value %
858 ((DoubleConstant) right).Value);
860 res = unchecked (((DoubleConstant) left).Value %
861 ((DoubleConstant) right).Value);
863 return new DoubleConstant (res);
864 } else if (left is FloatConstant){
867 if (ec.ConstantCheckState)
868 res = checked (((FloatConstant) left).Value %
869 ((FloatConstant) right).Value);
871 res = unchecked (((FloatConstant) left).Value %
872 ((FloatConstant) right).Value);
874 return new FloatConstant (res);
875 } else if (left is ULongConstant){
878 if (ec.ConstantCheckState)
879 res = checked (((ULongConstant) left).Value %
880 ((ULongConstant) right).Value);
882 res = unchecked (((ULongConstant) left).Value %
883 ((ULongConstant) right).Value);
885 return new ULongConstant (res);
886 } else if (left is LongConstant){
889 if (ec.ConstantCheckState)
890 res = checked (((LongConstant) left).Value %
891 ((LongConstant) right).Value);
893 res = unchecked (((LongConstant) left).Value %
894 ((LongConstant) right).Value);
896 return new LongConstant (res);
897 } else if (left is UIntConstant){
900 if (ec.ConstantCheckState)
901 res = checked (((UIntConstant) left).Value %
902 ((UIntConstant) right).Value);
904 res = unchecked (((UIntConstant) left).Value %
905 ((UIntConstant) right).Value);
907 return new UIntConstant (res);
908 } else if (left is IntConstant){
911 if (ec.ConstantCheckState)
912 res = checked (((IntConstant) left).Value %
913 ((IntConstant) right).Value);
915 res = unchecked (((IntConstant) left).Value %
916 ((IntConstant) right).Value);
918 return new IntConstant (res);
920 throw new Exception ( "Unexepected modulus input: " + left);
922 } catch (DivideByZeroException){
923 Report.Error (020, loc, "Division by constant zero");
924 } catch (OverflowException){
925 Error_CompileTimeOverflow (loc);
930 // There is no overflow checking on left shift
932 case Binary.Operator.LeftShift:
933 IntConstant ic = right.ToInt (loc);
935 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
938 int lshift_val = ic.Value;
941 if ((lic = left.ConvertToInt ()) != null)
942 return new IntConstant (lic.Value << lshift_val);
945 if ((luic = left.ConvertToUInt ()) != null)
946 return new UIntConstant (luic.Value << lshift_val);
949 if ((llc = left.ConvertToLong ()) != null)
950 return new LongConstant (llc.Value << lshift_val);
953 if ((lulc = left.ConvertToULong ()) != null)
954 return new ULongConstant (lulc.Value << lshift_val);
956 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
960 // There is no overflow checking on right shift
962 case Binary.Operator.RightShift:
963 IntConstant sic = right.ToInt (loc);
965 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
968 int rshift_val = sic.Value;
971 if ((ric = left.ConvertToInt ()) != null)
972 return new IntConstant (ric.Value >> rshift_val);
975 if ((ruic = left.ConvertToUInt ()) != null)
976 return new UIntConstant (ruic.Value >> rshift_val);
979 if ((rlc = left.ConvertToLong ()) != null)
980 return new LongConstant (rlc.Value >> rshift_val);
983 if ((rulc = left.ConvertToULong ()) != null)
984 return new ULongConstant (rulc.Value >> rshift_val);
986 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
989 case Binary.Operator.LogicalAnd:
990 if (left is BoolConstant && right is BoolConstant){
991 return new BoolConstant (
992 ((BoolConstant) left).Value &&
993 ((BoolConstant) right).Value);
997 case Binary.Operator.LogicalOr:
998 if (left is BoolConstant && right is BoolConstant){
999 return new BoolConstant (
1000 ((BoolConstant) left).Value ||
1001 ((BoolConstant) right).Value);
1005 case Binary.Operator.Equality:
1006 if (left is BoolConstant && right is BoolConstant){
1007 return new BoolConstant (
1008 ((BoolConstant) left).Value ==
1009 ((BoolConstant) right).Value);
1012 if (left is NullLiteral){
1013 if (right is NullLiteral)
1014 return new BoolConstant (true);
1015 else if (right is StringConstant)
1016 return new BoolConstant (
1017 ((StringConstant) right).Value == null);
1018 } else if (right is NullLiteral){
1019 if (left is NullLiteral)
1020 return new BoolConstant (true);
1021 else if (left is StringConstant)
1022 return new BoolConstant (
1023 ((StringConstant) left).Value == null);
1025 if (left is StringConstant && right is StringConstant){
1026 return new BoolConstant (
1027 ((StringConstant) left).Value ==
1028 ((StringConstant) right).Value);
1032 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1033 if (left == null || right == null)
1037 if (left is DoubleConstant)
1038 bool_res = ((DoubleConstant) left).Value ==
1039 ((DoubleConstant) right).Value;
1040 else if (left is FloatConstant)
1041 bool_res = ((FloatConstant) left).Value ==
1042 ((FloatConstant) right).Value;
1043 else if (left is ULongConstant)
1044 bool_res = ((ULongConstant) left).Value ==
1045 ((ULongConstant) right).Value;
1046 else if (left is LongConstant)
1047 bool_res = ((LongConstant) left).Value ==
1048 ((LongConstant) right).Value;
1049 else if (left is UIntConstant)
1050 bool_res = ((UIntConstant) left).Value ==
1051 ((UIntConstant) right).Value;
1052 else if (left is IntConstant)
1053 bool_res = ((IntConstant) left).Value ==
1054 ((IntConstant) right).Value;
1058 return new BoolConstant (bool_res);
1060 case Binary.Operator.Inequality:
1061 if (left is BoolConstant && right is BoolConstant){
1062 return new BoolConstant (
1063 ((BoolConstant) left).Value !=
1064 ((BoolConstant) right).Value);
1066 if (left is NullLiteral){
1067 if (right is NullLiteral)
1068 return new BoolConstant (false);
1069 else if (right is StringConstant)
1070 return new BoolConstant (
1071 ((StringConstant) right).Value != null);
1072 } else if (right is NullLiteral){
1073 if (left is NullLiteral)
1074 return new BoolConstant (false);
1075 else if (left is StringConstant)
1076 return new BoolConstant (
1077 ((StringConstant) left).Value != null);
1079 if (left is StringConstant && right is StringConstant){
1080 return new BoolConstant (
1081 ((StringConstant) left).Value !=
1082 ((StringConstant) right).Value);
1085 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1086 if (left == null || right == null)
1090 if (left is DoubleConstant)
1091 bool_res = ((DoubleConstant) left).Value !=
1092 ((DoubleConstant) right).Value;
1093 else if (left is FloatConstant)
1094 bool_res = ((FloatConstant) left).Value !=
1095 ((FloatConstant) right).Value;
1096 else if (left is ULongConstant)
1097 bool_res = ((ULongConstant) left).Value !=
1098 ((ULongConstant) right).Value;
1099 else if (left is LongConstant)
1100 bool_res = ((LongConstant) left).Value !=
1101 ((LongConstant) right).Value;
1102 else if (left is UIntConstant)
1103 bool_res = ((UIntConstant) left).Value !=
1104 ((UIntConstant) right).Value;
1105 else if (left is IntConstant)
1106 bool_res = ((IntConstant) left).Value !=
1107 ((IntConstant) right).Value;
1111 return new BoolConstant (bool_res);
1113 case Binary.Operator.LessThan:
1114 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1115 if (left == null || right == null)
1119 if (left is DoubleConstant)
1120 bool_res = ((DoubleConstant) left).Value <
1121 ((DoubleConstant) right).Value;
1122 else if (left is FloatConstant)
1123 bool_res = ((FloatConstant) left).Value <
1124 ((FloatConstant) right).Value;
1125 else if (left is ULongConstant)
1126 bool_res = ((ULongConstant) left).Value <
1127 ((ULongConstant) right).Value;
1128 else if (left is LongConstant)
1129 bool_res = ((LongConstant) left).Value <
1130 ((LongConstant) right).Value;
1131 else if (left is UIntConstant)
1132 bool_res = ((UIntConstant) left).Value <
1133 ((UIntConstant) right).Value;
1134 else if (left is IntConstant)
1135 bool_res = ((IntConstant) left).Value <
1136 ((IntConstant) right).Value;
1140 return new BoolConstant (bool_res);
1142 case Binary.Operator.GreaterThan:
1143 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1144 if (left == null || right == null)
1148 if (left is DoubleConstant)
1149 bool_res = ((DoubleConstant) left).Value >
1150 ((DoubleConstant) right).Value;
1151 else if (left is FloatConstant)
1152 bool_res = ((FloatConstant) left).Value >
1153 ((FloatConstant) right).Value;
1154 else if (left is ULongConstant)
1155 bool_res = ((ULongConstant) left).Value >
1156 ((ULongConstant) right).Value;
1157 else if (left is LongConstant)
1158 bool_res = ((LongConstant) left).Value >
1159 ((LongConstant) right).Value;
1160 else if (left is UIntConstant)
1161 bool_res = ((UIntConstant) left).Value >
1162 ((UIntConstant) right).Value;
1163 else if (left is IntConstant)
1164 bool_res = ((IntConstant) left).Value >
1165 ((IntConstant) right).Value;
1169 return new BoolConstant (bool_res);
1171 case Binary.Operator.GreaterThanOrEqual:
1172 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1173 if (left == null || right == null)
1177 if (left is DoubleConstant)
1178 bool_res = ((DoubleConstant) left).Value >=
1179 ((DoubleConstant) right).Value;
1180 else if (left is FloatConstant)
1181 bool_res = ((FloatConstant) left).Value >=
1182 ((FloatConstant) right).Value;
1183 else if (left is ULongConstant)
1184 bool_res = ((ULongConstant) left).Value >=
1185 ((ULongConstant) right).Value;
1186 else if (left is LongConstant)
1187 bool_res = ((LongConstant) left).Value >=
1188 ((LongConstant) right).Value;
1189 else if (left is UIntConstant)
1190 bool_res = ((UIntConstant) left).Value >=
1191 ((UIntConstant) right).Value;
1192 else if (left is IntConstant)
1193 bool_res = ((IntConstant) left).Value >=
1194 ((IntConstant) right).Value;
1198 return new BoolConstant (bool_res);
1200 case Binary.Operator.LessThanOrEqual:
1201 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1202 if (left == null || right == null)
1206 if (left is DoubleConstant)
1207 bool_res = ((DoubleConstant) left).Value <=
1208 ((DoubleConstant) right).Value;
1209 else if (left is FloatConstant)
1210 bool_res = ((FloatConstant) left).Value <=
1211 ((FloatConstant) right).Value;
1212 else if (left is ULongConstant)
1213 bool_res = ((ULongConstant) left).Value <=
1214 ((ULongConstant) right).Value;
1215 else if (left is LongConstant)
1216 bool_res = ((LongConstant) left).Value <=
1217 ((LongConstant) right).Value;
1218 else if (left is UIntConstant)
1219 bool_res = ((UIntConstant) left).Value <=
1220 ((UIntConstant) right).Value;
1221 else if (left is IntConstant)
1222 bool_res = ((IntConstant) left).Value <=
1223 ((IntConstant) right).Value;
1227 return new BoolConstant (bool_res);