/// <summary> /// Converts source values to a value for the binding target. /// </summary> /// <param name="values">The array of values that the source bindings produces.</param> /// <param name="targetType">The type of the binding target property.</param> /// <param name="parameter">The converter parameter to use.</param> /// <param name="culture">The culture to use in the converter.</param> /// <returns>A converted value.</returns> public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { try { // First time around we parse the evaluation input if (_eval == null) { _eval = new Eval(_language); _eval.ResolveIdentifier += new EventHandler <ResolveIdentifierEventArgs>(OnResolveIdentifier); _eval.Parse(_expression); } // Every time we evaluate we could throw an exception. This is because each time around the // bindings can provide values of different types. So first time round the binding has an // integer and so works correctly but next time it could provide a string and cause a type // error in the evaluation. EvalResult ret = _eval.Evaluate(values); // Null means we have no result to provide if (ret == null) { return(DependencyProperty.UnsetValue); } else { // If the return type is different to the target type if (ret.Value.GetType() != targetType) { // If possible we perform an implicit conversion to the target TypeCode targetTypeCode = Type.GetTypeCode(targetType); if (ImplicitConverter.CanConvertTo(targetTypeCode, ret.Value, _language)) { ret.Value = ImplicitConverter.ConvertTo(targetTypeCode, ret.Value, _language); } else { // Use type converters to attempt an explicit conversion ret.Value = ConvertUsingConverter(ret, targetType); } } return(ret.Value); } } catch (ParseException pe) { Console.WriteLine("EvalBinding Parsing Exception : {0} : Index '{1}'", pe.Message, pe.Index); return(DependencyProperty.UnsetValue); } catch (Exception e) { Console.WriteLine("EvalBinding Evaluation Exception : {0} : Eval '{1}'", e.Message, _eval.ToString()); return(DependencyProperty.UnsetValue); } }
private bool IsValidCast(Type sourceType, Type destType) { if (object.ReferenceEquals(sourceType, destType)) { // Identity cast always succeeds return(true); } else if (destType.IsAssignableFrom(sourceType) == true) { // Cast is already implicitly valid return(true); } else if (ImplicitConverter.EmitImplicitConvert(sourceType, destType, null) == true) { // Cast is already implicitly valid return(true); } else if (IsCastableNumericType(sourceType) & IsCastableNumericType(destType)) { // Explicit cast of numeric types always succeeds return(true); } else if (sourceType.IsEnum == true | destType.IsEnum == true) { return(this.IsValidExplicitEnumCast(sourceType, destType)); } else if ((this.GetExplictOverloadedOperator(sourceType, destType) != null)) { // Overloaded explict cast exists return(true); } if (sourceType.IsValueType == true) { // If we get here then the cast always fails since we are either casting one value type to another // or a value type to an invalid reference type return(false); } else { if (destType.IsValueType == true) { // Reference type to value type // Can only succeed if the reference type is a base of the value type or // it is one of the interfaces the value type implements Type[] interfaces = destType.GetInterfaces(); return(IsBaseType(destType, sourceType) == true | System.Array.IndexOf(interfaces, sourceType) != -1); } else { // Reference type to reference type return(this.IsValidExplicitReferenceCast(sourceType, destType)); } } }
private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm) { Label falseLabel = bm.FindLabel("falseLabel"); Label endLabel = bm.FindLabel("endLabel"); // Emit the condition _myCondition.Emit(ilg, services); // On false go to the false operand if (ilg.IsTemp == true) { bm.AddBranch(ilg, falseLabel); ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else if (bm.IsLongBranch(ilg, falseLabel) == false) { ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else { ilg.Emit(OpCodes.Brfalse, falseLabel); } // Emit the true operand _myWhenTrue.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(_myWhenTrue.ResultType, _myResultType, ilg); // Jump to end if (ilg.IsTemp == true) { bm.AddBranch(ilg, endLabel); ilg.Emit(OpCodes.Br_S, endLabel); } else if (bm.IsLongBranch(ilg, endLabel) == false) { ilg.Emit(OpCodes.Br_S, endLabel); } else { ilg.Emit(OpCodes.Br, endLabel); } bm.MarkLabel(ilg, falseLabel); ilg.MarkLabel(falseLabel); // Emit the false operand _myWhenFalse.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(_myWhenFalse.ResultType, _myResultType, ilg); // Fall through to end bm.MarkLabel(ilg, endLabel); ilg.MarkLabel(endLabel); }
private void EmitConditional(YaleIlGenerator ilg, ExpressionContext context, BranchManager branchManager) { var falseLabel = branchManager.FindLabel("falseLabel"); var endLabel = branchManager.FindLabel("endLabel"); // Emit the condition condition.Emit(ilg, context); // On false go to the false operand if (ilg.IsTemp) { branchManager.AddBranch(ilg, falseLabel); ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else if (branchManager.IsLongBranch(ilg, falseLabel) == false) { ilg.Emit(OpCodes.Brfalse_S, falseLabel); } else { ilg.Emit(OpCodes.Brfalse, falseLabel); } // Emit the true operand whenTrue.Emit(ilg, context); ImplicitConverter.EmitImplicitConvert(whenTrue.ResultType, resultType, ilg); // Jump to end if (ilg.IsTemp) { branchManager.AddBranch(ilg, endLabel); ilg.Emit(OpCodes.Br_S, endLabel); } else if (branchManager.IsLongBranch(ilg, endLabel) == false) { ilg.Emit(OpCodes.Br_S, endLabel); } else { ilg.Emit(OpCodes.Br, endLabel); } branchManager.MarkLabel(ilg, falseLabel); ilg.MarkLabel(falseLabel); // Emit the false operand whenFalse.Emit(ilg, context); ImplicitConverter.EmitImplicitConvert(whenFalse.ResultType, resultType, ilg); // Fall through to end branchManager.MarkLabel(ilg, endLabel); ilg.MarkLabel(endLabel); }
private void SetupArrayIndexer() { _myIndexerElement = _myIndexerElements[0]; if (_myIndexerElements.Count > 1) { base.ThrowCompileException(CompileErrorResourceKeys.MultiArrayIndexNotSupported, CompileExceptionReason.TypeMismatch); } else if (ImplicitConverter.EmitImplicitConvert(_myIndexerElement.ResultType, typeof(Int32), null) == false) { base.ThrowCompileException(CompileErrorResourceKeys.ArrayIndexersMustBeOfType, CompileExceptionReason.TypeMismatch, typeof(Int32).Name); } }
private void EmitCast(YaleIlGenerator ilg, Type sourceType, Type destType, ExpressionContext context) { var explicitOperator = GetExplictOverloadedOperator(sourceType, destType); if (ReferenceEquals(sourceType, destType)) { // Identity cast; do nothing return; } if (explicitOperator != null) { ilg.Emit(OpCodes.Call, explicitOperator); } else if (sourceType.IsEnum | destType.IsEnum) { EmitEnumCast(ilg, sourceType, destType, context); } else if (ImplicitConverter.EmitImplicitConvert(sourceType, destType, ilg)) { // Implicit numeric cast; do nothing return; } else if (IsCastableNumericType(sourceType) & IsCastableNumericType(destType)) { // Explicit numeric cast EmitExplicitNumericCast(ilg, sourceType, destType, context); } else if (sourceType.IsValueType) { Debug.Assert(destType.IsValueType == false, "expecting reference type"); ilg.Emit(OpCodes.Box, sourceType); } else { if (destType.IsValueType) { // Reference type to value type ilg.Emit(OpCodes.Unbox_Any, destType); } else { // Reference type to reference type if (destType.IsAssignableFrom(sourceType) == false) { // Only emit cast if it is an explicit cast ilg.Emit(OpCodes.Castclass, destType); } } } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { _myChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(_myChild.ResultType, _myResultType, ilg); ExpressionOptions options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions)); if (options.IsGeneric == false) { ImplicitConverter.EmitImplicitConvert(_myResultType, typeof(object), ilg); } ilg.Emit(OpCodes.Ret); }
/// <summary> /// Emit the arguments to a regular method call /// </summary> private void EmitRegularFunctionInternal(ParameterInfo[] parameters, BaseExpressionElement[] elements, YaleIlGenerator ilg, ExpressionContext context) { Debug.Assert(parameters.Length == elements.Length, "argument count mismatch"); // Emit each element and any required conversions to the actual parameter type for (var i = 0; i <= parameters.Length - 1; i++) { var element = elements[i]; var pi = parameters[i]; element.Emit(ilg, context); var success = ImplicitConverter.EmitImplicitConvert(element.ResultType, pi.ParameterType, ilg); Debug.Assert(success, "conversion failed"); } }
private void EmitCast(FleeILGenerator ilg, Type sourceType, Type destType, IServiceProvider services) { MethodInfo explicitOperator = this.GetExplictOverloadedOperator(sourceType, destType); if (object.ReferenceEquals(sourceType, destType)) { // Identity cast; do nothing return; } else if ((explicitOperator != null)) { ilg.Emit(OpCodes.Call, explicitOperator); } else if (sourceType.IsEnum == true | destType.IsEnum == true) { this.EmitEnumCast(ilg, sourceType, destType, services); } else if (ImplicitConverter.EmitImplicitConvert(sourceType, destType, ilg) == true) { // Implicit numeric cast; do nothing return; } else if (IsCastableNumericType(sourceType) & IsCastableNumericType(destType)) { // Explicit numeric cast EmitExplicitNumericCast(ilg, sourceType, destType, services); } else if (sourceType.IsValueType == true) { Debug.Assert(destType.IsValueType == false, "expecting reference type"); ilg.Emit(OpCodes.Box, sourceType); } else { if (destType.IsValueType == true) { // Reference type to value type ilg.Emit(OpCodes.Unbox_Any, destType); } else { // Reference type to reference type if (destType.IsAssignableFrom(sourceType) == false) { // Only emit cast if it is an explicit cast ilg.Emit(OpCodes.Castclass, destType); } } } }
//Entry point of IL Creation public override void Emit(YaleIlGenerator ilGenerator, ExpressionContext context) { _child.Emit(ilGenerator, context); ImplicitConverter.EmitImplicitConvert(_child.ResultType, _resultType, ilGenerator); //Todo: Verify if this convert stuff works if ("isGeneric".Equals("false")) { ImplicitConverter.EmitImplicitConvert(_resultType, typeof(object), ilGenerator); } ilGenerator.Emit(OpCodes.Ret); }
/// <summary> /// Emit the arguments to a regular method call /// </summary> /// <param name="parameters"></param> /// <param name="elements"></param> /// <param name="ilg"></param> /// <param name="services"></param> private void EmitRegularFunctionInternal(ParameterInfo[] parameters, ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services) { Debug.Assert(parameters.Length == elements.Length, "argument count mismatch"); // Emit each element and any required conversions to the actual parameter type for (int i = 0; i <= parameters.Length - 1; i++) { ExpressionElement element = elements[i]; ParameterInfo pi = parameters[i]; element.Emit(ilg, services); bool success = ImplicitConverter.EmitImplicitConvert(element.ResultType, pi.ParameterType, ilg); Debug.Assert(success, "conversion failed"); } }
private void EmitCollectionIn(YaleIlGenerator ilg, ExpressionContext context) { // Get the contains method var methodInfo = GetCollectionContainsMethod(); var firstParameter = methodInfo.GetParameters()[0]; // Load the collection targetCollectionElement.Emit(ilg, context); // Load the argument operand.Emit(ilg, context); // Do an implicit convert if necessary ImplicitConverter.EmitImplicitConvert(operand.ResultType, firstParameter.ParameterType, ilg); // Call the contains method ilg.Emit(OpCodes.Callvirt, methodInfo); }
private void EmitCollectionIn(FleeILGenerator ilg, IServiceProvider services) { // Get the contains method MethodInfo mi = this.GetCollectionContainsMethod(); ParameterInfo p1 = mi.GetParameters()[0]; // Load the collection MyTargetCollectionElement.Emit(ilg, services); // Load the argument MyOperand.Emit(ilg, services); // Do an implicit convert if necessary ImplicitConverter.EmitImplicitConvert(MyOperand.ResultType, p1.ParameterType, ilg); // Call the contains method ilg.Emit(OpCodes.Callvirt, mi); }
public override void Emit(YaleIlGenerator ilGenerator, ExpressionContext context) { var resultType = ResultType; if (ReferenceEquals(resultType, typeof(bool))) { DoEmitLogical(ilGenerator, context); } else { LeftChild.Emit(ilGenerator, context); ImplicitConverter.EmitImplicitConvert(LeftChild.ResultType, resultType, ilGenerator); RightChild.Emit(ilGenerator, context); ImplicitConverter.EmitImplicitConvert(RightChild.ResultType, resultType, ilGenerator); EmitBitwiseOperation(ilGenerator, myOperation); } }
private void EmitArrayLoad(FleeILGenerator ilg, IServiceProvider services) { _myIndexerElement.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(_myIndexerElement.ResultType, typeof(Int32), ilg); Type elementType = this.ResultType; if (elementType.IsValueType == false) { // Simple reference load ilg.Emit(OpCodes.Ldelem_Ref); } else { this.EmitValueTypeArrayLoad(ilg, elementType); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; if (object.ReferenceEquals(resultType, typeof(bool))) { this.DoEmitLogical(ilg, services); } else { MyLeftChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg); MyRightChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg); EmitBitwiseOperation(ilg, _myOperation); } }
private void EmitArrayLoad(YaleIlGenerator ilg, ExpressionContext context) { _indexerElement.Emit(ilg, context); ImplicitConverter.EmitImplicitConvert(_indexerElement.ResultType, typeof(Int32), ilg); var elementType = ResultType; if (elementType.IsValueType == false) { // Simple reference load ilg.Emit(OpCodes.Ldelem_Ref); } else { EmitValueTypeArrayLoad(ilg, elementType); } }
public override void Emit(YaleIlGenerator ilGenerator, ExpressionContext context) { var resultType = ResultType; MyChild.Emit(ilGenerator, context); ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, resultType, ilGenerator); var methodInfo = Utility.GetSimpleOverloadedOperator(UnaryNegation, resultType, resultType); if (methodInfo == null) { ilGenerator.Emit(OpCodes.Neg); } else { ilGenerator.Emit(OpCodes.Call, methodInfo); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type resultType = this.ResultType; MyChild.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, resultType, ilg); MethodInfo mi = Utility.GetSimpleOverloadedOperator("UnaryNegation", resultType, null); if (mi == null) { ilg.Emit(OpCodes.Neg); } else { ilg.Emit(OpCodes.Call, mi); } }
protected override Type GetResultType(Type leftType, Type rightType) { var binaryResultType = ImplicitConverter.GetBinaryResultType(leftType, rightType); var overloadedOperator = GetOverloadedCompareOperator(); var isEqualityOp = IsOpTypeEqualOrNotEqual(operation); // Use our string equality instead of overloaded operator if (ReferenceEquals(leftType, typeof(string)) & ReferenceEquals(rightType, typeof(string)) & isEqualityOp) { // String equality return(typeof(bool)); } if (overloadedOperator != null) { return(overloadedOperator.ReturnType); } if (binaryResultType != null) { // Comparison of numeric operands return(typeof(bool)); } if (ReferenceEquals(leftType, typeof(bool)) & ReferenceEquals(rightType, typeof(bool)) & isEqualityOp) { // Boolean equality return(typeof(bool)); } if (AreBothChildrenReferenceTypes() & isEqualityOp) { // Comparison of reference types return(typeof(bool)); } if (AreBothChildrenSameEnum()) { return(typeof(bool)); } // Invalid operands return(null); }
internal override Item GetItem(IServiceProvider services) { Type binaryResultType = ImplicitConverter.GetBinaryResultType(MyLeftChild.ResultType, MyRightChild.ResultType); MethodInfo overloadedOperator = this.GetOverloadedCompareOperator(); if (this.AreBothChildrenOfType(typeof(string))) { // String equality return(GetItemStringEquality()); } else if ((overloadedOperator != null)) { //base.EmitOverloadedOperatorCall(overloadedOperator, ilg, services); return(base.GetItemOverloadedOperatorCall(overloadedOperator, services)); } else if ((binaryResultType != null)) { // Emit a compare of numeric operands //EmitChildWithConvert(MyLeftChild, binaryResultType, ilg, services); //EmitChildWithConvert(MyRightChild, binaryResultType, ilg, services); //EmitCompareOperation(ilg, _myOperation); } else if (this.AreBothChildrenOfType(typeof(bool))) { // Boolean equality return(GetItemBoolEquality()); } else if (this.AreBothChildrenReferenceTypes() == true) { // Reference equality //this.EmitRegular(ilg, services); } else if (MyLeftChild.ResultType.IsEnum == true & MyRightChild.ResultType.IsEnum == true) { //this.EmitRegular(ilg, services); } else { Debug.Fail("unknown operand types"); } return(base.GetItem(services)); }
private void ResolveForCollectionSearch() { // Try to find a collection type targetCollectionType = GetTargetCollectionType(); if (targetCollectionType == null) { throw CreateCompileException(CompileErrors.SearchArgIsNotKnownCollectionType, CompileExceptionReason.TypeMismatch, targetCollectionElement.ResultType.Name); } // Validate that the operand type is compatible with the collection var methodInfo = GetCollectionContainsMethod(); var firstParameter = methodInfo.GetParameters()[0]; if (ImplicitConverter.EmitImplicitConvert(operand.ResultType, firstParameter.ParameterType, null) == false) { throw CreateCompileException(CompileErrors.OperandNotConvertibleToCollectionType, CompileExceptionReason.TypeMismatch, operand.ResultType.Name, firstParameter.ParameterType.Name); } }
/// <summary> /// Emit the arguments to a regular method call /// </summary> /// <param name="parameters"></param> /// <param name="elements"></param> /// <param name="ilg"></param> /// <param name="services"></param> private void EmitExtensionFunctionInternal(ParameterInfo[] parameters, ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services) { Debug.Assert(parameters.Length == elements.Length + 1, "argument count mismatch"); if (MyPrevious == null) { this.EmitLoadOwner(ilg); } // Emit each element and any required conversions to the actual parameter type for (int i = 0; i < parameters.Length - 1; i++) { var element = elements[i]; var pi = parameters[i + 1]; element.Emit(ilg, services); bool success = ImplicitConverter.EmitImplicitConvert(element.ResultType, pi.ParameterType, ilg); Debug.Assert(success, "conversion failed"); } }
private void ResolveForCollectionSearch() { // Try to find a collection type MyTargetCollectionType = this.GetTargetCollectionType(); if (MyTargetCollectionType == null) { base.ThrowCompileException(CompileErrorResourceKeys.SearchArgIsNotKnownCollectionType, CompileExceptionReason.TypeMismatch, MyTargetCollectionElement.ResultType.Name); } // Validate that the operand type is compatible with the collection MethodInfo mi = this.GetCollectionContainsMethod(); ParameterInfo p1 = mi.GetParameters()[0]; if (ImplicitConverter.EmitImplicitConvert(MyOperand.ResultType, p1.ParameterType, null) == false) { base.ThrowCompileException(CompileErrorResourceKeys.OperandNotConvertibleToCollectionType, CompileExceptionReason.TypeMismatch, MyOperand.ResultType.Name, p1.ParameterType.Name); } }
public override void Emit(YaleIlGenerator ilGenerator, ExpressionContext context) { var binaryResultType = ImplicitConverter.GetBinaryResultType(LeftChild.ResultType, RightChild.ResultType); var overloadedOperator = GetOverloadedCompareOperator(); if (AreBothChildrenOfType(typeof(string))) { // String equality LeftChild.Emit(ilGenerator, context); RightChild.Emit(ilGenerator, context); EmitStringEquality(ilGenerator, operation, context); } else if (overloadedOperator != null) { EmitOverloadedOperatorCall(overloadedOperator, ilGenerator, context); } else if (binaryResultType != null) { // Emit a compare of numeric operands EmitChildWithConvert(LeftChild, binaryResultType, ilGenerator, context); EmitChildWithConvert(RightChild, binaryResultType, ilGenerator, context); EmitCompareOperation(ilGenerator, operation); } else if (AreBothChildrenOfType(typeof(bool))) { // Boolean equality EmitRegular(ilGenerator, context); } else if (AreBothChildrenReferenceTypes()) { // Reference equality EmitRegular(ilGenerator, context); } else if (LeftChild.ResultType.IsEnum & RightChild.ResultType.IsEnum) { EmitRegular(ilGenerator, context); } else { Debug.Fail("unknown operand types"); } }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { Type binaryResultType = ImplicitConverter.GetBinaryResultType(MyLeftChild.ResultType, MyRightChild.ResultType); MethodInfo overloadedOperator = this.GetOverloadedCompareOperator(); if (this.AreBothChildrenOfType(typeof(string))) { // String equality MyLeftChild.Emit(ilg, services); MyRightChild.Emit(ilg, services); EmitStringEquality(ilg, _myOperation, services); } else if ((overloadedOperator != null)) { base.EmitOverloadedOperatorCall(overloadedOperator, ilg, services); } else if ((binaryResultType != null)) { // Emit a compare of numeric operands EmitChildWithConvert(MyLeftChild, binaryResultType, ilg, services); EmitChildWithConvert(MyRightChild, binaryResultType, ilg, services); EmitCompareOperation(ilg, _myOperation); } else if (this.AreBothChildrenOfType(typeof(bool))) { // Boolean equality this.EmitRegular(ilg, services); } else if (this.AreBothChildrenReferenceTypes() == true) { // Reference equality this.EmitRegular(ilg, services); } else if (MyLeftChild.ResultType.IsEnum == true & MyRightChild.ResultType.IsEnum == true) { this.EmitRegular(ilg, services); } else { Debug.Fail("unknown operand types"); } }
protected override System.Type GetResultType(System.Type leftType, System.Type rightType) { Type binaryResultType = ImplicitConverter.GetBinaryResultType(leftType, rightType); MethodInfo overloadedOperator = this.GetOverloadedCompareOperator(); bool isEqualityOp = IsOpTypeEqualOrNotEqual(_myOperation); // Use our string equality instead of overloaded operator if (object.ReferenceEquals(leftType, typeof(string)) & object.ReferenceEquals(rightType, typeof(string)) & isEqualityOp == true) { // String equality return(typeof(bool)); } else if ((overloadedOperator != null)) { return(overloadedOperator.ReturnType); } else if ((binaryResultType != null)) { // Comparison of numeric operands return(typeof(bool)); } else if (object.ReferenceEquals(leftType, typeof(bool)) & object.ReferenceEquals(rightType, typeof(bool)) & isEqualityOp == true) { // Boolean equality return(typeof(bool)); } else if (this.AreBothChildrenReferenceTypes() == true & isEqualityOp == true) { // Comparison of reference types return(typeof(bool)); } else if (this.AreBothChildrenSameEnum() == true) { return(typeof(bool)); } else { // Invalid operands return(null); } }
protected override System.Type GetResultType(System.Type leftType, System.Type rightType) { // Right argument (shift count) must be convertible to int32 if (ImplicitConverter.EmitImplicitNumericConvert(rightType, typeof(Int32), null) == false) { return(null); } // Left argument must be an integer type if (Utility.IsIntegralType(leftType) == false) { return(null); } TypeCode tc = Type.GetTypeCode(leftType); switch (tc) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: return(typeof(Int32)); case TypeCode.UInt32: return(typeof(UInt32)); case TypeCode.Int64: return(typeof(Int64)); case TypeCode.UInt64: return(typeof(UInt64)); default: Debug.Assert(false, "unknown left shift operand"); return(null); } }
/// <summary> /// Evalaute this node and return result. /// </summary> /// <param name="thisObject">Reference to object that is exposed as 'this'.</param> /// <returns>Result value and type of that result.</returns> public override EvalResult Evaluate(object thisObject) { // Get the result from evaluating both children EvalResult left = this[0].Evaluate(thisObject); EvalResult right = this[1].Evaluate(thisObject); // Both sides must be converted to doubles if (!ImplicitConverter.CanConvertToDouble(left.Value, _language)) { throw new ApplicationException("Cannot convert '" + left.Type.ToString() + "' type to 'Double' for left side of exponent '^' operation."); } if (!ImplicitConverter.CanConvertToDouble(right.Value, _language)) { throw new ApplicationException("Cannot convert '" + left.Type.ToString() + "' type to 'Double' for right side of exponent '^' operation."); } double leftDouble = ImplicitConverter.ConvertToDouble(left.Value, _language); double rightDouble = ImplicitConverter.ConvertToDouble(right.Value, _language); return(new EvalResult(TypeCode.Double, Math.Pow(leftDouble, rightDouble))); }
/// <summary> /// Load a PropertyDescriptor based property /// </summary> /// <param name="ilg"></param> private void EmitVirtualPropertyLoad(FleeILGenerator ilg) { // The previous value is already on the top of the stack but we need it at the bottom // Get a temporary local index int index = ilg.GetTempLocalIndex(MyPrevious.ResultType); // Store the previous value there Utility.EmitStoreLocal(ilg, index); // Load the variable collection EmitLoadVariables(ilg); // Load the property name ilg.Emit(OpCodes.Ldstr, MyName); // Load the previous value and convert it to object Utility.EmitLoadLocal(ilg, index); ImplicitConverter.EmitImplicitConvert(MyPrevious.ResultType, typeof(object), ilg); // Call the method to get the actual value MethodInfo mi = VariableCollection.GetVirtualPropertyLoadMethod(this.ResultType); this.EmitMethodCall(mi, ilg); }