2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2002 Ximian, Inc.
12 namespace Mono.MonoBASIC {
14 public class ConstantFold {
16 static public Constant ConvertNothingToDefaultConst (EmitContext ec,
17 Type target_type, Location loc)
19 switch (Type.GetTypeCode (target_type)) {
20 case TypeCode.Boolean :
21 return new BoolConstant (false);
23 return new ByteConstant (0);
25 return new CharConstant ((char)0);
27 return new SByteConstant (0);
29 return new ShortConstant (0);
31 return new IntConstant (0);
33 return new LongConstant (0);
34 case TypeCode.Decimal :
35 return new DecimalConstant (System.Decimal.Zero);
36 case TypeCode.Single :
37 return new FloatConstant (0.0F);
38 case TypeCode.Double :
39 return new DoubleConstant (0.0);
47 // Performs the numeric promotions on the left and right expresions
48 // and desposits the results on `lc' and `rc'.
50 // On success, the types of `lc' and `rc' on output will always match,
51 // and the pair will be one of:
60 static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
61 ref Constant left, ref Constant right,
65 Type conv_left_as = null;
66 Type conv_right_as = null;
71 if (left is NullLiteral)
73 if (right is NullLiteral)
76 if (conv_left_as != null)
77 left = ConvertNothingToDefaultConst (ec, conv_left_as, loc);
78 if (conv_right_as != null)
79 right = ConvertNothingToDefaultConst (ec, conv_right_as, loc);
80 if (left is DoubleConstant || right is DoubleConstant ||
81 oper == Binary.Operator.Exponentiation || oper == Binary.Operator.Division) {
83 // If either side is a double, convert the other to a double
85 if (!(left is DoubleConstant))
86 left = left.ToDouble (loc);
88 if (!(right is DoubleConstant))
89 right = right.ToDouble (loc);
91 } else if (left is FloatConstant || right is FloatConstant) {
93 // If either side is a float, convert the other to a float
95 if (!(left is FloatConstant))
96 left = left.ToFloat (loc);
98 if (!(right is FloatConstant))
99 right = right.ToFloat (loc);
101 } else if (left is ULongConstant || right is ULongConstant){
103 // If either operand is of type ulong, the other operand is
104 // converted to type ulong. or an error ocurrs if the other
105 // operand is of type sbyte, short, int or long
108 Constant match, other;
111 if (left is ULongConstant){
116 if (!(right is ULongConstant))
117 right = right.ToULong (loc);
123 left = left.ToULong (loc);
127 if (other is SByteConstant || other is ShortConstant ||
128 other is IntConstant || other is LongConstant){
129 Binary.Error_OperatorAmbiguous
130 (loc, oper, other.Type, match.Type);
136 } else if (left is LongConstant || right is LongConstant){
138 // If either operand is of type long, the other operand is converted
141 if (!(left is LongConstant))
142 left = left.ToLong (loc);
143 else if (!(right is LongConstant))
144 right = right.ToLong (loc);
146 } else if (left is UIntConstant || right is UIntConstant){
148 // If either operand is of type uint, and the other
149 // operand is of type sbyte, short or int, the operands are
150 // converted to type long.
153 if (left is UIntConstant){
160 if (other is UIntConstant)
163 if (other is SByteConstant || other is ShortConstant ||
164 other is IntConstant){
165 left = left.ToLong (loc);
166 right = right.ToLong (loc);
170 } else if (left is EnumConstant || right is EnumConstant){
172 // If either operand is an enum constant, the other one must
173 // be implicitly convertable to that enum's underlying type.
177 if (left is EnumConstant){
179 match = (EnumConstant) left;
182 match = (EnumConstant) right;
185 bool need_check = (other is EnumConstant) ||
186 ((oper != Binary.Operator.Addition) &&
187 (oper != Binary.Operator.Subtraction));
190 !Expression.ImplicitConversionExists (ec, match, other.Type)) {
191 Expression.Error_CannotConvertImplicit (loc, match.Type, other.Type);
197 if (left is EnumConstant)
198 left = ((EnumConstant) left).Child;
199 if (right is EnumConstant)
200 right = ((EnumConstant) right).Child;
205 // Force conversions to int32
207 if (!(left is IntConstant))
208 left = left.ToInt (loc);
209 if (!(right is IntConstant))
210 right = right.ToInt (loc);
215 static void Error_CompileTimeOverflow (Location loc)
217 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
221 /// Constant expression folder for binary operations.
223 /// Returns null if the expression can not be folded.
225 static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
226 Constant left, Constant right, Location loc)
229 Type rt = right.Type;
230 Type result_type = null;
234 // Enumerator folding
236 if (rt == lt && left is EnumConstant)
240 // During an enum evaluation, we need to unwrap enumerations
242 if (ec.InEnumContext){
243 if (left is EnumConstant)
244 left = ((EnumConstant) left).Child;
246 if (right is EnumConstant)
247 right = ((EnumConstant) right).Child;
251 Constant result = null;
253 case Binary.Operator.BitwiseOr:
254 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
255 if (left == null || right == null)
258 if (left is IntConstant){
260 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
262 v = new IntConstant (res);
263 if (result_type == null)
266 return new EnumConstant (v, result_type);
267 } else if (left is UIntConstant){
269 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
271 v = new UIntConstant (res);
272 if (result_type == null)
275 return new EnumConstant (v, result_type);
276 } else if (left is LongConstant){
278 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
280 v = new LongConstant (res);
281 if (result_type == null)
284 return new EnumConstant (v, result_type);
285 } else if (left is ULongConstant){
287 ulong res = ((ULongConstant)left).Value |
288 ((ULongConstant)right).Value;
290 v = new ULongConstant (res);
291 if (result_type == null)
294 return new EnumConstant (v, result_type);
298 case Binary.Operator.BitwiseAnd:
299 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
300 if (left == null || right == null)
303 if (left is IntConstant){
305 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
307 v = new IntConstant (res);
308 if (result_type == null)
311 return new EnumConstant (v, result_type);
312 } else if (left is UIntConstant){
314 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
316 v = new UIntConstant (res);
317 if (result_type == null)
320 return new EnumConstant (v, result_type);
321 } else if (left is LongConstant){
323 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
325 v = new LongConstant (res);
326 if (result_type == null)
329 return new EnumConstant (v, result_type);
330 } else if (left is ULongConstant){
332 ulong res = ((ULongConstant)left).Value &
333 ((ULongConstant)right).Value;
335 v = new ULongConstant (res);
336 if (result_type == null)
339 return new EnumConstant (v, result_type);
343 case Binary.Operator.ExclusiveOr:
344 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
345 if (left == null || right == null)
348 if (left is IntConstant){
350 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
352 v = new IntConstant (res);
353 if (result_type == null)
356 return new EnumConstant (v, result_type);
357 } else if (left is UIntConstant){
359 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
361 v = new UIntConstant (res);
362 if (result_type == null)
365 return new EnumConstant (v, result_type);
366 } else if (left is LongConstant){
368 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
370 v = new LongConstant (res);
371 if (result_type == null)
374 return new EnumConstant (v, result_type);
375 } else if (left is ULongConstant){
377 ulong res = ((ULongConstant)left).Value ^
378 ((ULongConstant)right).Value;
380 v = new ULongConstant (res);
381 if (result_type == null)
384 return new EnumConstant (v, result_type);
388 case Binary.Operator.Addition:
389 bool left_is_string = left is StringConstant;
390 bool right_is_string = right is StringConstant;
393 // If both sides are strings, then concatenate, if
394 // one is a string, and the other is not, then defer
395 // to runtime concatenation
398 if (left_is_string || right_is_string){
399 if (left_is_string && right_is_string)
400 return new StringConstant (
401 ((StringConstant) left).Value +
402 ((StringConstant) right).Value);
408 // handle "E operator + (E x, U y)"
409 // handle "E operator + (Y y, E x)"
411 // note that E operator + (E x, E y) is invalid
413 if (left is EnumConstant){
414 if (right is EnumConstant){
417 if (((EnumConstant) left).Child.Type != right.Type)
421 } else if (right is EnumConstant){
422 if (((EnumConstant) right).Child.Type != left.Type)
424 wrap_as = right.Type;
428 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
429 if (left == null || right == null)
433 if (left is DoubleConstant){
436 if (ec.ConstantCheckState)
437 res = checked (((DoubleConstant) left).Value +
438 ((DoubleConstant) right).Value);
440 res = unchecked (((DoubleConstant) left).Value +
441 ((DoubleConstant) right).Value);
443 result = new DoubleConstant (res);
444 } else if (left is FloatConstant){
447 if (ec.ConstantCheckState)
448 res = checked (((FloatConstant) left).Value +
449 ((FloatConstant) right).Value);
451 res = unchecked (((FloatConstant) left).Value +
452 ((FloatConstant) right).Value);
454 result = new FloatConstant (res);
455 } else if (left is ULongConstant){
458 if (ec.ConstantCheckState)
459 res = checked (((ULongConstant) left).Value +
460 ((ULongConstant) right).Value);
462 res = unchecked (((ULongConstant) left).Value +
463 ((ULongConstant) right).Value);
465 result = new ULongConstant (res);
466 } else if (left is LongConstant){
469 if (ec.ConstantCheckState)
470 res = checked (((LongConstant) left).Value +
471 ((LongConstant) right).Value);
473 res = unchecked (((LongConstant) left).Value +
474 ((LongConstant) right).Value);
476 result = new LongConstant (res);
477 } else if (left is UIntConstant){
480 if (ec.ConstantCheckState)
481 res = checked (((UIntConstant) left).Value +
482 ((UIntConstant) right).Value);
484 res = unchecked (((UIntConstant) left).Value +
485 ((UIntConstant) right).Value);
487 result = new UIntConstant (res);
488 } else if (left is IntConstant){
491 if (ec.ConstantCheckState)
492 res = checked (((IntConstant) left).Value +
493 ((IntConstant) right).Value);
495 res = unchecked (((IntConstant) left).Value +
496 ((IntConstant) right).Value);
498 result = new IntConstant (res);
500 throw new Exception ( "Unexepected input: " + left);
502 } catch (OverflowException){
503 Error_CompileTimeOverflow (loc);
507 return new EnumConstant (result, wrap_as);
511 case Binary.Operator.Subtraction:
513 // handle "E operator - (E x, U y)"
514 // handle "E operator - (Y y, E x)"
515 // handle "U operator - (E x, E y)"
518 if (left is EnumConstant){
519 if (right is EnumConstant){
520 if (left.Type == right.Type)
521 wrap_as = TypeManager.EnumToUnderlying (left.Type);
525 if (((EnumConstant) left).Child.Type != right.Type)
529 } else if (right is EnumConstant){
530 if (((EnumConstant) right).Child.Type != left.Type)
532 wrap_as = right.Type;
535 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
536 if (left == null || right == null)
540 if (left is DoubleConstant){
543 if (ec.ConstantCheckState)
544 res = checked (((DoubleConstant) left).Value -
545 ((DoubleConstant) right).Value);
547 res = unchecked (((DoubleConstant) left).Value -
548 ((DoubleConstant) right).Value);
550 result = new DoubleConstant (res);
551 } else if (left is FloatConstant){
554 if (ec.ConstantCheckState)
555 res = checked (((FloatConstant) left).Value -
556 ((FloatConstant) right).Value);
558 res = unchecked (((FloatConstant) left).Value -
559 ((FloatConstant) right).Value);
561 result = new FloatConstant (res);
562 } else if (left is ULongConstant){
565 if (ec.ConstantCheckState)
566 res = checked (((ULongConstant) left).Value -
567 ((ULongConstant) right).Value);
569 res = unchecked (((ULongConstant) left).Value -
570 ((ULongConstant) right).Value);
572 result = new ULongConstant (res);
573 } else if (left is LongConstant){
576 if (ec.ConstantCheckState)
577 res = checked (((LongConstant) left).Value -
578 ((LongConstant) right).Value);
580 res = unchecked (((LongConstant) left).Value -
581 ((LongConstant) right).Value);
583 result = new LongConstant (res);
584 } else if (left is UIntConstant){
587 if (ec.ConstantCheckState)
588 res = checked (((UIntConstant) left).Value -
589 ((UIntConstant) right).Value);
591 res = unchecked (((UIntConstant) left).Value -
592 ((UIntConstant) right).Value);
594 result = new UIntConstant (res);
595 } else if (left is IntConstant){
598 if (ec.ConstantCheckState)
599 res = checked (((IntConstant) left).Value -
600 ((IntConstant) right).Value);
602 res = unchecked (((IntConstant) left).Value -
603 ((IntConstant) right).Value);
605 result = new IntConstant (res);
607 throw new Exception ( "Unexepected input: " + left);
609 } catch (OverflowException){
610 Error_CompileTimeOverflow (loc);
613 return new EnumConstant (result, wrap_as);
617 case Binary.Operator.Multiply:
618 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
619 if (left == null || right == null)
623 if (left is DoubleConstant){
626 if (ec.ConstantCheckState)
627 res = checked (((DoubleConstant) left).Value *
628 ((DoubleConstant) right).Value);
630 res = unchecked (((DoubleConstant) left).Value *
631 ((DoubleConstant) right).Value);
633 return new DoubleConstant (res);
634 } else if (left is FloatConstant){
637 if (ec.ConstantCheckState)
638 res = checked (((FloatConstant) left).Value *
639 ((FloatConstant) right).Value);
641 res = unchecked (((FloatConstant) left).Value *
642 ((FloatConstant) right).Value);
644 return new FloatConstant (res);
645 } else if (left is ULongConstant){
648 if (ec.ConstantCheckState)
649 res = checked (((ULongConstant) left).Value *
650 ((ULongConstant) right).Value);
652 res = unchecked (((ULongConstant) left).Value *
653 ((ULongConstant) right).Value);
655 return new ULongConstant (res);
656 } else if (left is LongConstant){
659 if (ec.ConstantCheckState)
660 res = checked (((LongConstant) left).Value *
661 ((LongConstant) right).Value);
663 res = unchecked (((LongConstant) left).Value *
664 ((LongConstant) right).Value);
666 return new LongConstant (res);
667 } else if (left is UIntConstant){
670 if (ec.ConstantCheckState)
671 res = checked (((UIntConstant) left).Value *
672 ((UIntConstant) right).Value);
674 res = unchecked (((UIntConstant) left).Value *
675 ((UIntConstant) right).Value);
677 return new UIntConstant (res);
678 } else if (left is IntConstant){
681 if (ec.ConstantCheckState)
682 res = checked (((IntConstant) left).Value *
683 ((IntConstant) right).Value);
685 res = unchecked (((IntConstant) left).Value *
686 ((IntConstant) right).Value);
688 return new IntConstant (res);
690 throw new Exception ( "Unexepected input: " + left);
692 } catch (OverflowException){
693 Error_CompileTimeOverflow (loc);
697 case Binary.Operator.IntDivision:
698 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
699 if (left == null || right == null)
703 if (Mono.MonoBASIC.Parser.OptionStrict && (!(left is LongConstant) && !(left is IntConstant)) )
705 Expression.Error_CannotConvertTypeStrict (left.Type, Type.GetType("System.Int64"), loc);
710 if (left is DoubleConstant) {
711 long left_val, right_val, res;
712 left_val = (long) ((DoubleConstant) left).Value;
713 right_val = (long) ((DoubleConstant) right).Value;
715 if (ec.ConstantCheckState)
716 res = checked (left_val / right_val);
718 res = unchecked (left_val / right_val);
720 return new LongConstant (res);
721 } else if (left is FloatConstant) {
722 long left_val, right_val, res;
723 left_val = (long) ((FloatConstant) left).Value;
724 right_val = (long) ((FloatConstant) right).Value;
726 if (ec.ConstantCheckState)
727 res = checked (left_val / right_val);
729 res = unchecked (left_val / right_val);
731 return new LongConstant (res);
732 } else if (left is DecimalConstant) {
733 long left_val, right_val, res;
734 left_val = (long) ((DecimalConstant) left).Value;
735 right_val = (long) ((DecimalConstant) right).Value;
737 if (ec.ConstantCheckState)
738 res = checked (left_val / right_val);
740 res = unchecked (left_val / right_val);
742 return new LongConstant (res);
743 } else if (left is LongConstant) {
746 if (ec.ConstantCheckState)
747 res = checked (((LongConstant) left).Value /
748 ((LongConstant) right).Value);
750 res = unchecked (((LongConstant) left).Value /
751 ((LongConstant) right).Value);
753 return new LongConstant (res);
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);
766 } catch (OverflowException){
767 Error_CompileTimeOverflow (loc);
769 } catch (DivideByZeroException) {
770 Report.Error (30542, loc, "Division by constant zero");
774 case Binary.Operator.Division:
775 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
776 if (left == null || right == null)
782 if (ec.ConstantCheckState)
783 res = checked (((DoubleConstant) left).Value /
784 ((DoubleConstant) right).Value);
786 res = unchecked (((DoubleConstant) left).Value /
787 ((DoubleConstant) right).Value);
789 return new DoubleConstant (res);
790 } catch (OverflowException){
791 Error_CompileTimeOverflow (loc);
793 } catch (DivideByZeroException) {
794 Report.Error (30542, loc, "Division by constant zero");
799 case Binary.Operator.Modulus:
800 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
801 if (left == null || right == null)
805 if (left is DoubleConstant){
808 if (ec.ConstantCheckState)
809 res = checked (((DoubleConstant) left).Value %
810 ((DoubleConstant) right).Value);
812 res = unchecked (((DoubleConstant) left).Value %
813 ((DoubleConstant) right).Value);
815 return new DoubleConstant (res);
816 } else if (left is FloatConstant){
819 if (ec.ConstantCheckState)
820 res = checked (((FloatConstant) left).Value %
821 ((FloatConstant) right).Value);
823 res = unchecked (((FloatConstant) left).Value %
824 ((FloatConstant) right).Value);
826 return new FloatConstant (res);
827 } else if (left is ULongConstant){
830 if (ec.ConstantCheckState)
831 res = checked (((ULongConstant) left).Value %
832 ((ULongConstant) right).Value);
834 res = unchecked (((ULongConstant) left).Value %
835 ((ULongConstant) right).Value);
837 return new ULongConstant (res);
838 } else if (left is LongConstant){
841 if (ec.ConstantCheckState)
842 res = checked (((LongConstant) left).Value %
843 ((LongConstant) right).Value);
845 res = unchecked (((LongConstant) left).Value %
846 ((LongConstant) right).Value);
848 return new LongConstant (res);
849 } else if (left is UIntConstant){
852 if (ec.ConstantCheckState)
853 res = checked (((UIntConstant) left).Value %
854 ((UIntConstant) right).Value);
856 res = unchecked (((UIntConstant) left).Value %
857 ((UIntConstant) right).Value);
859 return new UIntConstant (res);
860 } else if (left is IntConstant){
863 if (ec.ConstantCheckState)
864 res = checked (((IntConstant) left).Value %
865 ((IntConstant) right).Value);
867 res = unchecked (((IntConstant) left).Value %
868 ((IntConstant) right).Value);
870 return new IntConstant (res);
872 throw new Exception ( "Unexepected input: " + left);
874 } catch (OverflowException){
875 Error_CompileTimeOverflow (loc);
877 } catch (DivideByZeroException) {
878 Report.Error (30542, loc, "Division by constant zero");
882 case Binary.Operator.Exponentiation:
883 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
884 if (left == null || right == null)
887 double powVal = System.Math.Pow(((DoubleConstant) left).Value,
888 ((DoubleConstant) right).Value);
890 return new DoubleConstant(powVal);
893 // There is no overflow checking on left shift
895 case Binary.Operator.LeftShift:
896 IntConstant ic = right.ToInt (loc);
898 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
901 int lshift_val = ic.Value;
904 if ((lic = left.ConvertToInt ()) != null)
905 return new IntConstant (lic.Value << lshift_val);
908 if ((luic = left.ConvertToUInt ()) != null)
909 return new UIntConstant (luic.Value << lshift_val);
912 if ((llc = left.ConvertToLong ()) != null)
913 return new LongConstant (llc.Value << lshift_val);
916 if ((lulc = left.ConvertToULong ()) != null)
917 return new ULongConstant (lulc.Value << lshift_val);
919 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
923 // There is no overflow checking on right shift
925 case Binary.Operator.RightShift:
926 IntConstant sic = right.ToInt (loc);
928 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
931 int rshift_val = sic.Value;
934 if ((ric = left.ConvertToInt ()) != null)
935 return new IntConstant (ric.Value >> rshift_val);
938 if ((ruic = left.ConvertToUInt ()) != null)
939 return new UIntConstant (ruic.Value >> rshift_val);
942 if ((rlc = left.ConvertToLong ()) != null)
943 return new LongConstant (rlc.Value >> rshift_val);
946 if ((rulc = left.ConvertToULong ()) != null)
947 return new ULongConstant (rulc.Value >> rshift_val);
949 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
952 case Binary.Operator.LogicalAnd:
953 if (left is BoolConstant && right is BoolConstant){
954 return new BoolConstant (
955 ((BoolConstant) left).Value &&
956 ((BoolConstant) right).Value);
960 case Binary.Operator.LogicalOr:
961 if (left is BoolConstant && right is BoolConstant){
962 return new BoolConstant (
963 ((BoolConstant) left).Value ||
964 ((BoolConstant) right).Value);
968 case Binary.Operator.Equality:
969 if (left is BoolConstant && right is BoolConstant){
970 return new BoolConstant (
971 ((BoolConstant) left).Value ==
972 ((BoolConstant) right).Value);
975 if (left is StringConstant && right is StringConstant){
976 return new BoolConstant (
977 ((StringConstant) left).Value ==
978 ((StringConstant) right).Value);
982 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
983 if (left == null || right == null)
987 if (left is DoubleConstant)
988 bool_res = ((DoubleConstant) left).Value ==
989 ((DoubleConstant) right).Value;
990 else if (left is FloatConstant)
991 bool_res = ((FloatConstant) left).Value ==
992 ((FloatConstant) right).Value;
993 else if (left is ULongConstant)
994 bool_res = ((ULongConstant) left).Value ==
995 ((ULongConstant) right).Value;
996 else if (left is LongConstant)
997 bool_res = ((LongConstant) left).Value ==
998 ((LongConstant) right).Value;
999 else if (left is UIntConstant)
1000 bool_res = ((UIntConstant) left).Value ==
1001 ((UIntConstant) right).Value;
1002 else if (left is IntConstant)
1003 bool_res = ((IntConstant) left).Value ==
1004 ((IntConstant) right).Value;
1008 return new BoolConstant (bool_res);
1010 case Binary.Operator.Inequality:
1011 if (left is BoolConstant && right is BoolConstant){
1012 return new BoolConstant (
1013 ((BoolConstant) left).Value !=
1014 ((BoolConstant) right).Value);
1016 if (left is StringConstant && right is StringConstant){
1017 return new BoolConstant (
1018 ((StringConstant) left).Value !=
1019 ((StringConstant) right).Value);
1022 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1023 if (left == null || right == null)
1027 if (left is DoubleConstant)
1028 bool_res = ((DoubleConstant) left).Value !=
1029 ((DoubleConstant) right).Value;
1030 else if (left is FloatConstant)
1031 bool_res = ((FloatConstant) left).Value !=
1032 ((FloatConstant) right).Value;
1033 else if (left is ULongConstant)
1034 bool_res = ((ULongConstant) left).Value !=
1035 ((ULongConstant) right).Value;
1036 else if (left is LongConstant)
1037 bool_res = ((LongConstant) left).Value !=
1038 ((LongConstant) right).Value;
1039 else if (left is UIntConstant)
1040 bool_res = ((UIntConstant) left).Value !=
1041 ((UIntConstant) right).Value;
1042 else if (left is IntConstant)
1043 bool_res = ((IntConstant) left).Value !=
1044 ((IntConstant) right).Value;
1048 return new BoolConstant (bool_res);
1050 case Binary.Operator.LessThan:
1051 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1052 if (left == null || right == null)
1056 if (left is DoubleConstant)
1057 bool_res = ((DoubleConstant) left).Value <
1058 ((DoubleConstant) right).Value;
1059 else if (left is FloatConstant)
1060 bool_res = ((FloatConstant) left).Value <
1061 ((FloatConstant) right).Value;
1062 else if (left is ULongConstant)
1063 bool_res = ((ULongConstant) left).Value <
1064 ((ULongConstant) right).Value;
1065 else if (left is LongConstant)
1066 bool_res = ((LongConstant) left).Value <
1067 ((LongConstant) right).Value;
1068 else if (left is UIntConstant)
1069 bool_res = ((UIntConstant) left).Value <
1070 ((UIntConstant) right).Value;
1071 else if (left is IntConstant)
1072 bool_res = ((IntConstant) left).Value <
1073 ((IntConstant) right).Value;
1077 return new BoolConstant (bool_res);
1079 case Binary.Operator.GreaterThan:
1080 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1081 if (left == null || right == null)
1085 if (left is DoubleConstant)
1086 bool_res = ((DoubleConstant) left).Value >
1087 ((DoubleConstant) right).Value;
1088 else if (left is FloatConstant)
1089 bool_res = ((FloatConstant) left).Value >
1090 ((FloatConstant) right).Value;
1091 else if (left is ULongConstant)
1092 bool_res = ((ULongConstant) left).Value >
1093 ((ULongConstant) right).Value;
1094 else if (left is LongConstant)
1095 bool_res = ((LongConstant) left).Value >
1096 ((LongConstant) right).Value;
1097 else if (left is UIntConstant)
1098 bool_res = ((UIntConstant) left).Value >
1099 ((UIntConstant) right).Value;
1100 else if (left is IntConstant)
1101 bool_res = ((IntConstant) left).Value >
1102 ((IntConstant) right).Value;
1106 return new BoolConstant (bool_res);
1108 case Binary.Operator.GreaterThanOrEqual:
1109 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1110 if (left == null || right == null)
1114 if (left is DoubleConstant)
1115 bool_res = ((DoubleConstant) left).Value >=
1116 ((DoubleConstant) right).Value;
1117 else if (left is FloatConstant)
1118 bool_res = ((FloatConstant) left).Value >=
1119 ((FloatConstant) right).Value;
1120 else if (left is ULongConstant)
1121 bool_res = ((ULongConstant) left).Value >=
1122 ((ULongConstant) right).Value;
1123 else if (left is LongConstant)
1124 bool_res = ((LongConstant) left).Value >=
1125 ((LongConstant) right).Value;
1126 else if (left is UIntConstant)
1127 bool_res = ((UIntConstant) left).Value >=
1128 ((UIntConstant) right).Value;
1129 else if (left is IntConstant)
1130 bool_res = ((IntConstant) left).Value >=
1131 ((IntConstant) right).Value;
1135 return new BoolConstant (bool_res);
1137 case Binary.Operator.LessThanOrEqual:
1138 DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
1139 if (left == null || right == null)
1143 if (left is DoubleConstant)
1144 bool_res = ((DoubleConstant) left).Value <=
1145 ((DoubleConstant) right).Value;
1146 else if (left is FloatConstant)
1147 bool_res = ((FloatConstant) left).Value <=
1148 ((FloatConstant) right).Value;
1149 else if (left is ULongConstant)
1150 bool_res = ((ULongConstant) left).Value <=
1151 ((ULongConstant) right).Value;
1152 else if (left is LongConstant)
1153 bool_res = ((LongConstant) left).Value <=
1154 ((LongConstant) right).Value;
1155 else if (left is UIntConstant)
1156 bool_res = ((UIntConstant) left).Value <=
1157 ((UIntConstant) right).Value;
1158 else if (left is IntConstant)
1159 bool_res = ((IntConstant) left).Value <=
1160 ((IntConstant) right).Value;
1164 return new BoolConstant (bool_res);