2 // cfold.cs: Constant Folding
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // (C) 2002, 2003 Ximian, Inc.
13 namespace Mono.CSharp {
15 public class ConstantFold {
17 static 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 desposits 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 static void DoBinaryNumericPromotions (ref Constant left, ref Constant right)
30 Type ltype = left.Type;
31 Type rtype = right.Type;
33 foreach (Type t in binary_promotions) {
34 if (t == ltype || t == rtype) {
35 left = left.ConvertImplicitly (t);
36 right = right.ConvertImplicitly (t);
41 left = left.ConvertImplicitly (TypeManager.int32_type);
42 right = right.ConvertImplicitly (TypeManager.int32_type);
45 internal static void Error_CompileTimeOverflow (Location loc)
47 Report.Error (220, loc, "The operation overflows at compile time in checked mode");
51 /// Constant expression folder for binary operations.
53 /// Returns null if the expression can not be folded.
55 static public Constant BinaryFold (EmitContext ec, Binary.Operator oper,
56 Constant left, Constant right, Location loc)
58 if (left is EmptyConstantCast)
59 return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);
61 if (right is EmptyConstantCast)
62 return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);
67 Constant result = null;
69 if (lt == TypeManager.bool_type && lt == rt) {
70 bool lv = ((BoolConstant) left ).Value;
71 bool rv = ((BoolConstant) right).Value;
73 case Binary.Operator.BitwiseAnd:
74 case Binary.Operator.LogicalAnd:
75 return new BoolConstant (lv && rv, left.Location);
76 case Binary.Operator.BitwiseOr:
77 case Binary.Operator.LogicalOr:
78 return new BoolConstant (lv || rv, left.Location);
79 case Binary.Operator.ExclusiveOr:
80 return new BoolConstant (lv ^ rv, left.Location);
81 case Binary.Operator.Equality:
82 return new BoolConstant (lv == rv, left.Location);
83 case Binary.Operator.Inequality:
84 return new BoolConstant (lv != rv, left.Location);
90 // During an enum evaluation, none of the rules are valid
91 // Not sure whether it is bug in csc or in documentation
93 if (ec.InEnumContext){
94 if (left is EnumConstant)
95 left = ((EnumConstant) left).Child;
97 if (right is EnumConstant)
98 right = ((EnumConstant) right).Child;
99 } else if (left is EnumConstant && rt == lt) {
102 /// E operator |(E x, E y);
103 /// E operator &(E x, E y);
104 /// E operator ^(E x, E y);
106 case Binary.Operator.BitwiseOr:
107 case Binary.Operator.BitwiseAnd:
108 case Binary.Operator.ExclusiveOr:
109 return BinaryFold (ec, oper, ((EnumConstant)left).Child,
110 ((EnumConstant)right).Child, loc).TryReduce (ec, lt, loc);
113 /// U operator -(E x, E y);
115 case Binary.Operator.Subtraction:
116 result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
117 return result.TryReduce (ec, ((EnumConstant)left).Child.Type, loc);
120 /// bool operator ==(E x, E y);
121 /// bool operator !=(E x, E y);
122 /// bool operator <(E x, E y);
123 /// bool operator >(E x, E y);
124 /// bool operator <=(E x, E y);
125 /// bool operator >=(E x, E y);
127 case Binary.Operator.Equality:
128 case Binary.Operator.Inequality:
129 case Binary.Operator.LessThan:
130 case Binary.Operator.GreaterThan:
131 case Binary.Operator.LessThanOrEqual:
132 case Binary.Operator.GreaterThanOrEqual:
133 return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
139 case Binary.Operator.BitwiseOr:
140 DoBinaryNumericPromotions (ref left, ref right);
141 if (left == null || right == null)
144 if (left is IntConstant){
145 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
147 return new IntConstant (res, left.Location);
149 if (left is UIntConstant){
150 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
152 return new UIntConstant (res, left.Location);
154 if (left is LongConstant){
155 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
157 return new LongConstant (res, left.Location);
159 if (left is ULongConstant){
160 ulong res = ((ULongConstant)left).Value |
161 ((ULongConstant)right).Value;
163 return new ULongConstant (res, left.Location);
167 case Binary.Operator.BitwiseAnd:
168 DoBinaryNumericPromotions (ref left, ref right);
169 if (left == null || right == null)
173 /// int operator &(int x, int y);
174 /// uint operator &(uint x, uint y);
175 /// long operator &(long x, long y);
176 /// ulong operator &(ulong x, ulong y);
178 if (left is IntConstant){
179 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
180 return new IntConstant (res, left.Location);
182 if (left is UIntConstant){
183 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
184 return new UIntConstant (res, left.Location);
186 if (left is LongConstant){
187 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
188 return new LongConstant (res, left.Location);
190 if (left is ULongConstant){
191 ulong res = ((ULongConstant)left).Value &
192 ((ULongConstant)right).Value;
194 return new ULongConstant (res, left.Location);
198 case Binary.Operator.ExclusiveOr:
199 DoBinaryNumericPromotions (ref left, ref right);
200 if (left == null || right == null)
203 if (left is IntConstant){
204 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
205 return new IntConstant (res, left.Location);
207 if (left is UIntConstant){
208 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
210 return new UIntConstant (res, left.Location);
212 if (left is LongConstant){
213 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
215 return new LongConstant (res, left.Location);
217 if (left is ULongConstant){
218 ulong res = ((ULongConstant)left).Value ^
219 ((ULongConstant)right).Value;
221 return new ULongConstant (res, left.Location);
225 case Binary.Operator.Addition:
227 // If both sides are strings, then concatenate, if
228 // one is a string, and the other is not, then defer
229 // to runtime concatenation
231 if (lt == TypeManager.string_type || rt == TypeManager.string_type){
232 if (lt == TypeManager.string_type && rt == TypeManager.string_type)
233 return new StringConstant (
234 ((StringConstant) left).Value +
235 ((StringConstant) right).Value, left.Location);
241 // handle "E operator + (E x, U y)"
242 // handle "E operator + (Y y, E x)"
244 EnumConstant lc = left as EnumConstant;
245 EnumConstant rc = right as EnumConstant;
246 if (lc != null || rc != null){
253 // U has to be implicitly convetible to E.base
254 right = right.ConvertImplicitly (lc.Child.Type);
258 result = BinaryFold (ec, oper, lc.Child, right, loc);
262 result = result.TryReduce (ec, lt, loc);
266 return new EnumConstant (result, lt);
269 DoBinaryNumericPromotions (ref left, ref right);
270 if (left == null || right == null)
274 if (left is DoubleConstant){
277 if (ec.ConstantCheckState)
278 res = checked (((DoubleConstant) left).Value +
279 ((DoubleConstant) right).Value);
281 res = unchecked (((DoubleConstant) left).Value +
282 ((DoubleConstant) right).Value);
284 return new DoubleConstant (res, left.Location);
286 if (left is FloatConstant){
289 if (ec.ConstantCheckState)
290 res = checked (((FloatConstant) left).Value +
291 ((FloatConstant) right).Value);
293 res = unchecked (((FloatConstant) left).Value +
294 ((FloatConstant) right).Value);
296 result = new FloatConstant (res, left.Location);
297 } else if (left is ULongConstant){
300 if (ec.ConstantCheckState)
301 res = checked (((ULongConstant) left).Value +
302 ((ULongConstant) right).Value);
304 res = unchecked (((ULongConstant) left).Value +
305 ((ULongConstant) right).Value);
307 result = new ULongConstant (res, left.Location);
308 } else if (left is LongConstant){
311 if (ec.ConstantCheckState)
312 res = checked (((LongConstant) left).Value +
313 ((LongConstant) right).Value);
315 res = unchecked (((LongConstant) left).Value +
316 ((LongConstant) right).Value);
318 result = new LongConstant (res, left.Location);
319 } else if (left is UIntConstant){
322 if (ec.ConstantCheckState)
323 res = checked (((UIntConstant) left).Value +
324 ((UIntConstant) right).Value);
326 res = unchecked (((UIntConstant) left).Value +
327 ((UIntConstant) right).Value);
329 result = new UIntConstant (res, left.Location);
330 } else if (left is IntConstant){
333 if (ec.ConstantCheckState)
334 res = checked (((IntConstant) left).Value +
335 ((IntConstant) right).Value);
337 res = unchecked (((IntConstant) left).Value +
338 ((IntConstant) right).Value);
340 result = new IntConstant (res, left.Location);
341 } else if (left is DecimalConstant) {
344 if (ec.ConstantCheckState)
345 res = checked (((DecimalConstant) left).Value +
346 ((DecimalConstant) right).Value);
348 res = unchecked (((DecimalConstant) left).Value +
349 ((DecimalConstant) right).Value);
351 result = new DecimalConstant (res, left.Location);
353 throw new Exception ( "Unexepected addition input: " + left);
355 } catch (OverflowException){
356 Error_CompileTimeOverflow (loc);
361 case Binary.Operator.Subtraction:
363 // handle "E operator - (E x, U y)"
364 // handle "E operator - (Y y, E x)"
366 lc = left as EnumConstant;
367 rc = right as EnumConstant;
368 if (lc != null || rc != null){
375 // U has to be implicitly convetible to E.base
376 right = right.ConvertImplicitly (lc.Child.Type);
380 result = BinaryFold (ec, oper, lc.Child, right, loc);
384 result = result.TryReduce (ec, lt, loc);
388 return new EnumConstant (result, lt);
391 DoBinaryNumericPromotions (ref left, ref right);
392 if (left == null || right == null)
396 if (left is DoubleConstant){
399 if (ec.ConstantCheckState)
400 res = checked (((DoubleConstant) left).Value -
401 ((DoubleConstant) right).Value);
403 res = unchecked (((DoubleConstant) left).Value -
404 ((DoubleConstant) right).Value);
406 result = new DoubleConstant (res, left.Location);
407 } else if (left is FloatConstant){
410 if (ec.ConstantCheckState)
411 res = checked (((FloatConstant) left).Value -
412 ((FloatConstant) right).Value);
414 res = unchecked (((FloatConstant) left).Value -
415 ((FloatConstant) right).Value);
417 result = new FloatConstant (res, left.Location);
418 } else if (left is ULongConstant){
421 if (ec.ConstantCheckState)
422 res = checked (((ULongConstant) left).Value -
423 ((ULongConstant) right).Value);
425 res = unchecked (((ULongConstant) left).Value -
426 ((ULongConstant) right).Value);
428 result = new ULongConstant (res, left.Location);
429 } else if (left is LongConstant){
432 if (ec.ConstantCheckState)
433 res = checked (((LongConstant) left).Value -
434 ((LongConstant) right).Value);
436 res = unchecked (((LongConstant) left).Value -
437 ((LongConstant) right).Value);
439 result = new LongConstant (res, left.Location);
440 } else if (left is UIntConstant){
443 if (ec.ConstantCheckState)
444 res = checked (((UIntConstant) left).Value -
445 ((UIntConstant) right).Value);
447 res = unchecked (((UIntConstant) left).Value -
448 ((UIntConstant) right).Value);
450 result = new UIntConstant (res, left.Location);
451 } else if (left is IntConstant){
454 if (ec.ConstantCheckState)
455 res = checked (((IntConstant) left).Value -
456 ((IntConstant) right).Value);
458 res = unchecked (((IntConstant) left).Value -
459 ((IntConstant) right).Value);
461 result = new IntConstant (res, left.Location);
462 } else if (left is DecimalConstant) {
465 if (ec.ConstantCheckState)
466 res = checked (((DecimalConstant) left).Value -
467 ((DecimalConstant) right).Value);
469 res = unchecked (((DecimalConstant) left).Value -
470 ((DecimalConstant) right).Value);
472 return new DecimalConstant (res, left.Location);
474 throw new Exception ( "Unexepected subtraction input: " + left);
476 } catch (OverflowException){
477 Error_CompileTimeOverflow (loc);
482 case Binary.Operator.Multiply:
483 DoBinaryNumericPromotions (ref left, ref right);
484 if (left == null || right == null)
488 if (left is DoubleConstant){
491 if (ec.ConstantCheckState)
492 res = checked (((DoubleConstant) left).Value *
493 ((DoubleConstant) right).Value);
495 res = unchecked (((DoubleConstant) left).Value *
496 ((DoubleConstant) right).Value);
498 return new DoubleConstant (res, left.Location);
499 } else if (left is FloatConstant){
502 if (ec.ConstantCheckState)
503 res = checked (((FloatConstant) left).Value *
504 ((FloatConstant) right).Value);
506 res = unchecked (((FloatConstant) left).Value *
507 ((FloatConstant) right).Value);
509 return new FloatConstant (res, left.Location);
510 } else if (left is ULongConstant){
513 if (ec.ConstantCheckState)
514 res = checked (((ULongConstant) left).Value *
515 ((ULongConstant) right).Value);
517 res = unchecked (((ULongConstant) left).Value *
518 ((ULongConstant) right).Value);
520 return new ULongConstant (res, left.Location);
521 } else if (left is LongConstant){
524 if (ec.ConstantCheckState)
525 res = checked (((LongConstant) left).Value *
526 ((LongConstant) right).Value);
528 res = unchecked (((LongConstant) left).Value *
529 ((LongConstant) right).Value);
531 return new LongConstant (res, left.Location);
532 } else if (left is UIntConstant){
535 if (ec.ConstantCheckState)
536 res = checked (((UIntConstant) left).Value *
537 ((UIntConstant) right).Value);
539 res = unchecked (((UIntConstant) left).Value *
540 ((UIntConstant) right).Value);
542 return new UIntConstant (res, left.Location);
543 } else if (left is IntConstant){
546 if (ec.ConstantCheckState)
547 res = checked (((IntConstant) left).Value *
548 ((IntConstant) right).Value);
550 res = unchecked (((IntConstant) left).Value *
551 ((IntConstant) right).Value);
553 return new IntConstant (res, left.Location);
554 } else if (left is DecimalConstant) {
557 if (ec.ConstantCheckState)
558 res = checked (((DecimalConstant) left).Value *
559 ((DecimalConstant) right).Value);
561 res = unchecked (((DecimalConstant) left).Value *
562 ((DecimalConstant) right).Value);
564 return new DecimalConstant (res, left.Location);
566 throw new Exception ( "Unexepected multiply input: " + left);
568 } catch (OverflowException){
569 Error_CompileTimeOverflow (loc);
573 case Binary.Operator.Division:
574 DoBinaryNumericPromotions (ref left, ref right);
575 if (left == null || right == null)
579 if (left is DoubleConstant){
582 if (ec.ConstantCheckState)
583 res = checked (((DoubleConstant) left).Value /
584 ((DoubleConstant) right).Value);
586 res = unchecked (((DoubleConstant) left).Value /
587 ((DoubleConstant) right).Value);
589 return new DoubleConstant (res, left.Location);
590 } else if (left is FloatConstant){
593 if (ec.ConstantCheckState)
594 res = checked (((FloatConstant) left).Value /
595 ((FloatConstant) right).Value);
597 res = unchecked (((FloatConstant) left).Value /
598 ((FloatConstant) right).Value);
600 return new FloatConstant (res, left.Location);
601 } else if (left is ULongConstant){
604 if (ec.ConstantCheckState)
605 res = checked (((ULongConstant) left).Value /
606 ((ULongConstant) right).Value);
608 res = unchecked (((ULongConstant) left).Value /
609 ((ULongConstant) right).Value);
611 return new ULongConstant (res, left.Location);
612 } else if (left is LongConstant){
615 if (ec.ConstantCheckState)
616 res = checked (((LongConstant) left).Value /
617 ((LongConstant) right).Value);
619 res = unchecked (((LongConstant) left).Value /
620 ((LongConstant) right).Value);
622 return new LongConstant (res, left.Location);
623 } else if (left is UIntConstant){
626 if (ec.ConstantCheckState)
627 res = checked (((UIntConstant) left).Value /
628 ((UIntConstant) right).Value);
630 res = unchecked (((UIntConstant) left).Value /
631 ((UIntConstant) right).Value);
633 return new UIntConstant (res, left.Location);
634 } else if (left is IntConstant){
637 if (ec.ConstantCheckState)
638 res = checked (((IntConstant) left).Value /
639 ((IntConstant) right).Value);
641 res = unchecked (((IntConstant) left).Value /
642 ((IntConstant) right).Value);
644 return new IntConstant (res, left.Location);
645 } else if (left is DecimalConstant) {
648 if (ec.ConstantCheckState)
649 res = checked (((DecimalConstant) left).Value /
650 ((DecimalConstant) right).Value);
652 res = unchecked (((DecimalConstant) left).Value /
653 ((DecimalConstant) right).Value);
655 return new DecimalConstant (res, left.Location);
657 throw new Exception ( "Unexepected division input: " + left);
659 } catch (OverflowException){
660 Error_CompileTimeOverflow (loc);
662 } catch (DivideByZeroException) {
663 Report.Error (020, loc, "Division by constant zero");
668 case Binary.Operator.Modulus:
669 DoBinaryNumericPromotions (ref left, ref right);
670 if (left == null || right == null)
674 if (left is DoubleConstant){
677 if (ec.ConstantCheckState)
678 res = checked (((DoubleConstant) left).Value %
679 ((DoubleConstant) right).Value);
681 res = unchecked (((DoubleConstant) left).Value %
682 ((DoubleConstant) right).Value);
684 return new DoubleConstant (res, left.Location);
685 } else if (left is FloatConstant){
688 if (ec.ConstantCheckState)
689 res = checked (((FloatConstant) left).Value %
690 ((FloatConstant) right).Value);
692 res = unchecked (((FloatConstant) left).Value %
693 ((FloatConstant) right).Value);
695 return new FloatConstant (res, left.Location);
696 } else if (left is ULongConstant){
699 if (ec.ConstantCheckState)
700 res = checked (((ULongConstant) left).Value %
701 ((ULongConstant) right).Value);
703 res = unchecked (((ULongConstant) left).Value %
704 ((ULongConstant) right).Value);
706 return new ULongConstant (res, left.Location);
707 } else if (left is LongConstant){
710 if (ec.ConstantCheckState)
711 res = checked (((LongConstant) left).Value %
712 ((LongConstant) right).Value);
714 res = unchecked (((LongConstant) left).Value %
715 ((LongConstant) right).Value);
717 return new LongConstant (res, left.Location);
718 } else if (left is UIntConstant){
721 if (ec.ConstantCheckState)
722 res = checked (((UIntConstant) left).Value %
723 ((UIntConstant) right).Value);
725 res = unchecked (((UIntConstant) left).Value %
726 ((UIntConstant) right).Value);
728 return new UIntConstant (res, left.Location);
729 } else if (left is IntConstant){
732 if (ec.ConstantCheckState)
733 res = checked (((IntConstant) left).Value %
734 ((IntConstant) right).Value);
736 res = unchecked (((IntConstant) left).Value %
737 ((IntConstant) right).Value);
739 return new IntConstant (res, left.Location);
741 throw new Exception ( "Unexepected modulus input: " + left);
743 } catch (DivideByZeroException){
744 Report.Error (020, loc, "Division by constant zero");
745 } catch (OverflowException){
746 Error_CompileTimeOverflow (loc);
751 // There is no overflow checking on left shift
753 case Binary.Operator.LeftShift:
754 IntConstant ic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
756 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
760 int lshift_val = ic.Value;
761 if (left.Type == TypeManager.uint64_type)
762 return new ULongConstant (((ULongConstant)left).Value << lshift_val, left.Location);
763 if (left.Type == TypeManager.int64_type)
764 return new LongConstant (((LongConstant)left).Value << lshift_val, left.Location);
765 if (left.Type == TypeManager.uint32_type)
766 return new UIntConstant (((UIntConstant)left).Value << lshift_val, left.Location);
768 left = left.ConvertImplicitly (TypeManager.int32_type);
769 if (left.Type == TypeManager.int32_type)
770 return new IntConstant (((IntConstant)left).Value << lshift_val, left.Location);
772 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
776 // There is no overflow checking on right shift
778 case Binary.Operator.RightShift:
779 IntConstant sic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
781 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
784 int rshift_val = sic.Value;
785 if (left.Type == TypeManager.uint64_type)
786 return new ULongConstant (((ULongConstant)left).Value >> rshift_val, left.Location);
787 if (left.Type == TypeManager.int64_type)
788 return new LongConstant (((LongConstant)left).Value >> rshift_val, left.Location);
789 if (left.Type == TypeManager.uint32_type)
790 return new UIntConstant (((UIntConstant)left).Value >> rshift_val, left.Location);
792 left = left.ConvertImplicitly (TypeManager.int32_type);
793 if (left.Type == TypeManager.int32_type)
794 return new IntConstant (((IntConstant)left).Value >> rshift_val, left.Location);
796 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
799 case Binary.Operator.Equality:
800 if (left is NullConstant){
801 if (right is NullConstant)
802 return new BoolConstant (true, left.Location);
803 else if (right is StringConstant)
804 return new BoolConstant (
805 ((StringConstant) right).Value == null, left.Location);
806 } else if (right is NullConstant){
807 if (left is NullConstant)
808 return new BoolConstant (true, left.Location);
809 else if (left is StringConstant)
810 return new BoolConstant (
811 ((StringConstant) left).Value == null, left.Location);
813 if (left is StringConstant && right is StringConstant){
814 return new BoolConstant (
815 ((StringConstant) left).Value ==
816 ((StringConstant) right).Value, left.Location);
820 DoBinaryNumericPromotions (ref left, ref right);
821 if (left == null || right == null)
825 if (left is DoubleConstant)
826 bool_res = ((DoubleConstant) left).Value ==
827 ((DoubleConstant) right).Value;
828 else if (left is FloatConstant)
829 bool_res = ((FloatConstant) left).Value ==
830 ((FloatConstant) right).Value;
831 else if (left is ULongConstant)
832 bool_res = ((ULongConstant) left).Value ==
833 ((ULongConstant) right).Value;
834 else if (left is LongConstant)
835 bool_res = ((LongConstant) left).Value ==
836 ((LongConstant) right).Value;
837 else if (left is UIntConstant)
838 bool_res = ((UIntConstant) left).Value ==
839 ((UIntConstant) right).Value;
840 else if (left is IntConstant)
841 bool_res = ((IntConstant) left).Value ==
842 ((IntConstant) right).Value;
846 return new BoolConstant (bool_res, left.Location);
848 case Binary.Operator.Inequality:
849 if (left is NullConstant){
850 if (right is NullConstant)
851 return new BoolConstant (false, left.Location);
852 else if (right is StringConstant)
853 return new BoolConstant (
854 ((StringConstant) right).Value != null, left.Location);
855 } else if (right is NullConstant){
856 if (left is NullConstant)
857 return new BoolConstant (false, left.Location);
858 else if (left is StringConstant)
859 return new BoolConstant (
860 ((StringConstant) left).Value != null, left.Location);
862 if (left is StringConstant && right is StringConstant){
863 return new BoolConstant (
864 ((StringConstant) left).Value !=
865 ((StringConstant) right).Value, left.Location);
869 DoBinaryNumericPromotions (ref left, ref right);
870 if (left == null || right == null)
874 if (left is DoubleConstant)
875 bool_res = ((DoubleConstant) left).Value !=
876 ((DoubleConstant) right).Value;
877 else if (left is FloatConstant)
878 bool_res = ((FloatConstant) left).Value !=
879 ((FloatConstant) right).Value;
880 else if (left is ULongConstant)
881 bool_res = ((ULongConstant) left).Value !=
882 ((ULongConstant) right).Value;
883 else if (left is LongConstant)
884 bool_res = ((LongConstant) left).Value !=
885 ((LongConstant) right).Value;
886 else if (left is UIntConstant)
887 bool_res = ((UIntConstant) left).Value !=
888 ((UIntConstant) right).Value;
889 else if (left is IntConstant)
890 bool_res = ((IntConstant) left).Value !=
891 ((IntConstant) right).Value;
895 return new BoolConstant (bool_res, left.Location);
897 case Binary.Operator.LessThan:
898 DoBinaryNumericPromotions (ref left, ref right);
899 if (left == null || right == null)
903 if (left is DoubleConstant)
904 bool_res = ((DoubleConstant) left).Value <
905 ((DoubleConstant) right).Value;
906 else if (left is FloatConstant)
907 bool_res = ((FloatConstant) left).Value <
908 ((FloatConstant) right).Value;
909 else if (left is ULongConstant)
910 bool_res = ((ULongConstant) left).Value <
911 ((ULongConstant) right).Value;
912 else if (left is LongConstant)
913 bool_res = ((LongConstant) left).Value <
914 ((LongConstant) right).Value;
915 else if (left is UIntConstant)
916 bool_res = ((UIntConstant) left).Value <
917 ((UIntConstant) right).Value;
918 else if (left is IntConstant)
919 bool_res = ((IntConstant) left).Value <
920 ((IntConstant) right).Value;
924 return new BoolConstant (bool_res, left.Location);
926 case Binary.Operator.GreaterThan:
927 DoBinaryNumericPromotions (ref left, ref right);
928 if (left == null || right == null)
932 if (left is DoubleConstant)
933 bool_res = ((DoubleConstant) left).Value >
934 ((DoubleConstant) right).Value;
935 else if (left is FloatConstant)
936 bool_res = ((FloatConstant) left).Value >
937 ((FloatConstant) right).Value;
938 else if (left is ULongConstant)
939 bool_res = ((ULongConstant) left).Value >
940 ((ULongConstant) right).Value;
941 else if (left is LongConstant)
942 bool_res = ((LongConstant) left).Value >
943 ((LongConstant) right).Value;
944 else if (left is UIntConstant)
945 bool_res = ((UIntConstant) left).Value >
946 ((UIntConstant) right).Value;
947 else if (left is IntConstant)
948 bool_res = ((IntConstant) left).Value >
949 ((IntConstant) right).Value;
953 return new BoolConstant (bool_res, left.Location);
955 case Binary.Operator.GreaterThanOrEqual:
956 DoBinaryNumericPromotions (ref left, ref right);
957 if (left == null || right == null)
961 if (left is DoubleConstant)
962 bool_res = ((DoubleConstant) left).Value >=
963 ((DoubleConstant) right).Value;
964 else if (left is FloatConstant)
965 bool_res = ((FloatConstant) left).Value >=
966 ((FloatConstant) right).Value;
967 else if (left is ULongConstant)
968 bool_res = ((ULongConstant) left).Value >=
969 ((ULongConstant) right).Value;
970 else if (left is LongConstant)
971 bool_res = ((LongConstant) left).Value >=
972 ((LongConstant) right).Value;
973 else if (left is UIntConstant)
974 bool_res = ((UIntConstant) left).Value >=
975 ((UIntConstant) right).Value;
976 else if (left is IntConstant)
977 bool_res = ((IntConstant) left).Value >=
978 ((IntConstant) right).Value;
982 return new BoolConstant (bool_res, left.Location);
984 case Binary.Operator.LessThanOrEqual:
985 DoBinaryNumericPromotions (ref left, ref right);
986 if (left == null || right == null)
990 if (left is DoubleConstant)
991 bool_res = ((DoubleConstant) left).Value <=
992 ((DoubleConstant) right).Value;
993 else if (left is FloatConstant)
994 bool_res = ((FloatConstant) left).Value <=
995 ((FloatConstant) right).Value;
996 else if (left is ULongConstant)
997 bool_res = ((ULongConstant) left).Value <=
998 ((ULongConstant) right).Value;
999 else if (left is LongConstant)
1000 bool_res = ((LongConstant) left).Value <=
1001 ((LongConstant) right).Value;
1002 else if (left is UIntConstant)
1003 bool_res = ((UIntConstant) left).Value <=
1004 ((UIntConstant) right).Value;
1005 else if (left is IntConstant)
1006 bool_res = ((IntConstant) left).Value <=
1007 ((IntConstant) right).Value;
1011 return new BoolConstant (bool_res, left.Location);