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

📄 expression.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
			} else if (t == TypeManager.short_type){				if (ec.CheckState)					ig.Emit (OpCodes.Conv_Ovf_I2);				else					ig.Emit (OpCodes.Conv_I2);			} else if (t == TypeManager.ushort_type || t == TypeManager.char_type){				if (ec.CheckState)					ig.Emit (OpCodes.Conv_Ovf_U2);				else					ig.Emit (OpCodes.Conv_U2);			}					}				void EmitCode (EmitContext ec, bool is_expr)		{			recurse = true;			this.is_expr = is_expr;			((IAssignMethod) expr).EmitAssign (ec, this, is_expr && (mode == Mode.PreIncrement || mode == Mode.PreDecrement), true);		}				public override void Emit (EmitContext ec)		{			//			// We use recurse to allow ourselfs to be the source			// of an assignment. This little hack prevents us from			// having to allocate another expression			//			if (recurse) {				((IAssignMethod) expr).Emit (ec, is_expr && (mode == Mode.PostIncrement  || mode == Mode.PostDecrement));				if (method == null)					LoadOneAndEmitOp (ec, expr.Type);				else					ec.ig.Emit (OpCodes.Call, method.Method);				recurse = false;				return;			}						EmitCode (ec, true);		}				public override void EmitStatement (EmitContext ec)		{			EmitCode (ec, false);		}	}	/// <summary>	///   Base class for the `Is' and `As' classes. 	/// </summary>	///	/// <remarks>	///   FIXME: Split this in two, and we get to save the `Operator' Oper	///   size. 	/// </remarks>	public abstract class Probe : Expression {		public Expression ProbeType;		protected Expression expr;		protected Type probe_type;				public Probe (Expression expr, Expression probe_type, Location l)		{			ProbeType = probe_type;			loc = l;			this.expr = expr;		}		public Expression Expr {			get {				return expr;			}		}		public override Expression DoResolve (EmitContext ec)		{			TypeExpr texpr = ProbeType.ResolveAsTypeTerminal (ec, false);			if (texpr == null)				return null;			probe_type = texpr.ResolveType (ec);			expr = expr.Resolve (ec);			if (expr == null)				return null;						if (expr.Type.IsPointer) {				Report.Error (244, loc, "\"is\" or \"as\" are not valid on pointer types");				return null;			}			return this;		}	}	/// <summary>	///   Implementation of the `is' operator.	/// </summary>	public class Is : Probe {		public Is (Expression expr, Expression probe_type, Location l)			: base (expr, probe_type, l)		{		}		enum Action {			AlwaysTrue, AlwaysNull, AlwaysFalse, LeaveOnStack, Probe		}		Action action;				public override void Emit (EmitContext ec)		{			ILGenerator ig = ec.ig;			expr.Emit (ec);			switch (action){			case Action.AlwaysFalse:				ig.Emit (OpCodes.Pop);				IntConstant.EmitInt (ig, 0);				return;			case Action.AlwaysTrue:				ig.Emit (OpCodes.Pop);				IntConstant.EmitInt (ig, 1);				return;			case Action.LeaveOnStack:				// the `e != null' rule.				ig.Emit (OpCodes.Ldnull);				ig.Emit (OpCodes.Ceq);				ig.Emit (OpCodes.Ldc_I4_0);				ig.Emit (OpCodes.Ceq);				return;			case Action.Probe:				ig.Emit (OpCodes.Isinst, probe_type);				ig.Emit (OpCodes.Ldnull);				ig.Emit (OpCodes.Cgt_Un);				return;			}			throw new Exception ("never reached");		}				public override void EmitBranchable (EmitContext ec, Label target, bool onTrue)		{			ILGenerator ig = ec.ig;			switch (action){			case Action.AlwaysFalse:				if (! onTrue)					ig.Emit (OpCodes.Br, target);								return;			case Action.AlwaysTrue:				if (onTrue)					ig.Emit (OpCodes.Br, target);								return;			case Action.LeaveOnStack:				// the `e != null' rule.				expr.Emit (ec);				ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);				return;			case Action.Probe:				expr.Emit (ec);				ig.Emit (OpCodes.Isinst, probe_type);				ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);				return;			}			throw new Exception ("never reached");		}		public override Expression DoResolve (EmitContext ec)		{			Expression e = base.DoResolve (ec);			if ((e == null) || (expr == null))				return null;			Type etype = expr.Type;			bool warning_always_matches = false;			bool warning_never_matches = false;			type = TypeManager.bool_type;			eclass = ExprClass.Value;			//			// First case, if at compile time, there is an implicit conversion			// then e != null (objects) or true (value types)			//			e = Convert.ImplicitConversionStandard (ec, expr, probe_type, loc);			if (e != null && !(e is NullCast)){				expr = e;				if (etype.IsValueType)					action = Action.AlwaysTrue;				else					action = Action.LeaveOnStack;				warning_always_matches = true;			} else if (Convert.ExplicitReferenceConversionExists (etype, probe_type)){				//				// Second case: explicit reference convresion				//				if (expr is NullLiteral)					action = Action.AlwaysFalse;				else					action = Action.Probe;			} else {				action = Action.AlwaysFalse;				warning_never_matches = true;			}						if (warning_always_matches)				Report.Warning (183, 1, loc, "The given expression is always of the provided (`{0}') type", TypeManager.CSharpName (probe_type));			else if (warning_never_matches){				if (!(probe_type.IsInterface || expr.Type.IsInterface))					Report.Warning (184, 1, loc, "The given expression is never of the provided (`{0}') type", TypeManager.CSharpName (probe_type));			}			return this;		}					}	/// <summary>	///   Implementation of the `as' operator.	/// </summary>	public class As : Probe {		public As (Expression expr, Expression probe_type, Location l)			: base (expr, probe_type, l)		{		}		bool do_isinst = false;		Expression resolved_type;				public override void Emit (EmitContext ec)		{			ILGenerator ig = ec.ig;			expr.Emit (ec);			if (do_isinst)				ig.Emit (OpCodes.Isinst, probe_type);		}		static void Error_CannotConvertType (Type source, Type target, Location loc)		{			Report.Error (39, loc, "Cannot convert type `{0}' to `{1}' via a built-in conversion",				TypeManager.CSharpName (source),				TypeManager.CSharpName (target));		}				public override Expression DoResolve (EmitContext ec)		{			if (resolved_type == null) {				resolved_type = base.DoResolve (ec);				if (resolved_type == null)					return null;			}			type = probe_type;			eclass = ExprClass.Value;			Type etype = expr.Type;			if (TypeManager.IsValueType (probe_type)){				Report.Error (77, loc, "The as operator must be used with a reference type (`" +					      TypeManager.CSharpName (probe_type) + "' is a value type)");				return null;						}						Expression e = Convert.ImplicitConversion (ec, expr, probe_type, loc);			if (e != null){				expr = e;				do_isinst = false;				return this;			}			if (Convert.ExplicitReferenceConversionExists (etype, probe_type)){				do_isinst = true;				return this;			}			Error_CannotConvertType (etype, probe_type, loc);			return null;		}					}		/// <summary>	///   This represents a typecast in the source language.	///	///   FIXME: Cast expressions have an unusual set of parsing	///   rules, we need to figure those out.	/// </summary>	public class Cast : Expression {		Expression target_type;		Expression expr;					public Cast (Expression cast_type, Expression expr)			: this (cast_type, expr, cast_type.Location)		{		}		public Cast (Expression cast_type, Expression expr, Location loc)		{			this.target_type = cast_type;			this.expr = expr;			this.loc = loc;		}		public Expression TargetType {			get {				return target_type;			}		}		public Expression Expr {			get {				return expr;			}			set {				expr = value;			}		}				public override Expression DoResolveLValue (EmitContext ec, Expression right_side)		{			expr = expr.DoResolveLValue (ec, right_side);			if (expr == null)				return null;			return ResolveRest (ec);		}		public override Expression DoResolve (EmitContext ec)		{			expr = expr.Resolve (ec);			if (expr == null)				return null;			return ResolveRest (ec);		}		Expression ResolveRest (EmitContext ec)		{			TypeExpr target = target_type.ResolveAsTypeTerminal (ec, false);			if (target == null)				return null;			type = target.ResolveType (ec);			if (type.IsAbstract && type.IsSealed) {				Report.Error (716, loc, "Cannot convert to static type `{0}'", TypeManager.CSharpName (type));				return null;			}			eclass = ExprClass.Value;			Constant c = expr as Constant;			if (c != null) {				c = c.TryReduce (ec, type, loc);				if (c != null)					return c;			}			if (type.IsPointer && !ec.InUnsafe) {				UnsafeError (loc);				return null;			}			expr = Convert.ExplicitConversion (ec, expr, type, loc);			return expr;		}				public override void Emit (EmitContext ec)		{			//			// This one will never happen			//			throw new Exception ("Should not happen");		}	}	/// <summary>	///   Binary operators	/// </summary>	public class Binary : Expression {		public enum Operator : byte {			Multiply, Division, Modulus,			Addition, Subtraction,			LeftShift, RightShift,			LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, 			Equality, Inequality,			BitwiseAnd,			ExclusiveOr,			BitwiseOr,			LogicalAnd,			LogicalOr,			TOP		}		Operator oper;		Expression left, right;		// This must be kept in sync with Operator!!!		public static readonly string [] oper_names;				static Binary ()		{			oper_names = new string [(int) Operator.TOP];			oper_names [(int) Operator.Multiply] = "op_Multiply";			oper_names [(int) Operator.Division] = "op_Division";			oper_names [(int) Operator.Modulus] = "op_Modulus";			oper_names [(int) Operator.Addition] = "op_Addition";			oper_names [(int) Operator.Subtraction] = "op_Subtraction";			oper_names [(int) Operator.LeftShift] = "op_LeftShift";			oper_names [(int) Operator.RightShift] = "op_RightShift";			oper_names [(int) Operator.LessThan] = "op_LessThan";			oper_names [(int) Operator.GreaterThan] = "op_GreaterThan";			oper_names [(int) Operator.LessThanOrEqual] = "op_LessThanOrEqual";			oper_names [(int) Operator.GreaterThanOrEqual] = "op_GreaterThanOrEqual";			oper_names [(int) Operator.Equality] = "op_Equality";			oper_names [(int) Operator.Inequality] = "op_Inequality";			oper_names [(int) Operator.BitwiseAnd] = "op_BitwiseAnd";			oper_names [(int) Operator.BitwiseOr] = "op_BitwiseOr";			oper_names [(int) Operator.ExclusiveOr] = "op_ExclusiveOr";			oper_names [(int) Operator.LogicalOr] = "op_LogicalOr";			oper_names [(int) Operator.LogicalAnd] = "op_LogicalAnd";		}		public Binary (Operator oper, Expression left, Expression right)		{			this.oper = oper;			this.left = left;			this.right = right;			this.loc = left.Location;		}		public Operator Oper {			get {				return oper;			}			set {				oper = value;			}		}				public Expression Left {			get {				return left;			}			set {				left = value;			}		}		public Expression Right {			get {				return right;			}			set {				right = value;			}		}		/// <summary>		///   Returns a stringified representation of the Operator		/// </summary>		public static string OperName (Operator oper)		{			switch (oper){			case Operator.Multiply:				return "*";			case Operator.Division:				return "/";			case Operator.Modulus:				return "%";			case Operator.Addition:				return "+";			case Operator.Subtraction:				return "-";			case Operator.LeftShift:				return "<<";			case Operator.RightShift:				return ">>";			case Operator.LessThan:				return "<";			case Operator.GreaterThan:

⌨️ 快捷键说明

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