Ejemplo n.º 1
0
        /// <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);
            }
        }
Ejemplo n.º 2
0
        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));
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
            }
        }
Ejemplo n.º 6
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        /// <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");
            }
        }
Ejemplo n.º 9
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 10
0
        //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);
        }
Ejemplo n.º 11
0
        /// <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");
            }
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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);
            }
        }
Ejemplo n.º 15
0
        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);
            }
        }
Ejemplo n.º 16
0
        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);
            }
        }
Ejemplo n.º 17
0
        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);
            }
        }
Ejemplo n.º 18
0
        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);
            }
        }
Ejemplo n.º 19
0
Archivo: Negate.cs Proyecto: Nucs/Regen
        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);
            }
        }
Ejemplo n.º 20
0
        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);
        }
Ejemplo n.º 21
0
        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));
        }
Ejemplo n.º 22
0
        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);
            }
        }
Ejemplo n.º 23
0
        /// <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");
            }
        }
Ejemplo n.º 24
0
        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);
            }
        }
Ejemplo n.º 25
0
        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");
            }
        }
Ejemplo n.º 26
0
        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");
            }
        }
Ejemplo n.º 27
0
        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);
            }
        }
Ejemplo n.º 28
0
        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);
            }
        }
Ejemplo n.º 29
0
        /// <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)));
        }
Ejemplo n.º 30
0
        /// <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);
        }