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
);