⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfold.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
//// cfold.cs: Constant Folding//// Author://   Miguel de Icaza (miguel@ximian.com)//// (C) 2002, 2003 Ximian, Inc.//using System;namespace Mono.CSharp {	public class ConstantFold {		//		// Performs the numeric promotions on the left and right expresions		// and desposits the results on `lc' and `rc'.		//		// On success, the types of `lc' and `rc' on output will always match,		// and the pair will be one of:		//		//   (double, double)		//   (float, float)		//   (ulong, ulong)		//   (long, long)		//   (uint, uint)		//   (int, int)		//   (short, short)   (Happens with enumerations with underlying short type)		//   (ushort, ushort) (Happens with enumerations with underlying short type)		//		static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,							 ref Constant left, ref Constant right,							 Location loc)		{			if (left is DoubleConstant || right is DoubleConstant){				//				// If either side is a double, convert the other to a double				//				if (!(left is DoubleConstant))					left = left.ToDouble (loc);				if (!(right is DoubleConstant))					right = right.ToDouble (loc);				return;			} else if (left is FloatConstant || right is FloatConstant) {				//				// If either side is a float, convert the other to a float				//				if (!(left is FloatConstant))					left = left.ToFloat (loc);				if (!(right is FloatConstant))					right = right.ToFloat (loc);;				return;			} else if (left is ULongConstant || right is ULongConstant){				//				// If either operand is of type ulong, the other operand is				// converted to type ulong.  or an error ocurrs if the other				// operand is of type sbyte, short, int or long				//#if WRONG				Constant match, other;#endif									if (left is ULongConstant){#if WRONG					other = right;					match = left;#endif					if (!(right is ULongConstant))						right = right.ToULong (loc);				} else {#if WRONG					other = left;					match = right;#endif					left = left.ToULong (loc);				}#if WRONG				if (other is SByteConstant || other is ShortConstant ||				    other is IntConstant || other is LongConstant){					Binary.Error_OperatorAmbiguous						(loc, oper, other.Type, match.Type);					left = null;					right = null;				}#endif				return;			} else if (left is LongConstant || right is LongConstant){				//				// If either operand is of type long, the other operand is converted				// to type long.				//				if (!(left is LongConstant))					left = left.ToLong (loc);				else if (!(right is LongConstant))					right = right.ToLong (loc);				return;			} else if (left is UIntConstant || right is UIntConstant){				//				// If either operand is of type uint, and the other				// operand is of type sbyte, short or int, the operands are				// converted to type long.				//				Constant other;				if (left is UIntConstant)					other = right;				else					other = left;				// Nothing to do.				if (other is UIntConstant)					return;				IntConstant ic = other as IntConstant;				if (ic != null){					if (ic.Value >= 0){						if (left == other)							left = new UIntConstant ((uint) ic.Value, ic.Location);						else							right = new UIntConstant ((uint) ic.Value, ic.Location);						return;					}				}								if (other is SByteConstant || other is ShortConstant || ic != null){					left = left.ToLong (loc);					right = right.ToLong (loc);				} else {					left = left.ToUInt (loc);					right = left.ToUInt (loc);				}				return;			} else if (left is DecimalConstant || right is DecimalConstant) {				if (!(left is DecimalConstant))					left = left.ToDecimal (loc);				else if (!(right is DecimalConstant))					right = right.ToDecimal (loc);				return;			} else if (left is EnumConstant || right is EnumConstant){				if (left is EnumConstant)					left = ((EnumConstant) left).Child;				if (right is EnumConstant)					right = ((EnumConstant) right).Child;				DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);				return;			} else {				//				// Force conversions to int32				//				if (!(left is IntConstant))					left = left.ToInt (loc);				if (!(right is IntConstant))					right = right.ToInt (loc);			}			return;		}		static void Error_CompileTimeOverflow (Location loc)		{			Report.Error (220, loc, "The operation overflows at compile time in checked mode");		}				/// <summary>		///   Constant expression folder for binary operations.		///		///   Returns null if the expression can not be folded.		/// </summary>		static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,						     Constant left, Constant right, Location loc)		{			if (left is NullCast)				return BinaryFold (ec, oper, ((NullCast)left).child, right, loc);			if (right is NullCast)				return BinaryFold (ec, oper, left, ((NullCast)right).child, loc);			Type lt = left.Type;			Type rt = right.Type;			Type result_type = null;			bool bool_res;			//			// Enumerator folding			//			if (rt == lt && left is EnumConstant)				result_type = lt;			//			// During an enum evaluation, we need to unwrap enumerations			//			if (ec.InEnumContext){				if (left is EnumConstant)					left = ((EnumConstant) left).Child;								if (right is EnumConstant)					right = ((EnumConstant) right).Child;			}			Type wrap_as;			Constant result = null;			switch (oper){			case Binary.Operator.BitwiseOr:				DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);				if (left == null || right == null)					return null;				if (left is IntConstant){					IntConstant v;					int res = ((IntConstant) left).Value | ((IntConstant) right).Value;										v = new IntConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is UIntConstant){					UIntConstant v;					uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;										v = new UIntConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is LongConstant){					LongConstant v;					long res = ((LongConstant)left).Value | ((LongConstant)right).Value;										v = new LongConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is ULongConstant){					ULongConstant v;					ulong res = ((ULongConstant)left).Value |						((ULongConstant)right).Value;										v = new ULongConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is UShortConstant){					UShortConstant v;					ushort res = (ushort) (((UShortConstant)left).Value |							       ((UShortConstant)right).Value);										v = new UShortConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is ShortConstant){					ShortConstant v;					short res = (short) (((ShortConstant)left).Value |							     ((ShortConstant)right).Value);										v = new ShortConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				}				break;							case Binary.Operator.BitwiseAnd:				DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);				if (left == null || right == null)					return null;								if (left is IntConstant){					IntConstant v;					int res = ((IntConstant) left).Value & ((IntConstant) right).Value;										v = new IntConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is UIntConstant){					UIntConstant v;					uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;										v = new UIntConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is LongConstant){					LongConstant v;					long res = ((LongConstant)left).Value & ((LongConstant)right).Value;										v = new LongConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is ULongConstant){					ULongConstant v;					ulong res = ((ULongConstant)left).Value &						((ULongConstant)right).Value;										v = new ULongConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is UShortConstant){					UShortConstant v;					ushort res = (ushort) (((UShortConstant)left).Value &							       ((UShortConstant)right).Value);										v = new UShortConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is ShortConstant){					ShortConstant v;					short res = (short) (((ShortConstant)left).Value &							     ((ShortConstant)right).Value);										v = new ShortConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				}				break;			case Binary.Operator.ExclusiveOr:				DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);				if (left == null || right == null)					return null;								if (left is IntConstant){					IntConstant v;					int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;										v = new IntConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is UIntConstant){					UIntConstant v;					uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;										v = new UIntConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is LongConstant){					LongConstant v;					long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;										v = new LongConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is ULongConstant){					ULongConstant v;					ulong res = ((ULongConstant)left).Value ^						((ULongConstant)right).Value;										v = new ULongConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is UShortConstant){					UShortConstant v;					ushort res = (ushort) (((UShortConstant)left).Value ^							       ((UShortConstant)right).Value);										v = new UShortConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				} else if (left is ShortConstant){					ShortConstant v;					short res = (short)(((ShortConstant)left).Value ^							    ((ShortConstant)right).Value);										v = new ShortConstant (res, left.Location);					if (result_type == null)						return v;					else						return new EnumConstant (v, result_type);				}				break;			case Binary.Operator.Addition:				bool left_is_string = left is StringConstant;				bool right_is_string = right is StringConstant;				//				// If both sides are strings, then concatenate, if				// one is a string, and the other is not, then defer				// to runtime concatenation				//				wrap_as = null;				if (left_is_string || right_is_string){					if (left_is_string && right_is_string)						return new StringConstant (							((StringConstant) left).Value +

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -