2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Copyright 2002, 2003 Ximian, Inc.
9 // Copyright 2003-2008, Novell, Inc.
13 namespace Mono.CSharp {
15 public class ConstantFold {
17 public static readonly Type[] binary_promotions = new Type[] {
18 TypeManager.decimal_type, TypeManager.double_type, TypeManager.float_type,
19 TypeManager.uint64_type, TypeManager.int64_type, TypeManager.uint32_type };
22 // Performs the numeric promotions on the left and right expresions
23 // and deposits the results on `lc' and `rc'.
25 // On success, the types of `lc' and `rc' on output will always match,
26 // and the pair will be one of:
28 // TODO: BinaryFold should be called as an optimization step only,
29 // error checking here is weak
31 static bool DoBinaryNumericPromotions (ResolveContext rc, ref Constant left, ref Constant right)
33 Type ltype = left.Type;
34 Type rtype = right.Type;
36 foreach (Type t in binary_promotions) {
38 return t == rtype || ConvertPromotion (rc, ref right, ref left, t);
41 return t == ltype || ConvertPromotion (rc, ref left, ref right, t);
44 left = left.ConvertImplicitly (rc, TypeManager.int32_type);
45 right = right.ConvertImplicitly (rc, TypeManager.int32_type);
46 return left != null && right != null;
49 static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, Type type)
51 Constant c = prim.ConvertImplicitly (rc, type);
57 if (type == TypeManager.uint32_type) {
58 type = TypeManager.int64_type;
59 prim = prim.ConvertImplicitly (rc, type);
60 second = second.ConvertImplicitly (rc, type);
61 return prim != null && second != null;
67 internal static void Error_CompileTimeOverflow (ResolveContext rc, Location loc)
69 rc.Report.Error (220, loc, "The operation overflows at compile time in checked mode");
73 /// Constant expression folder for binary operations.
75 /// Returns null if the expression can not be folded.
77 static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper,
78 Constant left, Constant right, Location loc)
80 Constant result = null;
82 if (left is EmptyConstantCast)
83 return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);
85 if (left is SideEffectConstant) {
86 result = BinaryFold (ec, oper, ((SideEffectConstant) left).value, right, loc);
89 return new SideEffectConstant (result, left, loc);
92 if (right is EmptyConstantCast)
93 return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);
95 if (right is SideEffectConstant) {
96 result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).value, loc);
99 return new SideEffectConstant (result, right, loc);
103 Type rt = right.Type;
106 if (lt == TypeManager.bool_type && lt == rt) {
107 bool lv = (bool) left.GetValue ();
108 bool rv = (bool) right.GetValue ();
110 case Binary.Operator.BitwiseAnd:
111 case Binary.Operator.LogicalAnd:
112 return new BoolConstant (lv && rv, left.Location);
113 case Binary.Operator.BitwiseOr:
114 case Binary.Operator.LogicalOr:
115 return new BoolConstant (lv || rv, left.Location);
116 case Binary.Operator.ExclusiveOr:
117 return new BoolConstant (lv ^ rv, left.Location);
118 case Binary.Operator.Equality:
119 return new BoolConstant (lv == rv, left.Location);
120 case Binary.Operator.Inequality:
121 return new BoolConstant (lv != rv, left.Location);
127 // During an enum evaluation, none of the rules are valid
128 // Not sure whether it is bug in csc or in documentation
130 if (ec.HasSet (ResolveContext.Options.EnumScope)){
131 if (left is EnumConstant)
132 left = ((EnumConstant) left).Child;
134 if (right is EnumConstant)
135 right = ((EnumConstant) right).Child;
136 } else if (left is EnumConstant && rt == lt) {
139 /// E operator |(E x, E y);
140 /// E operator &(E x, E y);
141 /// E operator ^(E x, E y);
143 case Binary.Operator.BitwiseOr:
144 case Binary.Operator.BitwiseAnd:
145 case Binary.Operator.ExclusiveOr:
146 result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
148 result = result.Resolve (ec).TryReduce (ec, lt, loc);
152 /// U operator -(E x, E y);
154 case Binary.Operator.Subtraction:
155 result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
157 result = result.Resolve (ec).TryReduce (ec, ((EnumConstant)left).Child.Type, loc);
161 /// bool operator ==(E x, E y);
162 /// bool operator !=(E x, E y);
163 /// bool operator <(E x, E y);
164 /// bool operator >(E x, E y);
165 /// bool operator <=(E x, E y);
166 /// bool operator >=(E x, E y);
168 case Binary.Operator.Equality:
169 case Binary.Operator.Inequality:
170 case Binary.Operator.LessThan:
171 case Binary.Operator.GreaterThan:
172 case Binary.Operator.LessThanOrEqual:
173 case Binary.Operator.GreaterThanOrEqual:
174 return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
180 case Binary.Operator.BitwiseOr:
181 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
184 if (left is IntConstant){
185 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
187 return new IntConstant (res, left.Location);
189 if (left is UIntConstant){
190 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
192 return new UIntConstant (res, left.Location);
194 if (left is LongConstant){
195 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
197 return new LongConstant (res, left.Location);
199 if (left is ULongConstant){
200 ulong res = ((ULongConstant)left).Value |
201 ((ULongConstant)right).Value;
203 return new ULongConstant (res, left.Location);
207 case Binary.Operator.BitwiseAnd:
208 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
212 /// int operator &(int x, int y);
213 /// uint operator &(uint x, uint y);
214 /// long operator &(long x, long y);
215 /// ulong operator &(ulong x, ulong y);
217 if (left is IntConstant){
218 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
219 return new IntConstant (res, left.Location);
221 if (left is UIntConstant){
222 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
223 return new UIntConstant (res, left.Location);
225 if (left is LongConstant){
226 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
227 return new LongConstant (res, left.Location);
229 if (left is ULongConstant){
230 ulong res = ((ULongConstant)left).Value &
231 ((ULongConstant)right).Value;
233 return new ULongConstant (res, left.Location);
237 case Binary.Operator.ExclusiveOr:
238 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
241 if (left is IntConstant){
242 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
243 return new IntConstant (res, left.Location);
245 if (left is UIntConstant){
246 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
248 return new UIntConstant (res, left.Location);
250 if (left is LongConstant){
251 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
253 return new LongConstant (res, left.Location);
255 if (left is ULongConstant){
256 ulong res = ((ULongConstant)left).Value ^
257 ((ULongConstant)right).Value;
259 return new ULongConstant (res, left.Location);
263 case Binary.Operator.Addition:
264 if (lt == TypeManager.null_type)
267 if (rt == TypeManager.null_type)
271 // If both sides are strings, then concatenate, if
272 // one is a string, and the other is not, then defer
273 // to runtime concatenation
275 if (lt == TypeManager.string_type || rt == TypeManager.string_type){
277 return new StringConstant ((string)left.GetValue () + (string)right.GetValue (),
284 // handle "E operator + (E x, U y)"
285 // handle "E operator + (Y y, E x)"
287 EnumConstant lc = left as EnumConstant;
288 EnumConstant rc = right as EnumConstant;
289 if (lc != null || rc != null){
296 // U has to be implicitly convetible to E.base
297 right = right.ConvertImplicitly (ec, lc.Child.Type);
301 result = BinaryFold (ec, oper, lc.Child, right, loc);
305 result = result.Resolve (ec).TryReduce (ec, lt, loc);
309 return new EnumConstant (result, lt);
312 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
316 if (left is DoubleConstant){
319 if (ec.ConstantCheckState)
320 res = checked (((DoubleConstant) left).Value +
321 ((DoubleConstant) right).Value);
323 res = unchecked (((DoubleConstant) left).Value +
324 ((DoubleConstant) right).Value);
326 return new DoubleConstant (res, left.Location);
328 if (left is FloatConstant){
331 if (ec.ConstantCheckState)
332 res = checked (((FloatConstant) left).Value +
333 ((FloatConstant) right).Value);
335 res = unchecked (((FloatConstant) left).Value +
336 ((FloatConstant) right).Value);
338 result = new FloatConstant (res, left.Location);
339 } else if (left is ULongConstant){
342 if (ec.ConstantCheckState)
343 res = checked (((ULongConstant) left).Value +
344 ((ULongConstant) right).Value);
346 res = unchecked (((ULongConstant) left).Value +
347 ((ULongConstant) right).Value);
349 result = new ULongConstant (res, left.Location);
350 } else if (left is LongConstant){
353 if (ec.ConstantCheckState)
354 res = checked (((LongConstant) left).Value +
355 ((LongConstant) right).Value);
357 res = unchecked (((LongConstant) left).Value +
358 ((LongConstant) right).Value);
360 result = new LongConstant (res, left.Location);
361 } else if (left is UIntConstant){
364 if (ec.ConstantCheckState)
365 res = checked (((UIntConstant) left).Value +
366 ((UIntConstant) right).Value);
368 res = unchecked (((UIntConstant) left).Value +
369 ((UIntConstant) right).Value);
371 result = new UIntConstant (res, left.Location);
372 } else if (left is IntConstant){
375 if (ec.ConstantCheckState)
376 res = checked (((IntConstant) left).Value +
377 ((IntConstant) right).Value);
379 res = unchecked (((IntConstant) left).Value +
380 ((IntConstant) right).Value);
382 result = new IntConstant (res, left.Location);
383 } else if (left is DecimalConstant) {
386 if (ec.ConstantCheckState)
387 res = checked (((DecimalConstant) left).Value +
388 ((DecimalConstant) right).Value);
390 res = unchecked (((DecimalConstant) left).Value +
391 ((DecimalConstant) right).Value);
393 result = new DecimalConstant (res, left.Location);
395 } catch (OverflowException){
396 Error_CompileTimeOverflow (ec, loc);
401 case Binary.Operator.Subtraction:
403 // handle "E operator - (E x, U y)"
404 // handle "E operator - (Y y, E x)"
406 lc = left as EnumConstant;
407 rc = right as EnumConstant;
408 if (lc != null || rc != null){
415 // U has to be implicitly convetible to E.base
416 right = right.ConvertImplicitly (ec, lc.Child.Type);
420 result = BinaryFold (ec, oper, lc.Child, right, loc);
424 result = result.Resolve (ec).TryReduce (ec, lt, loc);
428 return new EnumConstant (result, lt);
431 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
435 if (left is DoubleConstant){
438 if (ec.ConstantCheckState)
439 res = checked (((DoubleConstant) left).Value -
440 ((DoubleConstant) right).Value);
442 res = unchecked (((DoubleConstant) left).Value -
443 ((DoubleConstant) right).Value);
445 result = new DoubleConstant (res, left.Location);
446 } else if (left is FloatConstant){
449 if (ec.ConstantCheckState)
450 res = checked (((FloatConstant) left).Value -
451 ((FloatConstant) right).Value);
453 res = unchecked (((FloatConstant) left).Value -
454 ((FloatConstant) right).Value);
456 result = new FloatConstant (res, left.Location);
457 } else if (left is ULongConstant){
460 if (ec.ConstantCheckState)
461 res = checked (((ULongConstant) left).Value -
462 ((ULongConstant) right).Value);
464 res = unchecked (((ULongConstant) left).Value -
465 ((ULongConstant) right).Value);
467 result = new ULongConstant (res, left.Location);
468 } else if (left is LongConstant){
471 if (ec.ConstantCheckState)
472 res = checked (((LongConstant) left).Value -
473 ((LongConstant) right).Value);
475 res = unchecked (((LongConstant) left).Value -
476 ((LongConstant) right).Value);
478 result = new LongConstant (res, left.Location);
479 } else if (left is UIntConstant){
482 if (ec.ConstantCheckState)
483 res = checked (((UIntConstant) left).Value -
484 ((UIntConstant) right).Value);
486 res = unchecked (((UIntConstant) left).Value -
487 ((UIntConstant) right).Value);
489 result = new UIntConstant (res, left.Location);
490 } else if (left is IntConstant){
493 if (ec.ConstantCheckState)
494 res = checked (((IntConstant) left).Value -
495 ((IntConstant) right).Value);
497 res = unchecked (((IntConstant) left).Value -
498 ((IntConstant) right).Value);
500 result = new IntConstant (res, left.Location);
501 } else if (left is DecimalConstant) {
504 if (ec.ConstantCheckState)
505 res = checked (((DecimalConstant) left).Value -
506 ((DecimalConstant) right).Value);
508 res = unchecked (((DecimalConstant) left).Value -
509 ((DecimalConstant) right).Value);
511 return new DecimalConstant (res, left.Location);
513 throw new Exception ( "Unexepected subtraction input: " + left);
515 } catch (OverflowException){
516 Error_CompileTimeOverflow (ec, loc);
521 case Binary.Operator.Multiply:
522 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
526 if (left is DoubleConstant){
529 if (ec.ConstantCheckState)
530 res = checked (((DoubleConstant) left).Value *
531 ((DoubleConstant) right).Value);
533 res = unchecked (((DoubleConstant) left).Value *
534 ((DoubleConstant) right).Value);
536 return new DoubleConstant (res, left.Location);
537 } else if (left is FloatConstant){
540 if (ec.ConstantCheckState)
541 res = checked (((FloatConstant) left).Value *
542 ((FloatConstant) right).Value);
544 res = unchecked (((FloatConstant) left).Value *
545 ((FloatConstant) right).Value);
547 return new FloatConstant (res, left.Location);
548 } else if (left is ULongConstant){
551 if (ec.ConstantCheckState)
552 res = checked (((ULongConstant) left).Value *
553 ((ULongConstant) right).Value);
555 res = unchecked (((ULongConstant) left).Value *
556 ((ULongConstant) right).Value);
558 return new ULongConstant (res, left.Location);
559 } else if (left is LongConstant){
562 if (ec.ConstantCheckState)
563 res = checked (((LongConstant) left).Value *
564 ((LongConstant) right).Value);
566 res = unchecked (((LongConstant) left).Value *
567 ((LongConstant) right).Value);
569 return new LongConstant (res, left.Location);
570 } else if (left is UIntConstant){
573 if (ec.ConstantCheckState)
574 res = checked (((UIntConstant) left).Value *
575 ((UIntConstant) right).Value);
577 res = unchecked (((UIntConstant) left).Value *
578 ((UIntConstant) right).Value);
580 return new UIntConstant (res, left.Location);
581 } else if (left is IntConstant){
584 if (ec.ConstantCheckState)
585 res = checked (((IntConstant) left).Value *
586 ((IntConstant) right).Value);
588 res = unchecked (((IntConstant) left).Value *
589 ((IntConstant) right).Value);
591 return new IntConstant (res, left.Location);
592 } else if (left is DecimalConstant) {
595 if (ec.ConstantCheckState)
596 res = checked (((DecimalConstant) left).Value *
597 ((DecimalConstant) right).Value);
599 res = unchecked (((DecimalConstant) left).Value *
600 ((DecimalConstant) right).Value);
602 return new DecimalConstant (res, left.Location);
604 throw new Exception ( "Unexepected multiply input: " + left);
606 } catch (OverflowException){
607 Error_CompileTimeOverflow (ec, loc);
611 case Binary.Operator.Division:
612 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
616 if (left is DoubleConstant){
619 if (ec.ConstantCheckState)
620 res = checked (((DoubleConstant) left).Value /
621 ((DoubleConstant) right).Value);
623 res = unchecked (((DoubleConstant) left).Value /
624 ((DoubleConstant) right).Value);
626 return new DoubleConstant (res, left.Location);
627 } else if (left is FloatConstant){
630 if (ec.ConstantCheckState)
631 res = checked (((FloatConstant) left).Value /
632 ((FloatConstant) right).Value);
634 res = unchecked (((FloatConstant) left).Value /
635 ((FloatConstant) right).Value);
637 return new FloatConstant (res, left.Location);
638 } else if (left is ULongConstant){
641 if (ec.ConstantCheckState)
642 res = checked (((ULongConstant) left).Value /
643 ((ULongConstant) right).Value);
645 res = unchecked (((ULongConstant) left).Value /
646 ((ULongConstant) right).Value);
648 return new ULongConstant (res, left.Location);
649 } else if (left is LongConstant){
652 if (ec.ConstantCheckState)
653 res = checked (((LongConstant) left).Value /
654 ((LongConstant) right).Value);
656 res = unchecked (((LongConstant) left).Value /
657 ((LongConstant) right).Value);
659 return new LongConstant (res, left.Location);
660 } else if (left is UIntConstant){
663 if (ec.ConstantCheckState)
664 res = checked (((UIntConstant) left).Value /
665 ((UIntConstant) right).Value);
667 res = unchecked (((UIntConstant) left).Value /
668 ((UIntConstant) right).Value);
670 return new UIntConstant (res, left.Location);
671 } else if (left is IntConstant){
674 if (ec.ConstantCheckState)
675 res = checked (((IntConstant) left).Value /
676 ((IntConstant) right).Value);
678 res = unchecked (((IntConstant) left).Value /
679 ((IntConstant) right).Value);
681 return new IntConstant (res, left.Location);
682 } else if (left is DecimalConstant) {
685 if (ec.ConstantCheckState)
686 res = checked (((DecimalConstant) left).Value /
687 ((DecimalConstant) right).Value);
689 res = unchecked (((DecimalConstant) left).Value /
690 ((DecimalConstant) right).Value);
692 return new DecimalConstant (res, left.Location);
694 throw new Exception ( "Unexepected division input: " + left);
696 } catch (OverflowException){
697 Error_CompileTimeOverflow (ec, loc);
699 } catch (DivideByZeroException) {
700 ec.Report.Error (20, loc, "Division by constant zero");
705 case Binary.Operator.Modulus:
706 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
710 if (left is DoubleConstant){
713 if (ec.ConstantCheckState)
714 res = checked (((DoubleConstant) left).Value %
715 ((DoubleConstant) right).Value);
717 res = unchecked (((DoubleConstant) left).Value %
718 ((DoubleConstant) right).Value);
720 return new DoubleConstant (res, left.Location);
721 } else if (left is FloatConstant){
724 if (ec.ConstantCheckState)
725 res = checked (((FloatConstant) left).Value %
726 ((FloatConstant) right).Value);
728 res = unchecked (((FloatConstant) left).Value %
729 ((FloatConstant) right).Value);
731 return new FloatConstant (res, left.Location);
732 } else if (left is ULongConstant){
735 if (ec.ConstantCheckState)
736 res = checked (((ULongConstant) left).Value %
737 ((ULongConstant) right).Value);
739 res = unchecked (((ULongConstant) left).Value %
740 ((ULongConstant) right).Value);
742 return new ULongConstant (res, left.Location);
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, left.Location);
754 } else if (left is UIntConstant){
757 if (ec.ConstantCheckState)
758 res = checked (((UIntConstant) left).Value %
759 ((UIntConstant) right).Value);
761 res = unchecked (((UIntConstant) left).Value %
762 ((UIntConstant) right).Value);
764 return new UIntConstant (res, left.Location);
765 } else if (left is IntConstant){
768 if (ec.ConstantCheckState)
769 res = checked (((IntConstant) left).Value %
770 ((IntConstant) right).Value);
772 res = unchecked (((IntConstant) left).Value %
773 ((IntConstant) right).Value);
775 return new IntConstant (res, left.Location);
777 throw new Exception ( "Unexepected modulus input: " + left);
779 } catch (DivideByZeroException){
780 ec.Report.Error (20, loc, "Division by constant zero");
781 } catch (OverflowException){
782 Error_CompileTimeOverflow (ec, loc);
787 // There is no overflow checking on left shift
789 case Binary.Operator.LeftShift:
790 IntConstant ic = right.ConvertImplicitly (ec, TypeManager.int32_type) as IntConstant;
792 Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
796 int lshift_val = ic.Value;
797 if (left.Type == TypeManager.uint64_type)
798 return new ULongConstant (((ULongConstant)left).Value << lshift_val, left.Location);
799 if (left.Type == TypeManager.int64_type)
800 return new LongConstant (((LongConstant)left).Value << lshift_val, left.Location);
801 if (left.Type == TypeManager.uint32_type)
802 return new UIntConstant (((UIntConstant)left).Value << lshift_val, left.Location);
804 left = left.ConvertImplicitly (ec, TypeManager.int32_type);
805 if (left.Type == TypeManager.int32_type)
806 return new IntConstant (((IntConstant)left).Value << lshift_val, left.Location);
808 Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
812 // There is no overflow checking on right shift
814 case Binary.Operator.RightShift:
815 IntConstant sic = right.ConvertImplicitly (ec, TypeManager.int32_type) as IntConstant;
817 Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); ;
820 int rshift_val = sic.Value;
821 if (left.Type == TypeManager.uint64_type)
822 return new ULongConstant (((ULongConstant)left).Value >> rshift_val, left.Location);
823 if (left.Type == TypeManager.int64_type)
824 return new LongConstant (((LongConstant)left).Value >> rshift_val, left.Location);
825 if (left.Type == TypeManager.uint32_type)
826 return new UIntConstant (((UIntConstant)left).Value >> rshift_val, left.Location);
828 left = left.ConvertImplicitly (ec, TypeManager.int32_type);
829 if (left.Type == TypeManager.int32_type)
830 return new IntConstant (((IntConstant)left).Value >> rshift_val, left.Location);
832 Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
835 case Binary.Operator.Equality:
836 if (TypeManager.IsReferenceType (lt) && TypeManager.IsReferenceType (lt)) {
837 if (left.IsNull || right.IsNull) {
838 return ReducedExpression.Create (
839 new BoolConstant (left.IsNull == right.IsNull, left.Location).Resolve (ec),
840 new Binary (oper, left, right, loc));
843 if (left is StringConstant && right is StringConstant)
844 return new BoolConstant (
845 ((StringConstant) left).Value == ((StringConstant) right).Value, left.Location);
850 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
854 if (left is DoubleConstant)
855 bool_res = ((DoubleConstant) left).Value ==
856 ((DoubleConstant) right).Value;
857 else if (left is FloatConstant)
858 bool_res = ((FloatConstant) left).Value ==
859 ((FloatConstant) right).Value;
860 else if (left is ULongConstant)
861 bool_res = ((ULongConstant) left).Value ==
862 ((ULongConstant) right).Value;
863 else if (left is LongConstant)
864 bool_res = ((LongConstant) left).Value ==
865 ((LongConstant) right).Value;
866 else if (left is UIntConstant)
867 bool_res = ((UIntConstant) left).Value ==
868 ((UIntConstant) right).Value;
869 else if (left is IntConstant)
870 bool_res = ((IntConstant) left).Value ==
871 ((IntConstant) right).Value;
875 return new BoolConstant (bool_res, left.Location);
877 case Binary.Operator.Inequality:
878 if (TypeManager.IsReferenceType (lt) && TypeManager.IsReferenceType (lt)) {
879 if (left.IsNull || right.IsNull) {
880 return ReducedExpression.Create (
881 new BoolConstant (left.IsNull != right.IsNull, left.Location).Resolve (ec),
882 new Binary (oper, left, right, loc));
885 if (left is StringConstant && right is StringConstant)
886 return new BoolConstant (
887 ((StringConstant) left).Value != ((StringConstant) right).Value, left.Location);
892 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
896 if (left is DoubleConstant)
897 bool_res = ((DoubleConstant) left).Value !=
898 ((DoubleConstant) right).Value;
899 else if (left is FloatConstant)
900 bool_res = ((FloatConstant) left).Value !=
901 ((FloatConstant) right).Value;
902 else if (left is ULongConstant)
903 bool_res = ((ULongConstant) left).Value !=
904 ((ULongConstant) right).Value;
905 else if (left is LongConstant)
906 bool_res = ((LongConstant) left).Value !=
907 ((LongConstant) right).Value;
908 else if (left is UIntConstant)
909 bool_res = ((UIntConstant) left).Value !=
910 ((UIntConstant) right).Value;
911 else if (left is IntConstant)
912 bool_res = ((IntConstant) left).Value !=
913 ((IntConstant) right).Value;
917 return new BoolConstant (bool_res, left.Location);
919 case Binary.Operator.LessThan:
920 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
924 if (left is DoubleConstant)
925 bool_res = ((DoubleConstant) left).Value <
926 ((DoubleConstant) right).Value;
927 else if (left is FloatConstant)
928 bool_res = ((FloatConstant) left).Value <
929 ((FloatConstant) right).Value;
930 else if (left is ULongConstant)
931 bool_res = ((ULongConstant) left).Value <
932 ((ULongConstant) right).Value;
933 else if (left is LongConstant)
934 bool_res = ((LongConstant) left).Value <
935 ((LongConstant) right).Value;
936 else if (left is UIntConstant)
937 bool_res = ((UIntConstant) left).Value <
938 ((UIntConstant) right).Value;
939 else if (left is IntConstant)
940 bool_res = ((IntConstant) left).Value <
941 ((IntConstant) right).Value;
945 return new BoolConstant (bool_res, left.Location);
947 case Binary.Operator.GreaterThan:
948 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
952 if (left is DoubleConstant)
953 bool_res = ((DoubleConstant) left).Value >
954 ((DoubleConstant) right).Value;
955 else if (left is FloatConstant)
956 bool_res = ((FloatConstant) left).Value >
957 ((FloatConstant) right).Value;
958 else if (left is ULongConstant)
959 bool_res = ((ULongConstant) left).Value >
960 ((ULongConstant) right).Value;
961 else if (left is LongConstant)
962 bool_res = ((LongConstant) left).Value >
963 ((LongConstant) right).Value;
964 else if (left is UIntConstant)
965 bool_res = ((UIntConstant) left).Value >
966 ((UIntConstant) right).Value;
967 else if (left is IntConstant)
968 bool_res = ((IntConstant) left).Value >
969 ((IntConstant) right).Value;
973 return new BoolConstant (bool_res, left.Location);
975 case Binary.Operator.GreaterThanOrEqual:
976 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
980 if (left is DoubleConstant)
981 bool_res = ((DoubleConstant) left).Value >=
982 ((DoubleConstant) right).Value;
983 else if (left is FloatConstant)
984 bool_res = ((FloatConstant) left).Value >=
985 ((FloatConstant) right).Value;
986 else if (left is ULongConstant)
987 bool_res = ((ULongConstant) left).Value >=
988 ((ULongConstant) right).Value;
989 else if (left is LongConstant)
990 bool_res = ((LongConstant) left).Value >=
991 ((LongConstant) right).Value;
992 else if (left is UIntConstant)
993 bool_res = ((UIntConstant) left).Value >=
994 ((UIntConstant) right).Value;
995 else if (left is IntConstant)
996 bool_res = ((IntConstant) left).Value >=
997 ((IntConstant) right).Value;
1001 return new BoolConstant (bool_res, left.Location);
1003 case Binary.Operator.LessThanOrEqual:
1004 if (!DoBinaryNumericPromotions (ec, ref left, ref right))
1008 if (left is DoubleConstant)
1009 bool_res = ((DoubleConstant) left).Value <=
1010 ((DoubleConstant) right).Value;
1011 else if (left is FloatConstant)
1012 bool_res = ((FloatConstant) left).Value <=
1013 ((FloatConstant) right).Value;
1014 else if (left is ULongConstant)
1015 bool_res = ((ULongConstant) left).Value <=
1016 ((ULongConstant) right).Value;
1017 else if (left is LongConstant)
1018 bool_res = ((LongConstant) left).Value <=
1019 ((LongConstant) right).Value;
1020 else if (left is UIntConstant)
1021 bool_res = ((UIntConstant) left).Value <=
1022 ((UIntConstant) right).Value;
1023 else if (left is IntConstant)
1024 bool_res = ((IntConstant) left).Value <=
1025 ((IntConstant) right).Value;
1029 return new BoolConstant (bool_res, left.Location);