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 (left is SideEffectConstant)
62 return BinaryFold (ec, oper, ((SideEffectConstant) left).left, right, loc);
64 if (right is EmptyConstantCast)
65 return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);
67 if (right is SideEffectConstant)
68 return BinaryFold (ec, oper, left, ((SideEffectConstant) right).left, loc);
73 Constant result = null;
75 if (lt == TypeManager.bool_type && lt == rt) {
76 bool lv = ((BoolConstant) left ).Value;
77 bool rv = ((BoolConstant) right).Value;
79 case Binary.Operator.BitwiseAnd:
80 case Binary.Operator.LogicalAnd:
81 return new BoolConstant (lv && rv, left.Location);
82 case Binary.Operator.BitwiseOr:
83 case Binary.Operator.LogicalOr:
84 return new BoolConstant (lv || rv, left.Location);
85 case Binary.Operator.ExclusiveOr:
86 return new BoolConstant (lv ^ rv, left.Location);
87 case Binary.Operator.Equality:
88 return new BoolConstant (lv == rv, left.Location);
89 case Binary.Operator.Inequality:
90 return new BoolConstant (lv != rv, left.Location);
96 // During an enum evaluation, none of the rules are valid
97 // Not sure whether it is bug in csc or in documentation
99 if (ec.InEnumContext){
100 if (left is EnumConstant)
101 left = ((EnumConstant) left).Child;
103 if (right is EnumConstant)
104 right = ((EnumConstant) right).Child;
105 } else if (left is EnumConstant && rt == lt) {
108 /// E operator |(E x, E y);
109 /// E operator &(E x, E y);
110 /// E operator ^(E x, E y);
112 case Binary.Operator.BitwiseOr:
113 case Binary.Operator.BitwiseAnd:
114 case Binary.Operator.ExclusiveOr:
115 return BinaryFold (ec, oper, ((EnumConstant)left).Child,
116 ((EnumConstant)right).Child, loc).TryReduce (ec, lt, loc);
119 /// U operator -(E x, E y);
121 case Binary.Operator.Subtraction:
122 result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
123 return result.TryReduce (ec, ((EnumConstant)left).Child.Type, loc);
126 /// bool operator ==(E x, E y);
127 /// bool operator !=(E x, E y);
128 /// bool operator <(E x, E y);
129 /// bool operator >(E x, E y);
130 /// bool operator <=(E x, E y);
131 /// bool operator >=(E x, E y);
133 case Binary.Operator.Equality:
134 case Binary.Operator.Inequality:
135 case Binary.Operator.LessThan:
136 case Binary.Operator.GreaterThan:
137 case Binary.Operator.LessThanOrEqual:
138 case Binary.Operator.GreaterThanOrEqual:
139 return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
145 case Binary.Operator.BitwiseOr:
146 DoBinaryNumericPromotions (ref left, ref right);
147 if (left == null || right == null)
150 if (left is IntConstant){
151 int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
153 return new IntConstant (res, left.Location);
155 if (left is UIntConstant){
156 uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
158 return new UIntConstant (res, left.Location);
160 if (left is LongConstant){
161 long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
163 return new LongConstant (res, left.Location);
165 if (left is ULongConstant){
166 ulong res = ((ULongConstant)left).Value |
167 ((ULongConstant)right).Value;
169 return new ULongConstant (res, left.Location);
173 case Binary.Operator.BitwiseAnd:
174 DoBinaryNumericPromotions (ref left, ref right);
175 if (left == null || right == null)
179 /// int operator &(int x, int y);
180 /// uint operator &(uint x, uint y);
181 /// long operator &(long x, long y);
182 /// ulong operator &(ulong x, ulong y);
184 if (left is IntConstant){
185 int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
186 return new IntConstant (res, left.Location);
188 if (left is UIntConstant){
189 uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
190 return new UIntConstant (res, left.Location);
192 if (left is LongConstant){
193 long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
194 return new LongConstant (res, left.Location);
196 if (left is ULongConstant){
197 ulong res = ((ULongConstant)left).Value &
198 ((ULongConstant)right).Value;
200 return new ULongConstant (res, left.Location);
204 case Binary.Operator.ExclusiveOr:
205 DoBinaryNumericPromotions (ref left, ref right);
206 if (left == null || right == null)
209 if (left is IntConstant){
210 int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
211 return new IntConstant (res, left.Location);
213 if (left is UIntConstant){
214 uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
216 return new UIntConstant (res, left.Location);
218 if (left is LongConstant){
219 long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
221 return new LongConstant (res, left.Location);
223 if (left is ULongConstant){
224 ulong res = ((ULongConstant)left).Value ^
225 ((ULongConstant)right).Value;
227 return new ULongConstant (res, left.Location);
231 case Binary.Operator.Addition:
233 // If both sides are strings, then concatenate, if
234 // one is a string, and the other is not, then defer
235 // to runtime concatenation
237 if (lt == TypeManager.string_type || rt == TypeManager.string_type){
238 if (lt == TypeManager.string_type && rt == TypeManager.string_type)
239 return new StringConstant (
240 ((StringConstant) left).Value +
241 ((StringConstant) right).Value, left.Location);
247 // handle "E operator + (E x, U y)"
248 // handle "E operator + (Y y, E x)"
250 EnumConstant lc = left as EnumConstant;
251 EnumConstant rc = right as EnumConstant;
252 if (lc != null || rc != null){
259 // U has to be implicitly convetible to E.base
260 right = right.ConvertImplicitly (lc.Child.Type);
264 result = BinaryFold (ec, oper, lc.Child, right, loc);
268 result = result.TryReduce (ec, lt, loc);
272 return new EnumConstant (result, lt);
275 DoBinaryNumericPromotions (ref left, ref right);
276 if (left == null || right == null)
280 if (left is DoubleConstant){
283 if (ec.ConstantCheckState)
284 res = checked (((DoubleConstant) left).Value +
285 ((DoubleConstant) right).Value);
287 res = unchecked (((DoubleConstant) left).Value +
288 ((DoubleConstant) right).Value);
290 return new DoubleConstant (res, left.Location);
292 if (left is FloatConstant){
295 if (ec.ConstantCheckState)
296 res = checked (((FloatConstant) left).Value +
297 ((FloatConstant) right).Value);
299 res = unchecked (((FloatConstant) left).Value +
300 ((FloatConstant) right).Value);
302 result = new FloatConstant (res, left.Location);
303 } else if (left is ULongConstant){
306 if (ec.ConstantCheckState)
307 res = checked (((ULongConstant) left).Value +
308 ((ULongConstant) right).Value);
310 res = unchecked (((ULongConstant) left).Value +
311 ((ULongConstant) right).Value);
313 result = new ULongConstant (res, left.Location);
314 } else if (left is LongConstant){
317 if (ec.ConstantCheckState)
318 res = checked (((LongConstant) left).Value +
319 ((LongConstant) right).Value);
321 res = unchecked (((LongConstant) left).Value +
322 ((LongConstant) right).Value);
324 result = new LongConstant (res, left.Location);
325 } else if (left is UIntConstant){
328 if (ec.ConstantCheckState)
329 res = checked (((UIntConstant) left).Value +
330 ((UIntConstant) right).Value);
332 res = unchecked (((UIntConstant) left).Value +
333 ((UIntConstant) right).Value);
335 result = new UIntConstant (res, left.Location);
336 } else if (left is IntConstant){
339 if (ec.ConstantCheckState)
340 res = checked (((IntConstant) left).Value +
341 ((IntConstant) right).Value);
343 res = unchecked (((IntConstant) left).Value +
344 ((IntConstant) right).Value);
346 result = new IntConstant (res, left.Location);
347 } else if (left is DecimalConstant) {
350 if (ec.ConstantCheckState)
351 res = checked (((DecimalConstant) left).Value +
352 ((DecimalConstant) right).Value);
354 res = unchecked (((DecimalConstant) left).Value +
355 ((DecimalConstant) right).Value);
357 result = new DecimalConstant (res, left.Location);
359 throw new Exception ( "Unexepected addition input: " + left);
361 } catch (OverflowException){
362 Error_CompileTimeOverflow (loc);
367 case Binary.Operator.Subtraction:
369 // handle "E operator - (E x, U y)"
370 // handle "E operator - (Y y, E x)"
372 lc = left as EnumConstant;
373 rc = right as EnumConstant;
374 if (lc != null || rc != null){
381 // U has to be implicitly convetible to E.base
382 right = right.ConvertImplicitly (lc.Child.Type);
386 result = BinaryFold (ec, oper, lc.Child, right, loc);
390 result = result.TryReduce (ec, lt, loc);
394 return new EnumConstant (result, lt);
397 DoBinaryNumericPromotions (ref left, ref right);
398 if (left == null || right == null)
402 if (left is DoubleConstant){
405 if (ec.ConstantCheckState)
406 res = checked (((DoubleConstant) left).Value -
407 ((DoubleConstant) right).Value);
409 res = unchecked (((DoubleConstant) left).Value -
410 ((DoubleConstant) right).Value);
412 result = new DoubleConstant (res, left.Location);
413 } else if (left is FloatConstant){
416 if (ec.ConstantCheckState)
417 res = checked (((FloatConstant) left).Value -
418 ((FloatConstant) right).Value);
420 res = unchecked (((FloatConstant) left).Value -
421 ((FloatConstant) right).Value);
423 result = new FloatConstant (res, left.Location);
424 } else if (left is ULongConstant){
427 if (ec.ConstantCheckState)
428 res = checked (((ULongConstant) left).Value -
429 ((ULongConstant) right).Value);
431 res = unchecked (((ULongConstant) left).Value -
432 ((ULongConstant) right).Value);
434 result = new ULongConstant (res, left.Location);
435 } else if (left is LongConstant){
438 if (ec.ConstantCheckState)
439 res = checked (((LongConstant) left).Value -
440 ((LongConstant) right).Value);
442 res = unchecked (((LongConstant) left).Value -
443 ((LongConstant) right).Value);
445 result = new LongConstant (res, left.Location);
446 } else if (left is UIntConstant){
449 if (ec.ConstantCheckState)
450 res = checked (((UIntConstant) left).Value -
451 ((UIntConstant) right).Value);
453 res = unchecked (((UIntConstant) left).Value -
454 ((UIntConstant) right).Value);
456 result = new UIntConstant (res, left.Location);
457 } else if (left is IntConstant){
460 if (ec.ConstantCheckState)
461 res = checked (((IntConstant) left).Value -
462 ((IntConstant) right).Value);
464 res = unchecked (((IntConstant) left).Value -
465 ((IntConstant) right).Value);
467 result = new IntConstant (res, left.Location);
468 } else if (left is DecimalConstant) {
471 if (ec.ConstantCheckState)
472 res = checked (((DecimalConstant) left).Value -
473 ((DecimalConstant) right).Value);
475 res = unchecked (((DecimalConstant) left).Value -
476 ((DecimalConstant) right).Value);
478 return new DecimalConstant (res, left.Location);
480 throw new Exception ( "Unexepected subtraction input: " + left);
482 } catch (OverflowException){
483 Error_CompileTimeOverflow (loc);
488 case Binary.Operator.Multiply:
489 DoBinaryNumericPromotions (ref left, ref right);
490 if (left == null || right == null)
494 if (left is DoubleConstant){
497 if (ec.ConstantCheckState)
498 res = checked (((DoubleConstant) left).Value *
499 ((DoubleConstant) right).Value);
501 res = unchecked (((DoubleConstant) left).Value *
502 ((DoubleConstant) right).Value);
504 return new DoubleConstant (res, left.Location);
505 } else if (left is FloatConstant){
508 if (ec.ConstantCheckState)
509 res = checked (((FloatConstant) left).Value *
510 ((FloatConstant) right).Value);
512 res = unchecked (((FloatConstant) left).Value *
513 ((FloatConstant) right).Value);
515 return new FloatConstant (res, left.Location);
516 } else if (left is ULongConstant){
519 if (ec.ConstantCheckState)
520 res = checked (((ULongConstant) left).Value *
521 ((ULongConstant) right).Value);
523 res = unchecked (((ULongConstant) left).Value *
524 ((ULongConstant) right).Value);
526 return new ULongConstant (res, left.Location);
527 } else if (left is LongConstant){
530 if (ec.ConstantCheckState)
531 res = checked (((LongConstant) left).Value *
532 ((LongConstant) right).Value);
534 res = unchecked (((LongConstant) left).Value *
535 ((LongConstant) right).Value);
537 return new LongConstant (res, left.Location);
538 } else if (left is UIntConstant){
541 if (ec.ConstantCheckState)
542 res = checked (((UIntConstant) left).Value *
543 ((UIntConstant) right).Value);
545 res = unchecked (((UIntConstant) left).Value *
546 ((UIntConstant) right).Value);
548 return new UIntConstant (res, left.Location);
549 } else if (left is IntConstant){
552 if (ec.ConstantCheckState)
553 res = checked (((IntConstant) left).Value *
554 ((IntConstant) right).Value);
556 res = unchecked (((IntConstant) left).Value *
557 ((IntConstant) right).Value);
559 return new IntConstant (res, left.Location);
560 } else if (left is DecimalConstant) {
563 if (ec.ConstantCheckState)
564 res = checked (((DecimalConstant) left).Value *
565 ((DecimalConstant) right).Value);
567 res = unchecked (((DecimalConstant) left).Value *
568 ((DecimalConstant) right).Value);
570 return new DecimalConstant (res, left.Location);
572 throw new Exception ( "Unexepected multiply input: " + left);
574 } catch (OverflowException){
575 Error_CompileTimeOverflow (loc);
579 case Binary.Operator.Division:
580 DoBinaryNumericPromotions (ref left, ref right);
581 if (left == null || right == null)
585 if (left is DoubleConstant){
588 if (ec.ConstantCheckState)
589 res = checked (((DoubleConstant) left).Value /
590 ((DoubleConstant) right).Value);
592 res = unchecked (((DoubleConstant) left).Value /
593 ((DoubleConstant) right).Value);
595 return new DoubleConstant (res, left.Location);
596 } else if (left is FloatConstant){
599 if (ec.ConstantCheckState)
600 res = checked (((FloatConstant) left).Value /
601 ((FloatConstant) right).Value);
603 res = unchecked (((FloatConstant) left).Value /
604 ((FloatConstant) right).Value);
606 return new FloatConstant (res, left.Location);
607 } else if (left is ULongConstant){
610 if (ec.ConstantCheckState)
611 res = checked (((ULongConstant) left).Value /
612 ((ULongConstant) right).Value);
614 res = unchecked (((ULongConstant) left).Value /
615 ((ULongConstant) right).Value);
617 return new ULongConstant (res, left.Location);
618 } else if (left is LongConstant){
621 if (ec.ConstantCheckState)
622 res = checked (((LongConstant) left).Value /
623 ((LongConstant) right).Value);
625 res = unchecked (((LongConstant) left).Value /
626 ((LongConstant) right).Value);
628 return new LongConstant (res, left.Location);
629 } else if (left is UIntConstant){
632 if (ec.ConstantCheckState)
633 res = checked (((UIntConstant) left).Value /
634 ((UIntConstant) right).Value);
636 res = unchecked (((UIntConstant) left).Value /
637 ((UIntConstant) right).Value);
639 return new UIntConstant (res, left.Location);
640 } else if (left is IntConstant){
643 if (ec.ConstantCheckState)
644 res = checked (((IntConstant) left).Value /
645 ((IntConstant) right).Value);
647 res = unchecked (((IntConstant) left).Value /
648 ((IntConstant) right).Value);
650 return new IntConstant (res, left.Location);
651 } else if (left is DecimalConstant) {
654 if (ec.ConstantCheckState)
655 res = checked (((DecimalConstant) left).Value /
656 ((DecimalConstant) right).Value);
658 res = unchecked (((DecimalConstant) left).Value /
659 ((DecimalConstant) right).Value);
661 return new DecimalConstant (res, left.Location);
663 throw new Exception ( "Unexepected division input: " + left);
665 } catch (OverflowException){
666 Error_CompileTimeOverflow (loc);
668 } catch (DivideByZeroException) {
669 Report.Error (020, loc, "Division by constant zero");
674 case Binary.Operator.Modulus:
675 DoBinaryNumericPromotions (ref left, ref right);
676 if (left == null || right == null)
680 if (left is DoubleConstant){
683 if (ec.ConstantCheckState)
684 res = checked (((DoubleConstant) left).Value %
685 ((DoubleConstant) right).Value);
687 res = unchecked (((DoubleConstant) left).Value %
688 ((DoubleConstant) right).Value);
690 return new DoubleConstant (res, left.Location);
691 } else if (left is FloatConstant){
694 if (ec.ConstantCheckState)
695 res = checked (((FloatConstant) left).Value %
696 ((FloatConstant) right).Value);
698 res = unchecked (((FloatConstant) left).Value %
699 ((FloatConstant) right).Value);
701 return new FloatConstant (res, left.Location);
702 } else if (left is ULongConstant){
705 if (ec.ConstantCheckState)
706 res = checked (((ULongConstant) left).Value %
707 ((ULongConstant) right).Value);
709 res = unchecked (((ULongConstant) left).Value %
710 ((ULongConstant) right).Value);
712 return new ULongConstant (res, left.Location);
713 } else if (left is LongConstant){
716 if (ec.ConstantCheckState)
717 res = checked (((LongConstant) left).Value %
718 ((LongConstant) right).Value);
720 res = unchecked (((LongConstant) left).Value %
721 ((LongConstant) right).Value);
723 return new LongConstant (res, left.Location);
724 } else if (left is UIntConstant){
727 if (ec.ConstantCheckState)
728 res = checked (((UIntConstant) left).Value %
729 ((UIntConstant) right).Value);
731 res = unchecked (((UIntConstant) left).Value %
732 ((UIntConstant) right).Value);
734 return new UIntConstant (res, left.Location);
735 } else if (left is IntConstant){
738 if (ec.ConstantCheckState)
739 res = checked (((IntConstant) left).Value %
740 ((IntConstant) right).Value);
742 res = unchecked (((IntConstant) left).Value %
743 ((IntConstant) right).Value);
745 return new IntConstant (res, left.Location);
747 throw new Exception ( "Unexepected modulus input: " + left);
749 } catch (DivideByZeroException){
750 Report.Error (020, loc, "Division by constant zero");
751 } catch (OverflowException){
752 Error_CompileTimeOverflow (loc);
757 // There is no overflow checking on left shift
759 case Binary.Operator.LeftShift:
760 IntConstant ic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
762 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
766 int lshift_val = ic.Value;
767 if (left.Type == TypeManager.uint64_type)
768 return new ULongConstant (((ULongConstant)left).Value << lshift_val, left.Location);
769 if (left.Type == TypeManager.int64_type)
770 return new LongConstant (((LongConstant)left).Value << lshift_val, left.Location);
771 if (left.Type == TypeManager.uint32_type)
772 return new UIntConstant (((UIntConstant)left).Value << lshift_val, left.Location);
774 left = left.ConvertImplicitly (TypeManager.int32_type);
775 if (left.Type == TypeManager.int32_type)
776 return new IntConstant (((IntConstant)left).Value << lshift_val, left.Location);
778 Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
782 // There is no overflow checking on right shift
784 case Binary.Operator.RightShift:
785 IntConstant sic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
787 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
790 int rshift_val = sic.Value;
791 if (left.Type == TypeManager.uint64_type)
792 return new ULongConstant (((ULongConstant)left).Value >> rshift_val, left.Location);
793 if (left.Type == TypeManager.int64_type)
794 return new LongConstant (((LongConstant)left).Value >> rshift_val, left.Location);
795 if (left.Type == TypeManager.uint32_type)
796 return new UIntConstant (((UIntConstant)left).Value >> rshift_val, left.Location);
798 left = left.ConvertImplicitly (TypeManager.int32_type);
799 if (left.Type == TypeManager.int32_type)
800 return new IntConstant (((IntConstant)left).Value >> rshift_val, left.Location);
802 Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
805 case Binary.Operator.Equality:
806 if (left is NullConstant){
807 if (right is NullConstant)
808 return new BoolConstant (true, left.Location);
809 else if (right is StringConstant)
810 return new BoolConstant (
811 ((StringConstant) right).Value == null, left.Location);
812 } else if (right is NullConstant){
813 if (left is NullConstant)
814 return new BoolConstant (true, left.Location);
815 else if (left is StringConstant)
816 return new BoolConstant (
817 ((StringConstant) left).Value == null, left.Location);
819 if (left is StringConstant && right is StringConstant){
820 return new BoolConstant (
821 ((StringConstant) left).Value ==
822 ((StringConstant) right).Value, left.Location);
826 DoBinaryNumericPromotions (ref left, ref right);
827 if (left == null || right == null)
831 if (left is DoubleConstant)
832 bool_res = ((DoubleConstant) left).Value ==
833 ((DoubleConstant) right).Value;
834 else if (left is FloatConstant)
835 bool_res = ((FloatConstant) left).Value ==
836 ((FloatConstant) right).Value;
837 else if (left is ULongConstant)
838 bool_res = ((ULongConstant) left).Value ==
839 ((ULongConstant) right).Value;
840 else if (left is LongConstant)
841 bool_res = ((LongConstant) left).Value ==
842 ((LongConstant) right).Value;
843 else if (left is UIntConstant)
844 bool_res = ((UIntConstant) left).Value ==
845 ((UIntConstant) right).Value;
846 else if (left is IntConstant)
847 bool_res = ((IntConstant) left).Value ==
848 ((IntConstant) right).Value;
852 return new BoolConstant (bool_res, left.Location);
854 case Binary.Operator.Inequality:
855 if (left is NullConstant){
856 if (right is NullConstant)
857 return new BoolConstant (false, left.Location);
858 else if (right is StringConstant)
859 return new BoolConstant (
860 ((StringConstant) right).Value != null, left.Location);
861 } else if (right is NullConstant){
862 if (left is NullConstant)
863 return new BoolConstant (false, left.Location);
864 else if (left is StringConstant)
865 return new BoolConstant (
866 ((StringConstant) left).Value != null, left.Location);
868 if (left is StringConstant && right is StringConstant){
869 return new BoolConstant (
870 ((StringConstant) left).Value !=
871 ((StringConstant) right).Value, left.Location);
875 DoBinaryNumericPromotions (ref left, ref right);
876 if (left == null || right == null)
880 if (left is DoubleConstant)
881 bool_res = ((DoubleConstant) left).Value !=
882 ((DoubleConstant) right).Value;
883 else if (left is FloatConstant)
884 bool_res = ((FloatConstant) left).Value !=
885 ((FloatConstant) right).Value;
886 else if (left is ULongConstant)
887 bool_res = ((ULongConstant) left).Value !=
888 ((ULongConstant) right).Value;
889 else if (left is LongConstant)
890 bool_res = ((LongConstant) left).Value !=
891 ((LongConstant) right).Value;
892 else if (left is UIntConstant)
893 bool_res = ((UIntConstant) left).Value !=
894 ((UIntConstant) right).Value;
895 else if (left is IntConstant)
896 bool_res = ((IntConstant) left).Value !=
897 ((IntConstant) right).Value;
901 return new BoolConstant (bool_res, left.Location);
903 case Binary.Operator.LessThan:
904 DoBinaryNumericPromotions (ref left, ref right);
905 if (left == null || right == null)
909 if (left is DoubleConstant)
910 bool_res = ((DoubleConstant) left).Value <
911 ((DoubleConstant) right).Value;
912 else if (left is FloatConstant)
913 bool_res = ((FloatConstant) left).Value <
914 ((FloatConstant) right).Value;
915 else if (left is ULongConstant)
916 bool_res = ((ULongConstant) left).Value <
917 ((ULongConstant) right).Value;
918 else if (left is LongConstant)
919 bool_res = ((LongConstant) left).Value <
920 ((LongConstant) right).Value;
921 else if (left is UIntConstant)
922 bool_res = ((UIntConstant) left).Value <
923 ((UIntConstant) right).Value;
924 else if (left is IntConstant)
925 bool_res = ((IntConstant) left).Value <
926 ((IntConstant) right).Value;
930 return new BoolConstant (bool_res, left.Location);
932 case Binary.Operator.GreaterThan:
933 DoBinaryNumericPromotions (ref left, ref right);
934 if (left == null || right == null)
938 if (left is DoubleConstant)
939 bool_res = ((DoubleConstant) left).Value >
940 ((DoubleConstant) right).Value;
941 else if (left is FloatConstant)
942 bool_res = ((FloatConstant) left).Value >
943 ((FloatConstant) right).Value;
944 else if (left is ULongConstant)
945 bool_res = ((ULongConstant) left).Value >
946 ((ULongConstant) right).Value;
947 else if (left is LongConstant)
948 bool_res = ((LongConstant) left).Value >
949 ((LongConstant) right).Value;
950 else if (left is UIntConstant)
951 bool_res = ((UIntConstant) left).Value >
952 ((UIntConstant) right).Value;
953 else if (left is IntConstant)
954 bool_res = ((IntConstant) left).Value >
955 ((IntConstant) right).Value;
959 return new BoolConstant (bool_res, left.Location);
961 case Binary.Operator.GreaterThanOrEqual:
962 DoBinaryNumericPromotions (ref left, ref right);
963 if (left == null || right == null)
967 if (left is DoubleConstant)
968 bool_res = ((DoubleConstant) left).Value >=
969 ((DoubleConstant) right).Value;
970 else if (left is FloatConstant)
971 bool_res = ((FloatConstant) left).Value >=
972 ((FloatConstant) right).Value;
973 else if (left is ULongConstant)
974 bool_res = ((ULongConstant) left).Value >=
975 ((ULongConstant) right).Value;
976 else if (left is LongConstant)
977 bool_res = ((LongConstant) left).Value >=
978 ((LongConstant) right).Value;
979 else if (left is UIntConstant)
980 bool_res = ((UIntConstant) left).Value >=
981 ((UIntConstant) right).Value;
982 else if (left is IntConstant)
983 bool_res = ((IntConstant) left).Value >=
984 ((IntConstant) right).Value;
988 return new BoolConstant (bool_res, left.Location);
990 case Binary.Operator.LessThanOrEqual:
991 DoBinaryNumericPromotions (ref left, ref right);
992 if (left == null || right == null)
996 if (left is DoubleConstant)
997 bool_res = ((DoubleConstant) left).Value <=
998 ((DoubleConstant) right).Value;
999 else if (left is FloatConstant)
1000 bool_res = ((FloatConstant) left).Value <=
1001 ((FloatConstant) right).Value;
1002 else if (left is ULongConstant)
1003 bool_res = ((ULongConstant) left).Value <=
1004 ((ULongConstant) right).Value;
1005 else if (left is LongConstant)
1006 bool_res = ((LongConstant) left).Value <=
1007 ((LongConstant) right).Value;
1008 else if (left is UIntConstant)
1009 bool_res = ((UIntConstant) left).Value <=
1010 ((UIntConstant) right).Value;
1011 else if (left is IntConstant)
1012 bool_res = ((IntConstant) left).Value <=
1013 ((IntConstant) right).Value;
1017 return new BoolConstant (bool_res, left.Location);