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 Constant result = null;
60 if (left is EmptyConstantCast)
61 return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);
63 if (left is SideEffectConstant) {
64 result = BinaryFold (ec, oper, ((SideEffectConstant) left).left, right, loc);
67 return new SideEffectConstant (result, left, loc);
70 if (right is EmptyConstantCast)
71 return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);
73 if (right is SideEffectConstant) {
74 result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).left, loc);
77 return new SideEffectConstant (result, right, loc);
84 if (lt == TypeManager.bool_type && lt == rt) {
85 bool lv = ((BoolConstant) left ).Value;
86 bool rv = ((BoolConstant) right).Value;
88 case Binary.Operator.BitwiseAnd:
89 case Binary.Operator.LogicalAnd:
90 return new BoolConstant (lv && rv, left.Location);
91 case Binary.Operator.BitwiseOr:
92 case Binary.Operator.LogicalOr:
93 return new BoolConstant (lv || rv, left.Location);
94 case Binary.Operator.ExclusiveOr:
95 return new BoolConstant (lv ^ rv, left.Location);
96 case Binary.Operator.Equality:
97 return new BoolConstant (lv == rv, left.Location);
98 case Binary.Operator.Inequality:
99 return new BoolConstant (lv != rv, left.Location);
105 // During an enum evaluation, none of the rules are valid
106 // Not sure whether it is bug in csc or in documentation
108 if (ec.InEnumContext){
109 if (left is EnumConstant)
110 left = ((EnumConstant) left).Child;
112 if (right is EnumConstant)
113 right = ((EnumConstant) right).Child;
114 } else if (left is EnumConstant && rt == lt) {
117 /// E operator |(E x, E y);
118 /// E operator &(E x, E y);
119 /// E operator ^(E x, E y);
121 case Binary.Operator.BitwiseOr:
122 case Binary.Operator.BitwiseAnd:
123 case Binary.Operator.ExclusiveOr:
124 return BinaryFold (ec, oper, ((EnumConstant)left).Child,
125 ((EnumConstant)right).Child, loc).TryReduce (ec, lt, loc);
128 /// U operator -(E x, E y);
130 case Binary.Operator.Subtraction:
131 result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
132 return result.TryReduce (ec, ((EnumConstant)left).Child.Type, loc);
135 /// bool operator ==(E x, E y);
136 /// bool operator !=(E x, E y);
137 /// bool operator <(E x, E y);
138 /// bool operator >(E x, E y);
139 /// bool operator <=(E x, E y);
140 /// bool operator >=(E x, E y);
142 case Binary.Operator.Equality:
143 case Binary.Operator.Inequality:
144 case Binary.Operator.LessThan:
145 case Binary.Operator.GreaterThan:
146 case Binary.Operator.LessThanOrEqual:
147 case Binary.Operator.GreaterThanOrEqual:
148 return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
154 case Binary.Operator.BitwiseOr:
155 DoBinaryNumericPromotions (ref left, ref right);
156 if (left == null || right == null)
159 if (left is IntConstant){
160 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
162 return new IntConstant (res, left.Location);
164 if (left is UIntConstant){
165 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
167 return new UIntConstant (res, left.Location);
169 if (left is LongConstant){
170 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
172 return new LongConstant (res, left.Location);
174 if (left is ULongConstant){
175 ulong res = ((ULongConstant)left).Value |
176 ((ULongConstant)right).Value;
178 return new ULongConstant (res, left.Location);
182 case Binary.Operator.BitwiseAnd:
183 DoBinaryNumericPromotions (ref left, ref right);
184 if (left == null || right == null)
188 /// int operator &(int x, int y);
189 /// uint operator &(uint x, uint y);
190 /// long operator &(long x, long y);
191 /// ulong operator &(ulong x, ulong y);
193 if (left is IntConstant){
194 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
195 return new IntConstant (res, left.Location);
197 if (left is UIntConstant){
198 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
199 return new UIntConstant (res, left.Location);
201 if (left is LongConstant){
202 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
203 return new LongConstant (res, left.Location);
205 if (left is ULongConstant){
206 ulong res = ((ULongConstant)left).Value &
207 ((ULongConstant)right).Value;
209 return new ULongConstant (res, left.Location);
213 case Binary.Operator.ExclusiveOr:
214 DoBinaryNumericPromotions (ref left, ref right);
215 if (left == null || right == null)
218 if (left is IntConstant){
219 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
220 return new IntConstant (res, left.Location);
222 if (left is UIntConstant){
223 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
225 return new UIntConstant (res, left.Location);
227 if (left is LongConstant){
228 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
230 return new LongConstant (res, left.Location);
232 if (left is ULongConstant){
233 ulong res = ((ULongConstant)left).Value ^
234 ((ULongConstant)right).Value;
236 return new ULongConstant (res, left.Location);
240 case Binary.Operator.Addition:
242 // If both sides are strings, then concatenate, if
243 // one is a string, and the other is not, then defer
244 // to runtime concatenation
246 if (lt == TypeManager.string_type || rt == TypeManager.string_type){
247 if (lt == TypeManager.string_type && rt == TypeManager.string_type)
248 return new StringConstant (
249 ((StringConstant) left).Value +
250 ((StringConstant) right).Value, left.Location);
256 // handle "E operator + (E x, U y)"
257 // handle "E operator + (Y y, E x)"
259 EnumConstant lc = left as EnumConstant;
260 EnumConstant rc = right as EnumConstant;
261 if (lc != null || rc != null){
268 // U has to be implicitly convetible to E.base
269 right = right.ConvertImplicitly (lc.Child.Type);
273 result = BinaryFold (ec, oper, lc.Child, right, loc);
277 result = result.TryReduce (ec, lt, loc);
281 return new EnumConstant (result, lt);
284 DoBinaryNumericPromotions (ref left, ref right);
285 if (left == null || right == null)
289 if (left is DoubleConstant){
292 if (ec.ConstantCheckState)
293 res = checked (((DoubleConstant) left).Value +
294 ((DoubleConstant) right).Value);
296 res = unchecked (((DoubleConstant) left).Value +
297 ((DoubleConstant) right).Value);
299 return new DoubleConstant (res, left.Location);
301 if (left is FloatConstant){
304 if (ec.ConstantCheckState)
305 res = checked (((FloatConstant) left).Value +
306 ((FloatConstant) right).Value);
308 res = unchecked (((FloatConstant) left).Value +
309 ((FloatConstant) right).Value);
311 result = new FloatConstant (res, left.Location);
312 } else if (left is ULongConstant){
315 if (ec.ConstantCheckState)
316 res = checked (((ULongConstant) left).Value +
317 ((ULongConstant) right).Value);
319 res = unchecked (((ULongConstant) left).Value +
320 ((ULongConstant) right).Value);
322 result = new ULongConstant (res, left.Location);
323 } else if (left is LongConstant){
326 if (ec.ConstantCheckState)
327 res = checked (((LongConstant) left).Value +
328 ((LongConstant) right).Value);
330 res = unchecked (((LongConstant) left).Value +
331 ((LongConstant) right).Value);
333 result = new LongConstant (res, left.Location);
334 } else if (left is UIntConstant){
337 if (ec.ConstantCheckState)
338 res = checked (((UIntConstant) left).Value +
339 ((UIntConstant) right).Value);
341 res = unchecked (((UIntConstant) left).Value +
342 ((UIntConstant) right).Value);
344 result = new UIntConstant (res, left.Location);
345 } else if (left is IntConstant){
348 if (ec.ConstantCheckState)
349 res = checked (((IntConstant) left).Value +
350 ((IntConstant) right).Value);
352 res = unchecked (((IntConstant) left).Value +
353 ((IntConstant) right).Value);
355 result = new IntConstant (res, left.Location);
356 } else if (left is DecimalConstant) {
359 if (ec.ConstantCheckState)
360 res = checked (((DecimalConstant) left).Value +
361 ((DecimalConstant) right).Value);
363 res = unchecked (((DecimalConstant) left).Value +
364 ((DecimalConstant) right).Value);
366 result = new DecimalConstant (res, left.Location);
368 throw new Exception ( "Unexepected addition input: " + left);
370 } catch (OverflowException){
371 Error_CompileTimeOverflow (loc);
376 case Binary.Operator.Subtraction:
378 // handle "E operator - (E x, U y)"
379 // handle "E operator - (Y y, E x)"
381 lc = left as EnumConstant;
382 rc = right as EnumConstant;
383 if (lc != null || rc != null){
390 // U has to be implicitly convetible to E.base
391 right = right.ConvertImplicitly (lc.Child.Type);
395 result = BinaryFold (ec, oper, lc.Child, right, loc);
399 result = result.TryReduce (ec, lt, loc);
403 return new EnumConstant (result, lt);
406 DoBinaryNumericPromotions (ref left, ref right);
407 if (left == null || right == null)
411 if (left is DoubleConstant){
414 if (ec.ConstantCheckState)
415 res = checked (((DoubleConstant) left).Value -
416 ((DoubleConstant) right).Value);
418 res = unchecked (((DoubleConstant) left).Value -
419 ((DoubleConstant) right).Value);
421 result = new DoubleConstant (res, left.Location);
422 } else if (left is FloatConstant){
425 if (ec.ConstantCheckState)
426 res = checked (((FloatConstant) left).Value -
427 ((FloatConstant) right).Value);
429 res = unchecked (((FloatConstant) left).Value -
430 ((FloatConstant) right).Value);
432 result = new FloatConstant (res, left.Location);
433 } else if (left is ULongConstant){
436 if (ec.ConstantCheckState)
437 res = checked (((ULongConstant) left).Value -
438 ((ULongConstant) right).Value);
440 res = unchecked (((ULongConstant) left).Value -
441 ((ULongConstant) right).Value);
443 result = new ULongConstant (res, left.Location);
444 } else if (left is LongConstant){
447 if (ec.ConstantCheckState)
448 res = checked (((LongConstant) left).Value -
449 ((LongConstant) right).Value);
451 res = unchecked (((LongConstant) left).Value -
452 ((LongConstant) right).Value);
454 result = new LongConstant (res, left.Location);
455 } else if (left is UIntConstant){
458 if (ec.ConstantCheckState)
459 res = checked (((UIntConstant) left).Value -
460 ((UIntConstant) right).Value);
462 res = unchecked (((UIntConstant) left).Value -
463 ((UIntConstant) right).Value);
465 result = new UIntConstant (res, left.Location);
466 } else if (left is IntConstant){
469 if (ec.ConstantCheckState)
470 res = checked (((IntConstant) left).Value -
471 ((IntConstant) right).Value);
473 res = unchecked (((IntConstant) left).Value -
474 ((IntConstant) right).Value);
476 result = new IntConstant (res, left.Location);
477 } else if (left is DecimalConstant) {
480 if (ec.ConstantCheckState)
481 res = checked (((DecimalConstant) left).Value -
482 ((DecimalConstant) right).Value);
484 res = unchecked (((DecimalConstant) left).Value -
485 ((DecimalConstant) right).Value);
487 return new DecimalConstant (res, left.Location);
489 throw new Exception ( "Unexepected subtraction input: " + left);
491 } catch (OverflowException){
492 Error_CompileTimeOverflow (loc);
497 case Binary.Operator.Multiply:
498 DoBinaryNumericPromotions (ref left, ref right);
499 if (left == null || right == null)
503 if (left is DoubleConstant){
506 if (ec.ConstantCheckState)
507 res = checked (((DoubleConstant) left).Value *
508 ((DoubleConstant) right).Value);
510 res = unchecked (((DoubleConstant) left).Value *
511 ((DoubleConstant) right).Value);
513 return new DoubleConstant (res, left.Location);
514 } else if (left is FloatConstant){
517 if (ec.ConstantCheckState)
518 res = checked (((FloatConstant) left).Value *
519 ((FloatConstant) right).Value);
521 res = unchecked (((FloatConstant) left).Value *
522 ((FloatConstant) right).Value);
524 return new FloatConstant (res, left.Location);
525 } else if (left is ULongConstant){
528 if (ec.ConstantCheckState)
529 res = checked (((ULongConstant) left).Value *
530 ((ULongConstant) right).Value);
532 res = unchecked (((ULongConstant) left).Value *
533 ((ULongConstant) right).Value);
535 return new ULongConstant (res, left.Location);
536 } else if (left is LongConstant){
539 if (ec.ConstantCheckState)
540 res = checked (((LongConstant) left).Value *
541 ((LongConstant) right).Value);
543 res = unchecked (((LongConstant) left).Value *
544 ((LongConstant) right).Value);
546 return new LongConstant (res, left.Location);
547 } else if (left is UIntConstant){
550 if (ec.ConstantCheckState)
551 res = checked (((UIntConstant) left).Value *
552 ((UIntConstant) right).Value);
554 res = unchecked (((UIntConstant) left).Value *
555 ((UIntConstant) right).Value);
557 return new UIntConstant (res, left.Location);
558 } else if (left is IntConstant){
561 if (ec.ConstantCheckState)
562 res = checked (((IntConstant) left).Value *
563 ((IntConstant) right).Value);
565 res = unchecked (((IntConstant) left).Value *
566 ((IntConstant) right).Value);
568 return new IntConstant (res, left.Location);
569 } else if (left is DecimalConstant) {
572 if (ec.ConstantCheckState)
573 res = checked (((DecimalConstant) left).Value *
574 ((DecimalConstant) right).Value);
576 res = unchecked (((DecimalConstant) left).Value *
577 ((DecimalConstant) right).Value);
579 return new DecimalConstant (res, left.Location);
581 throw new Exception ( "Unexepected multiply input: " + left);
583 } catch (OverflowException){
584 Error_CompileTimeOverflow (loc);
588 case Binary.Operator.Division:
589 DoBinaryNumericPromotions (ref left, ref right);
590 if (left == null || right == null)
594 if (left is DoubleConstant){
597 if (ec.ConstantCheckState)
598 res = checked (((DoubleConstant) left).Value /
599 ((DoubleConstant) right).Value);
601 res = unchecked (((DoubleConstant) left).Value /
602 ((DoubleConstant) right).Value);
604 return new DoubleConstant (res, left.Location);
605 } else if (left is FloatConstant){
608 if (ec.ConstantCheckState)
609 res = checked (((FloatConstant) left).Value /
610 ((FloatConstant) right).Value);
612 res = unchecked (((FloatConstant) left).Value /
613 ((FloatConstant) right).Value);
615 return new FloatConstant (res, left.Location);
616 } else if (left is ULongConstant){
619 if (ec.ConstantCheckState)
620 res = checked (((ULongConstant) left).Value /
621 ((ULongConstant) right).Value);
623 res = unchecked (((ULongConstant) left).Value /
624 ((ULongConstant) right).Value);
626 return new ULongConstant (res, left.Location);
627 } else if (left is LongConstant){
630 if (ec.ConstantCheckState)
631 res = checked (((LongConstant) left).Value /
632 ((LongConstant) right).Value);
634 res = unchecked (((LongConstant) left).Value /
635 ((LongConstant) right).Value);
637 return new LongConstant (res, left.Location);
638 } else if (left is UIntConstant){
641 if (ec.ConstantCheckState)
642 res = checked (((UIntConstant) left).Value /
643 ((UIntConstant) right).Value);
645 res = unchecked (((UIntConstant) left).Value /
646 ((UIntConstant) right).Value);
648 return new UIntConstant (res, left.Location);
649 } else if (left is IntConstant){
652 if (ec.ConstantCheckState)
653 res = checked (((IntConstant) left).Value /
654 ((IntConstant) right).Value);
656 res = unchecked (((IntConstant) left).Value /
657 ((IntConstant) right).Value);
659 return new IntConstant (res, left.Location);
660 } else if (left is DecimalConstant) {
663 if (ec.ConstantCheckState)
664 res = checked (((DecimalConstant) left).Value /
665 ((DecimalConstant) right).Value);
667 res = unchecked (((DecimalConstant) left).Value /
668 ((DecimalConstant) right).Value);
670 return new DecimalConstant (res, left.Location);
672 throw new Exception ( "Unexepected division input: " + left);
674 } catch (OverflowException){
675 Error_CompileTimeOverflow (loc);
677 } catch (DivideByZeroException) {
678 Report.Error (020, loc, "Division by constant zero");
683 case Binary.Operator.Modulus:
684 DoBinaryNumericPromotions (ref left, ref right);
685 if (left == null || right == null)
689 if (left is DoubleConstant){
692 if (ec.ConstantCheckState)
693 res = checked (((DoubleConstant) left).Value %
694 ((DoubleConstant) right).Value);
696 res = unchecked (((DoubleConstant) left).Value %
697 ((DoubleConstant) right).Value);
699 return new DoubleConstant (res, left.Location);
700 } else if (left is FloatConstant){
703 if (ec.ConstantCheckState)
704 res = checked (((FloatConstant) left).Value %
705 ((FloatConstant) right).Value);
707 res = unchecked (((FloatConstant) left).Value %
708 ((FloatConstant) right).Value);
710 return new FloatConstant (res, left.Location);
711 } else if (left is ULongConstant){
714 if (ec.ConstantCheckState)
715 res = checked (((ULongConstant) left).Value %
716 ((ULongConstant) right).Value);
718 res = unchecked (((ULongConstant) left).Value %
719 ((ULongConstant) right).Value);
721 return new ULongConstant (res, left.Location);
722 } else if (left is LongConstant){
725 if (ec.ConstantCheckState)
726 res = checked (((LongConstant) left).Value %
727 ((LongConstant) right).Value);
729 res = unchecked (((LongConstant) left).Value %
730 ((LongConstant) right).Value);
732 return new LongConstant (res, left.Location);
733 } else if (left is UIntConstant){
736 if (ec.ConstantCheckState)
737 res = checked (((UIntConstant) left).Value %
738 ((UIntConstant) right).Value);
740 res = unchecked (((UIntConstant) left).Value %
741 ((UIntConstant) right).Value);
743 return new UIntConstant (res, left.Location);
744 } else if (left is IntConstant){
747 if (ec.ConstantCheckState)
748 res = checked (((IntConstant) left).Value %
749 ((IntConstant) right).Value);
751 res = unchecked (((IntConstant) left).Value %
752 ((IntConstant) right).Value);
754 return new IntConstant (res, left.Location);
756 throw new Exception ( "Unexepected modulus input: " + left);
758 } catch (DivideByZeroException){
759 Report.Error (020, loc, "Division by constant zero");
760 } catch (OverflowException){
761 Error_CompileTimeOverflow (loc);
766 // There is no overflow checking on left shift
768 case Binary.Operator.LeftShift:
769 IntConstant ic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
771 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
775 int lshift_val = ic.Value;
776 if (left.Type == TypeManager.uint64_type)
777 return new ULongConstant (((ULongConstant)left).Value << lshift_val, left.Location);
778 if (left.Type == TypeManager.int64_type)
779 return new LongConstant (((LongConstant)left).Value << lshift_val, left.Location);
780 if (left.Type == TypeManager.uint32_type)
781 return new UIntConstant (((UIntConstant)left).Value << lshift_val, left.Location);
783 left = left.ConvertImplicitly (TypeManager.int32_type);
784 if (left.Type == TypeManager.int32_type)
785 return new IntConstant (((IntConstant)left).Value << lshift_val, left.Location);
787 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
791 // There is no overflow checking on right shift
793 case Binary.Operator.RightShift:
794 IntConstant sic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
796 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
799 int rshift_val = sic.Value;
800 if (left.Type == TypeManager.uint64_type)
801 return new ULongConstant (((ULongConstant)left).Value >> rshift_val, left.Location);
802 if (left.Type == TypeManager.int64_type)
803 return new LongConstant (((LongConstant)left).Value >> rshift_val, left.Location);
804 if (left.Type == TypeManager.uint32_type)
805 return new UIntConstant (((UIntConstant)left).Value >> rshift_val, left.Location);
807 left = left.ConvertImplicitly (TypeManager.int32_type);
808 if (left.Type == TypeManager.int32_type)
809 return new IntConstant (((IntConstant)left).Value >> rshift_val, left.Location);
811 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
814 case Binary.Operator.Equality:
815 if (left is NullConstant){
816 if (right is NullConstant)
817 return new BoolConstant (true, left.Location);
818 else if (right is StringConstant)
819 return new BoolConstant (
820 ((StringConstant) right).Value == null, left.Location);
821 } else if (right is NullConstant){
822 if (left is NullConstant)
823 return new BoolConstant (true, left.Location);
824 else if (left is StringConstant)
825 return new BoolConstant (
826 ((StringConstant) left).Value == null, left.Location);
828 if (left is StringConstant && right is StringConstant){
829 return new BoolConstant (
830 ((StringConstant) left).Value ==
831 ((StringConstant) right).Value, left.Location);
835 DoBinaryNumericPromotions (ref left, ref right);
836 if (left == null || right == null)
840 if (left is DoubleConstant)
841 bool_res = ((DoubleConstant) left).Value ==
842 ((DoubleConstant) right).Value;
843 else if (left is FloatConstant)
844 bool_res = ((FloatConstant) left).Value ==
845 ((FloatConstant) right).Value;
846 else if (left is ULongConstant)
847 bool_res = ((ULongConstant) left).Value ==
848 ((ULongConstant) right).Value;
849 else if (left is LongConstant)
850 bool_res = ((LongConstant) left).Value ==
851 ((LongConstant) right).Value;
852 else if (left is UIntConstant)
853 bool_res = ((UIntConstant) left).Value ==
854 ((UIntConstant) right).Value;
855 else if (left is IntConstant)
856 bool_res = ((IntConstant) left).Value ==
857 ((IntConstant) right).Value;
861 return new BoolConstant (bool_res, left.Location);
863 case Binary.Operator.Inequality:
864 if (left is NullConstant){
865 if (right is NullConstant)
866 return new BoolConstant (false, left.Location);
867 else if (right is StringConstant)
868 return new BoolConstant (
869 ((StringConstant) right).Value != null, left.Location);
870 } else if (right is NullConstant){
871 if (left is NullConstant)
872 return new BoolConstant (false, left.Location);
873 else if (left is StringConstant)
874 return new BoolConstant (
875 ((StringConstant) left).Value != null, left.Location);
877 if (left is StringConstant && right is StringConstant){
878 return new BoolConstant (
879 ((StringConstant) left).Value !=
880 ((StringConstant) right).Value, left.Location);
884 DoBinaryNumericPromotions (ref left, ref right);
885 if (left == null || right == null)
889 if (left is DoubleConstant)
890 bool_res = ((DoubleConstant) left).Value !=
891 ((DoubleConstant) right).Value;
892 else if (left is FloatConstant)
893 bool_res = ((FloatConstant) left).Value !=
894 ((FloatConstant) right).Value;
895 else if (left is ULongConstant)
896 bool_res = ((ULongConstant) left).Value !=
897 ((ULongConstant) right).Value;
898 else if (left is LongConstant)
899 bool_res = ((LongConstant) left).Value !=
900 ((LongConstant) right).Value;
901 else if (left is UIntConstant)
902 bool_res = ((UIntConstant) left).Value !=
903 ((UIntConstant) right).Value;
904 else if (left is IntConstant)
905 bool_res = ((IntConstant) left).Value !=
906 ((IntConstant) right).Value;
910 return new BoolConstant (bool_res, left.Location);
912 case Binary.Operator.LessThan:
913 DoBinaryNumericPromotions (ref left, ref right);
914 if (left == null || right == null)
918 if (left is DoubleConstant)
919 bool_res = ((DoubleConstant) left).Value <
920 ((DoubleConstant) right).Value;
921 else if (left is FloatConstant)
922 bool_res = ((FloatConstant) left).Value <
923 ((FloatConstant) right).Value;
924 else if (left is ULongConstant)
925 bool_res = ((ULongConstant) left).Value <
926 ((ULongConstant) right).Value;
927 else if (left is LongConstant)
928 bool_res = ((LongConstant) left).Value <
929 ((LongConstant) right).Value;
930 else if (left is UIntConstant)
931 bool_res = ((UIntConstant) left).Value <
932 ((UIntConstant) right).Value;
933 else if (left is IntConstant)
934 bool_res = ((IntConstant) left).Value <
935 ((IntConstant) right).Value;
939 return new BoolConstant (bool_res, left.Location);
941 case Binary.Operator.GreaterThan:
942 DoBinaryNumericPromotions (ref left, ref right);
943 if (left == null || right == null)
947 if (left is DoubleConstant)
948 bool_res = ((DoubleConstant) left).Value >
949 ((DoubleConstant) right).Value;
950 else if (left is FloatConstant)
951 bool_res = ((FloatConstant) left).Value >
952 ((FloatConstant) right).Value;
953 else if (left is ULongConstant)
954 bool_res = ((ULongConstant) left).Value >
955 ((ULongConstant) right).Value;
956 else if (left is LongConstant)
957 bool_res = ((LongConstant) left).Value >
958 ((LongConstant) right).Value;
959 else if (left is UIntConstant)
960 bool_res = ((UIntConstant) left).Value >
961 ((UIntConstant) right).Value;
962 else if (left is IntConstant)
963 bool_res = ((IntConstant) left).Value >
964 ((IntConstant) right).Value;
968 return new BoolConstant (bool_res, left.Location);
970 case Binary.Operator.GreaterThanOrEqual:
971 DoBinaryNumericPromotions (ref left, ref right);
972 if (left == null || right == null)
976 if (left is DoubleConstant)
977 bool_res = ((DoubleConstant) left).Value >=
978 ((DoubleConstant) right).Value;
979 else if (left is FloatConstant)
980 bool_res = ((FloatConstant) left).Value >=
981 ((FloatConstant) right).Value;
982 else if (left is ULongConstant)
983 bool_res = ((ULongConstant) left).Value >=
984 ((ULongConstant) right).Value;
985 else if (left is LongConstant)
986 bool_res = ((LongConstant) left).Value >=
987 ((LongConstant) right).Value;
988 else if (left is UIntConstant)
989 bool_res = ((UIntConstant) left).Value >=
990 ((UIntConstant) right).Value;
991 else if (left is IntConstant)
992 bool_res = ((IntConstant) left).Value >=
993 ((IntConstant) right).Value;
997 return new BoolConstant (bool_res, left.Location);
999 case Binary.Operator.LessThanOrEqual:
1000 DoBinaryNumericPromotions (ref left, ref right);
1001 if (left == null || right == null)
1005 if (left is DoubleConstant)
1006 bool_res = ((DoubleConstant) left).Value <=
1007 ((DoubleConstant) right).Value;
1008 else if (left is FloatConstant)
1009 bool_res = ((FloatConstant) left).Value <=
1010 ((FloatConstant) right).Value;
1011 else if (left is ULongConstant)
1012 bool_res = ((ULongConstant) left).Value <=
1013 ((ULongConstant) right).Value;
1014 else if (left is LongConstant)
1015 bool_res = ((LongConstant) left).Value <=
1016 ((LongConstant) right).Value;
1017 else if (left is UIntConstant)
1018 bool_res = ((UIntConstant) left).Value <=
1019 ((UIntConstant) right).Value;
1020 else if (left is IntConstant)
1021 bool_res = ((IntConstant) left).Value <=
1022 ((IntConstant) right).Value;
1026 return new BoolConstant (bool_res, left.Location);