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

📄 constant.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
//// constant.cs: Constants.//// Author://   Miguel de Icaza (miguel@ximian.com)//   Marek Safar (marek.safar@seznam.cz)//// (C) 2001 Ximian, Inc.////namespace Mono.CSharp {	using System;	using System.Reflection.Emit;	/// <summary>	///   Base class for constants and literals.	/// </summary>	public abstract class Constant : Expression {		protected Constant (Location loc)		{			this.loc = loc;		}		/// <remarks>		///   This is different from ToString in that ToString		///   is supposed to be there for debugging purposes,		///   and is not guaranteed to be useful for anything else,		///   AsString() will provide something that can be used		///   for round-tripping C# code.  Maybe it can be used		///   for IL assembly as well.		/// </remarks>		public abstract string AsString ();		override public string ToString ()		{			return this.GetType ().Name + " (" + AsString () + ")";		}		/// <summary>		///  This is used to obtain the actual value of the literal		///  cast into an object.		/// </summary>		public abstract object GetValue ();		public virtual object GetTypedValue ()		{			return GetValue ();		}		/// <summary>		///   Constants are always born in a fully resolved state		/// </summary>		public override Expression DoResolve (EmitContext ec)		{			return this;		}		//		// The various ToXXXX conversion functions are used by the constant		// folding evaluator.   A null value is returned if the conversion is		// not possible.   		//		// Note: not all the patterns for catching `implicit_conv' are the same.		// some implicit conversions can never be performed between two types		// even if the conversion would be lossless (for example short to uint),		// but some conversions are explicitly permitted by the standard provided		// that there will be no loss of information (for example, int to uint).		//		public DoubleConstant ToDouble (Location loc)		{			DoubleConstant c = ConvertToDouble ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.double_type, false);			return c;		}		public FloatConstant ToFloat (Location loc)		{			FloatConstant c = ConvertToFloat ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.float_type, false);			return c;		}		public ULongConstant ToULong (Location loc)		{			ULongConstant c = ConvertToULong ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.uint64_type, false);			return c;		}		public LongConstant ToLong (Location loc)		{			LongConstant c = ConvertToLong ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.int64_type, false);			return c;		}				public UIntConstant ToUInt (Location loc)		{			UIntConstant c = ConvertToUInt ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.uint32_type, false);			return c;		}		public IntConstant ToInt (Location loc)		{			IntConstant c = ConvertToInt ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.int32_type, false);			return c;		}		public DecimalConstant ToDecimal (Location loc)		{			DecimalConstant c = ConvertToDecimal ();			if (c == null)				Error_ValueCannotBeConverted (loc, TypeManager.decimal_type, false);			return c;		}		public virtual Constant ToType (Type type, Location loc)		{			if (Type == type)				return this;			if (type == TypeManager.object_type)				return this;			if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){				Error_ValueCannotBeConverted (loc, type, false);				return null;			}			// Special-case: The 0 literal can be converted to an enum value,			// and ImplicitStandardConversionExists will return true in that case.			if (IsZeroInteger && Type == TypeManager.int32_type && TypeManager.IsEnumType (type)) {				return new EnumConstant (this, type);			}			bool fail;						object constant_value = TypeManager.ChangeType (GetValue (), type, out fail);			if (fail){				Error_ValueCannotBeConverted (loc, type, false);								//				// We should always catch the error before this is ever				// reached, by calling Convert.ImplicitStandardConversionExists				//				throw new Exception (					String.Format ("LookupConstantValue: This should never be reached {0} {1}", Type, type));			}			Constant retval;			if (type == TypeManager.int32_type)				retval = new IntConstant ((int) constant_value, loc);			else if (type == TypeManager.uint32_type)				retval = new UIntConstant ((uint) constant_value, loc);			else if (type == TypeManager.int64_type)				retval = new LongConstant ((long) constant_value, loc);			else if (type == TypeManager.uint64_type)				retval = new ULongConstant ((ulong) constant_value, loc);			else if (type == TypeManager.float_type)				retval = new FloatConstant ((float) constant_value, loc);			else if (type == TypeManager.double_type)				retval = new DoubleConstant ((double) constant_value, loc);			else if (type == TypeManager.string_type)				retval = new StringConstant ((string) constant_value, loc);			else if (type == TypeManager.short_type)				retval = new ShortConstant ((short) constant_value, loc);			else if (type == TypeManager.ushort_type)				retval = new UShortConstant ((ushort) constant_value, loc);			else if (type == TypeManager.sbyte_type)				retval = new SByteConstant ((sbyte) constant_value, loc);			else if (type == TypeManager.byte_type)				retval = new ByteConstant ((byte) constant_value, loc);			else if (type == TypeManager.char_type)				retval = new CharConstant ((char) constant_value, loc);			else if (type == TypeManager.bool_type)				retval = new BoolConstant ((bool) constant_value, loc);			else if (type == TypeManager.decimal_type)				retval = new DecimalConstant ((decimal) constant_value, loc);			else				throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);						return retval;		}		protected void CheckRange (EmitContext ec, ulong value, Type type, ulong max)		{			if (!ec.ConstantCheckState)				return;			if (value > max)				throw new OverflowException ();		}		protected void CheckRange (EmitContext ec, double value, Type type, long min, long max)		{			if (!ec.ConstantCheckState)				return;			if (((value < min) || (value > max)))				throw new OverflowException ();		}		protected void CheckUnsigned (EmitContext ec, long value, Type type)		{			if (!ec.ConstantCheckState)				return;			if (value < 0)				throw new OverflowException ();		}		public abstract Constant Reduce (EmitContext ec, Type target_type);		/// <summary>		///   Attempts to do a compile-time folding of a constant cast.		/// </summary>		public Constant TryReduce (EmitContext ec, Type target_type, Location loc)		{			try {				return  TryReduce (ec, target_type);			}			catch (OverflowException) {				if (ec.ConstantCheckState) {					Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",						this.GetValue (), TypeManager.CSharpName (target_type));				}				return null;			}		}		Constant TryReduce (EmitContext ec, Type target_type)		{			if (Type == target_type)				return this;			if (TypeManager.IsEnumType (target_type)) {				Constant c = TryReduce (ec, TypeManager.EnumToUnderlying (target_type));				if (c == null)					return null;				return new EnumConstant (c, target_type);			}			return Reduce (ec, target_type);		}		public virtual DecimalConstant ConvertToDecimal ()		{			return null;		}				public virtual DoubleConstant ConvertToDouble ()		{			return null;		}		public virtual FloatConstant ConvertToFloat ()		{			return null;		}		public virtual ULongConstant ConvertToULong ()		{			return null;		}		public virtual LongConstant ConvertToLong ()		{			return null;		}		public virtual UIntConstant ConvertToUInt ()		{			return null;		}		public virtual IntConstant ConvertToInt ()		{			return null;		}		public abstract Constant Increment ();				public abstract bool IsDefaultValue {			get;		}		public abstract bool IsNegative {			get;		}		//		// Returns true iff 1) the stack type of this is one of Object, 		// int32, int64 and 2) this == 0 or this == null.		//		public virtual bool IsZeroInteger {			get { return false; }		}	}		public class BoolConstant : Constant {		public readonly bool Value;				public BoolConstant (bool val, Location loc):			base (loc)		{			type = TypeManager.bool_type;			eclass = ExprClass.Value;			Value = val;		}		override public string AsString ()		{			return Value ? "true" : "false";		}		public override object GetValue ()		{			return (object) Value;		}								public override void Emit (EmitContext ec)		{			if (Value)				ec.ig.Emit (OpCodes.Ldc_I4_1);			else				ec.ig.Emit (OpCodes.Ldc_I4_0);		}		public override Constant Increment ()		{			throw new NotSupportedException ();		}			public override bool IsDefaultValue {			get {				return !Value;			}		}		public override bool IsNegative {			get {				return false;			}		}			public override bool IsZeroInteger {			get { return Value == false; }		}		public override Constant Reduce (EmitContext ec, Type target_type)		{			return null;		}	}	public class ByteConstant : Constant {		public readonly byte Value;		public ByteConstant (byte v, Location loc):			base (loc)		{			type = TypeManager.byte_type;			eclass = ExprClass.Value;			Value = v;		}		public override void Emit (EmitContext ec)		{			IntLiteral.EmitInt (ec.ig, Value);		}		public override string AsString ()		{			return Value.ToString ();		}		public override object GetValue ()		{			return Value;		}		public override DoubleConstant ConvertToDouble ()		{			return new DoubleConstant (Value, loc);		}		public override FloatConstant ConvertToFloat ()		{			return new FloatConstant (Value, loc);		}		public override ULongConstant ConvertToULong ()		{			return new ULongConstant (Value, loc);		}		public override LongConstant ConvertToLong ()		{			return new LongConstant (Value, loc);		}		public override UIntConstant ConvertToUInt ()		{			return new UIntConstant (Value, loc);		}		public override IntConstant ConvertToInt ()		{			return new IntConstant (Value, loc);		}		public override Constant Increment ()		{			return new ByteConstant (checked ((byte)(Value + 1)), loc);		}		public override bool IsDefaultValue {			get {				return Value == 0;			}		}		public override bool IsNegative {			get {				return false;			}		}		public override bool IsZeroInteger {			get { return Value == 0; }		}		public override Constant Reduce (EmitContext ec, Type target_type)		{			if (target_type == TypeManager.sbyte_type) {				CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);				return new SByteConstant ((sbyte) Value, Location);			}			if (target_type == TypeManager.short_type)				return new ShortConstant ((short) Value, Location);			if (target_type == TypeManager.ushort_type)				return new UShortConstant ((ushort) Value, Location);			if (target_type == TypeManager.int32_type)				return new IntConstant ((int) Value, Location);			if (target_type == TypeManager.uint32_type)				return new UIntConstant ((uint) Value, Location);			if (target_type == TypeManager.int64_type)				return new LongConstant ((long) Value, Location);			if (target_type == TypeManager.uint64_type)				return new ULongConstant ((ulong) Value, Location);			if (target_type == TypeManager.float_type)				return new FloatConstant ((float) Value, Location);			if (target_type == TypeManager.double_type)				return new DoubleConstant ((double) Value, Location);			if (target_type == TypeManager.char_type)				return new CharConstant ((char) Value, Location);			if (target_type == TypeManager.decimal_type)				return new DecimalConstant ((decimal) Value, Location);			return null;		}	}	public class CharConstant : Constant {		public readonly char Value;		public CharConstant (char v, Location loc):			base (loc)		{			type = TypeManager.char_type;			eclass = ExprClass.Value;			Value = v;		}		public override void Emit (EmitContext ec)		{			IntLiteral.EmitInt (ec.ig, Value);		}		static public string descape (char c)		{			switch (c){			case '\a':				return "\\a"; 			case '\b':				return "\\b"; 			case '\n':				return "\\n"; 			case '\t':				return "\\t"; 			case '\v':				return "\\v"; 			case '\r':				return "\\r"; 			case '\\':				return "\\\\";			case '\f':				return "\\f"; 			case '\0':				return "\\0"; 			case '"':				return "\\\""; 			case '\'':				return "\\\'"; 			}			return c.ToString ();		}		public override string AsString ()		{			return "\"" + descape (Value) + "\"";		}		public override object GetValue ()		{			return Value;		}		public override DoubleConstant ConvertToDouble ()		{			return new DoubleConstant (Value, loc);		}		public override FloatConstant ConvertToFloat ()		{			return new FloatConstant (Value, loc);		}		public override ULongConstant ConvertToULong ()		{			return new ULongConstant (Value, loc);		}		public override LongConstant ConvertToLong ()		{			return new LongConstant (Value, loc);		}		public override UIntConstant ConvertToUInt ()		{			return new UIntConstant (Value, loc);		}		public override IntConstant ConvertToInt ()		{			return new IntConstant (Value, loc);		}		public override Constant Increment ()		{			return new CharConstant (checked ((char)(Value + 1)), loc);		}				public override bool IsDefaultValue {			get {				return Value == 0;			}		}		public override bool IsNegative {			get {				return false;			}		}		public override bool IsZeroInteger {			get { return Value == '\0'; }		}		public override Constant Reduce (EmitContext ec, Type target_type)		{			if (target_type == TypeManager.byte_type) {				CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue);				return new ByteConstant ((byte) Value, Location);			}			if (target_type == TypeManager.sbyte_type) {				CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);				return new SByteConstant ((sbyte) Value, Location);			}			if (target_type == TypeManager.short_type) {				CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);				return new ShortConstant ((short) Value, Location);			}			if (target_type == TypeManager.int32_type)				return new IntConstant ((int) Value, Location);			if (target_type == TypeManager.uint32_type)				return new UIntConstant ((uint) Value, Location);			if (target_type == TypeManager.int64_type)				return new LongConstant ((long) Value, Location);			if (target_type == TypeManager.uint64_type)				return new ULongConstant ((ulong) Value, Location);			if (target_type == TypeManager.float_type)				return new FloatConstant ((float) Value, Location);			if (target_type == TypeManager.double_type)				return new DoubleConstant ((double) Value, Location);			if (target_type == TypeManager.decimal_type)				return new DecimalConstant ((decimal) Value, Location);			return null;		}	}	public class SByteConstant : Constant {		public readonly sbyte Value;		public SByteConstant (sbyte v, Location loc):			base (loc)

⌨️ 快捷键说明

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