コード例 #1
0
        /// <summary>
        /// Generates a vector related expression given a supported expression generation request.
        /// </summary>
        /// <param name="request">The expression generation request to be processed.</param>
        /// <returns>A new expression or null if the request is not supported.</returns>
        public Expression Generate(IExpressionGenerationRequest request) {
            if (null == request) throw new ArgumentNullException("request");
            Contract.EndContractBlock();

            var expressionName = request.ExpressionName;
            var inputExpressions = request.InputExpressions.ToArray();
            var topLevelGenerator = request.TopLevelGenerator;

            if (inputExpressions.Length > 0) {
                if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "MAGNITUDE"))
                    return new MagnitudeExpression(inputExpressions, topLevelGenerator);
                if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "SQUAREDMAGNITUDE"))
                    return new SquaredMagnitudeExpression(inputExpressions, topLevelGenerator);

                if (inputExpressions.Length % 2 == 0) {
                    if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "DOTPRODUCT"))
                        return new DotProductExpression(inputExpressions, topLevelGenerator);
                    if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "DISTANCE"))
                        return new DistanceExpression(inputExpressions, topLevelGenerator);
                    if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "SQUAREDDISTANCE"))
                        return new SquaredDistanceExpression(inputExpressions, topLevelGenerator);
                }
            }

            return null;
        }
コード例 #2
0
        private Expression CreatePow(IExpressionGenerationRequest request, Expression left, Expression right)
        {
            Contract.Requires(null != request);
            Contract.Requires(null != left);
            Contract.Requires(null != right);

            if (left.Type == typeof(double) && right.Type == typeof(double))
            {
                return(Expression.Power(left, right));
            }

            var lhsDouble = request.TopLevelGenerator.GenerateConversion(typeof(double), left);
            var rhsDouble = request.TopLevelGenerator.GenerateConversion(typeof(double), right);

            if (lhsDouble == null || rhsDouble == null)
            {
                return(null);
            }

            Expression result = Expression.Power(lhsDouble, rhsDouble);

            if (request.DesiredResultType != null && request.DesiredResultType != result.Type)
            {
                result = request.TopLevelGenerator.GenerateConversion(request.DesiredResultType, result);
            }

            return(result);
        }
コード例 #3
0
 /// <inheritdoc/>
 public Expression Generate(IExpressionGenerationRequest request) {
     if (null == request) throw new ArgumentNullException("request");
     Contract.EndContractBlock();
     return AllExpressionGenerators
         .Select(x => x.Generate(request))
         .FirstOrDefault(x => null != x);
 }
コード例 #4
0
 private Expression GenerateSquareRoot(IExpressionGenerationRequest request, Expression parameter)
 {
     Contract.Requires(null != request);
     Contract.Requires(null != parameter);
     Contract.Ensures(Contract.Result <Expression>() != null);
     return(new SquareRootExpression(parameter, request.TopLevelGenerator));
 }
コード例 #5
0
        /// <inheritdoc/>
        public Expression Generate(IExpressionGenerationRequest request)
        {
            if (null == request)
            {
                throw new ArgumentNullException("request");
            }
            if (String.IsNullOrEmpty(request.ExpressionName))
            {
                throw new ArgumentException("Invalid request expression name.", "request");
            }
            Contract.EndContractBlock();

            var expressionName = request.ExpressionName;

            if (
                "CONVERT".Equals(expressionName, StringComparison.OrdinalIgnoreCase) &&
                request.InputExpressions.Count == 1 &&
                null != request.DesiredResultType
                )
            {
                Contract.Assume(request.InputExpressions[0] != null);
                return(GenerateConversionExpression(request.InputExpressions[0], request.DesiredResultType));
            }

            if (
                request.InputExpressions.Count == 0 &&
                null != request.DesiredResultType &&
                typeof(void) != request.DesiredResultType
                )
            {
                return(GenerateConstantExpression(expressionName, request.DesiredResultType));
            }

            return(GenerateStandardExpression(request));
        }
コード例 #6
0
 /// <inheritdoc/>
 public Expression Generate(IExpressionGenerationRequest request)
 {
     if (null == request)
     {
         throw new ArgumentNullException("request");
     }
     Contract.EndContractBlock();
     return(AllExpressionGenerators
            .Select(x => x.Generate(request))
            .FirstOrDefault(x => null != x));
 }
コード例 #7
0
        private Expression GenerateNegation(IExpressionGenerationRequest request, Expression parameter)
        {
            Contract.Requires(null != request);
            Contract.Requires(null != parameter);
            var resultType = parameter.Type;

            if (resultType == typeof(ulong) || resultType == typeof(uint) || resultType == typeof(ushort) || resultType == typeof(byte) || resultType == typeof(sbyte))
            {
                var zeroConstant = GenerateConstantExpression("0", resultType);
                Contract.Assume(null != zeroConstant);
                return(request.TopLevelGenerator.Generate("Subtract", zeroConstant, parameter));
            }
            return(Checked ? Expression.NegateChecked(parameter) : Expression.Negate(parameter));
        }
コード例 #8
0
        /// <summary>
        /// Generates a vector related expression given a supported expression generation request.
        /// </summary>
        /// <param name="request">The expression generation request to be processed.</param>
        /// <returns>A new expression or null if the request is not supported.</returns>
        public Expression Generate(IExpressionGenerationRequest request)
        {
            if (null == request)
            {
                throw new ArgumentNullException("request");
            }
            Contract.EndContractBlock();

            var expressionName    = request.ExpressionName;
            var inputExpressions  = request.InputExpressions.ToArray();
            var topLevelGenerator = request.TopLevelGenerator;

            if (inputExpressions.Length > 0)
            {
                if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "MAGNITUDE"))
                {
                    return(new MagnitudeExpression(inputExpressions, topLevelGenerator));
                }
                if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "SQUAREDMAGNITUDE"))
                {
                    return(new SquaredMagnitudeExpression(inputExpressions, topLevelGenerator));
                }

                if (inputExpressions.Length % 2 == 0)
                {
                    if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "DOTPRODUCT"))
                    {
                        return(new DotProductExpression(inputExpressions, topLevelGenerator));
                    }
                    if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "DISTANCE"))
                    {
                        return(new DistanceExpression(inputExpressions, topLevelGenerator));
                    }
                    if (StringComparer.OrdinalIgnoreCase.Equals(expressionName, "SQUAREDDISTANCE"))
                    {
                        return(new SquaredDistanceExpression(inputExpressions, topLevelGenerator));
                    }
                }
            }

            return(null);
        }
コード例 #9
0
        private Expression GenerateArithmetic(IExpressionGenerationRequest request, IList <Expression> inputs)
        {
            Contract.Requires(request != null);
            Contract.Requires(inputs != null);
            Contract.Requires(inputs.Count >= 1);
            Contract.Requires(Contract.ForAll(inputs, x => x != null));
            Contract.Assume(inputs[0] != null);
            var result = inputs[0];

            for (int i = 1; i < inputs.Count; i++)
            {
                Contract.Assume(inputs[i] != null);
                result = GenerateArithmetic(request, result, inputs[i]);
                if (null == result)
                {
                    return(null);
                }
            }
            return(result);
        }
コード例 #10
0
        private Expression GenerateCompareTo(IExpressionGenerationRequest request, Expression left, Expression right)
        {
            Contract.Requires(null != request);
            Contract.Requires(null != left);
            Contract.Requires(null != right);
            if (left.IsMemoryLocationOrConstant() && right.IsMemoryLocationOrConstant())
            {
                var eq   = request.TopLevelGenerator.GenerateOrThrow("EQUAL", left, right);
                var less = request.TopLevelGenerator.GenerateOrThrow("LESS", left, right);
                Contract.Assume(typeof(IComparable <>).GetGenericArguments() != null);
                Contract.Assume(typeof(IComparable <>).GetGenericArguments().Length == 1);
                Contract.Assume(typeof(IComparable <>).IsGenericTypeDefinition());
                var comparableType = typeof(IComparable <>).MakeGenericType(right.Type);

                if (left.Type.ImplementsInterface(comparableType))
                {
                    var method = comparableType.GetPublicInstanceInvokableMethod(
                        "CompareTo",
                        new[] { right.Type }
                        );
                    Contract.Assume(method != null);
                    return(method.BuildInstanceCallExpression(left, right));
                }

                return(Expression.Condition(
                           eq,
                           Expression.Constant(0),
                           Expression.Condition(
                               less,
                               Expression.Constant(-1),
                               Expression.Constant(1)
                               )
                           ));
            }

            return(new BlockExpressionBuilder().AddUsingMemoryLocationsOrConstants(locals => new[] {
                GenerateCompareTo(request, locals[0], locals[1])
            }, left, right).GetExpression());
        }
コード例 #11
0
        private Expression GenerateArithmetic(IExpressionGenerationRequest request, Expression left, Expression right)
        {
            Contract.Requires(null != request);
            Contract.Requires(null != left);
            Contract.Requires(null != right);
            if ((left.Type == right.Type) && (left.Type == typeof(byte) || left.Type == typeof(char) || left.Type == typeof(sbyte)))
            {
                var methodName = ToTitleCase(request.ExpressionName) + (Checked ? "Checked" : "Unchecked");
                Contract.Assume(!String.IsNullOrEmpty(methodName));
                var method = typeof(SpecializedOperations).GetPublicStaticInvokableMethod(
                    methodName,
                    new[] { left.Type, left.Type }
                    );
                if (null != method)
                {
                    return(Expression.Call(method, left, right));
                }
            }

            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Add"))
            {
                return(Checked ? Expression.AddChecked(left, right) : Expression.Add(left, right));
            }
            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Subtract"))
            {
                return(Checked ? Expression.SubtractChecked(left, right) : Expression.Subtract(left, right));
            }
            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Multiply"))
            {
                return(Checked ? Expression.MultiplyChecked(left, right) : Expression.Multiply(left, right));
            }
            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Divide"))
            {
                return(Expression.Divide(left, right));
            }
            return(null);
        }
コード例 #12
0
        private Expression GenerateStandardExpression(IExpressionGenerationRequest expressionRequest)
        {
            Contract.Requires(null != expressionRequest);

            var parameters     = expressionRequest.InputExpressions;
            var expressionName = expressionRequest.ExpressionName;

            if (parameters.Count == 1)
            {
                Func <IExpressionGenerationRequest, Expression, Expression> unaryGenerator;
                if (_standardUnaryExpressionGeneratorLookup.TryGetValue(expressionName, out unaryGenerator))
                {
                    Contract.Assume(unaryGenerator != null);
                    return(unaryGenerator(expressionRequest, parameters[0]));
                }
            }
            if (parameters.Count == 2)
            {
                Func <IExpressionGenerationRequest, Expression, Expression, Expression> binaryGenerator;
                if (_standardBinaryExpressionGeneratorLookup.TryGetValue(expressionName, out binaryGenerator))
                {
                    Contract.Assume(binaryGenerator != null);
                    return(binaryGenerator(expressionRequest, parameters[0], parameters[1]));
                }
            }
            if (parameters.Count > 2)
            {
                var result = GenerateArithmetic(expressionRequest, parameters);
                if (null != result)
                {
                    return(result);
                }
            }

            return(null);
        }
コード例 #13
0
 private Expression GenerateSquareRoot(IExpressionGenerationRequest request, Expression parameter) {
     Contract.Requires(null != request);
     Contract.Requires(null != parameter);
     Contract.Ensures(Contract.Result<Expression>() != null);
     return new SquareRootExpression(parameter, request.TopLevelGenerator);
 }
コード例 #14
0
 private Expression GenerateArithmetic(IExpressionGenerationRequest request, IList<Expression> inputs) {
     Contract.Requires(request != null);
     Contract.Requires(inputs != null);
     Contract.Requires(inputs.Count >= 1);
     Contract.Requires(Contract.ForAll(inputs, x => x != null));
     Contract.Assume(inputs[0] != null);
     var result = inputs[0];
     for (int i = 1; i < inputs.Count; i++) {
         Contract.Assume(inputs[i] != null);
         result = GenerateArithmetic(request, result, inputs[i]);
         if (null == result)
             return null;
     }
     return result;
 }
コード例 #15
0
 private Expression GenerateNegation(IExpressionGenerationRequest request, Expression parameter) {
     Contract.Requires(null != request);
     Contract.Requires(null != parameter);
     var resultType = parameter.Type;
     if (resultType == typeof(ulong) || resultType == typeof(uint) || resultType == typeof(ushort) || resultType == typeof(byte) || resultType == typeof(sbyte)) {
         var zeroConstant = GenerateConstantExpression("0", resultType);
         Contract.Assume(null != zeroConstant);
         return request.TopLevelGenerator.Generate("Subtract", zeroConstant, parameter);
     }
     return Checked ? Expression.NegateChecked(parameter) : Expression.Negate(parameter);
 }
コード例 #16
0
        private Expression CreatePow(IExpressionGenerationRequest request, Expression left, Expression right) {
            Contract.Requires(null != request);
            Contract.Requires(null != left);
            Contract.Requires(null != right);

            if (left.Type == typeof(double) && right.Type == typeof(double))
                return Expression.Power(left, right);

            var lhsDouble = request.TopLevelGenerator.GenerateConversion(typeof (double), left);
            var rhsDouble = request.TopLevelGenerator.GenerateConversion(typeof (double), right);
            if (lhsDouble == null || rhsDouble == null)
                return null;

            Expression result = Expression.Power(lhsDouble, rhsDouble);

            if (request.DesiredResultType != null && request.DesiredResultType != result.Type)
                result = request.TopLevelGenerator.GenerateConversion(request.DesiredResultType, result);

            return result;
        }
コード例 #17
0
 public Expression Generate(IExpressionGenerationRequest request)
 {
     Contract.Requires(null != request);
     Contract.EndContractBlock();
     throw new NotImplementedException();
 }
コード例 #18
0
        private Expression GenerateArithmetic(IExpressionGenerationRequest request, Expression left, Expression right) {
            Contract.Requires(null != request);
            Contract.Requires(null != left);
            Contract.Requires(null != right);
            if ((left.Type == right.Type) && (left.Type == typeof(byte) || left.Type == typeof(char) || left.Type == typeof(sbyte))) {
                var methodName = ToTitleCase(request.ExpressionName) + (Checked ? "Checked" : "Unchecked");
                Contract.Assume(!String.IsNullOrEmpty(methodName));
                var method = typeof(SpecializedOperations).GetPublicStaticInvokableMethod(
                    methodName,
                    new[] { left.Type, left.Type }
                );
                if (null != method) {
                    return Expression.Call(method, left, right);
                }
            }

            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Add"))
                return Checked ? Expression.AddChecked(left, right) : Expression.Add(left, right);
            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Subtract"))
                return Checked ? Expression.SubtractChecked(left, right) : Expression.Subtract(left, right);
            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Multiply"))
                return Checked ? Expression.MultiplyChecked(left, right) : Expression.Multiply(left, right);
            if (StringComparer.OrdinalIgnoreCase.Equals(request.ExpressionName, "Divide"))
                return Expression.Divide(left, right);
            return null;
        }
コード例 #19
0
 public Expression Generate(IExpressionGenerationRequest request) {
     Contract.Requires(null != request);
     Contract.EndContractBlock();
     throw new NotImplementedException();
 }
コード例 #20
0
        /// <inheritdoc/>
        public Expression Generate(IExpressionGenerationRequest request) {
            if (null == request) throw new ArgumentNullException("request");
            if (String.IsNullOrEmpty(request.ExpressionName)) throw new ArgumentException("Invalid request expression name.", "request");
            Contract.EndContractBlock();

            var expressionName = request.ExpressionName;

            if (
                "CONVERT".Equals(expressionName, StringComparison.OrdinalIgnoreCase)
                && request.InputExpressions.Count == 1
                && null != request.DesiredResultType
            ) {
                Contract.Assume(request.InputExpressions[0] != null);
                return GenerateConversionExpression(request.InputExpressions[0], request.DesiredResultType);
            }

            if (
                request.InputExpressions.Count == 0
                && null != request.DesiredResultType
                && typeof(void) != request.DesiredResultType
            ) {
                return GenerateConstantExpression(expressionName, request.DesiredResultType);
            }

            return GenerateStandardExpression(request);
        }
コード例 #21
0
        private Expression GenerateStandardExpression(IExpressionGenerationRequest expressionRequest) {
            Contract.Requires(null != expressionRequest);

            var parameters = expressionRequest.InputExpressions;
            var expressionName = expressionRequest.ExpressionName;

            if (parameters.Count == 1) {
                Func<IExpressionGenerationRequest, Expression, Expression> unaryGenerator;
                if (_standardUnaryExpressionGeneratorLookup.TryGetValue(expressionName, out unaryGenerator)) {
                    Contract.Assume(unaryGenerator != null);
                    return unaryGenerator(expressionRequest, parameters[0]);
                }
            }
            if (parameters.Count == 2) {
                Func<IExpressionGenerationRequest, Expression, Expression, Expression> binaryGenerator;
                if (_standardBinaryExpressionGeneratorLookup.TryGetValue(expressionName, out binaryGenerator)) {
                    Contract.Assume(binaryGenerator != null);
                    return binaryGenerator(expressionRequest, parameters[0], parameters[1]);
                }
            }
            if (parameters.Count > 2) {
                var result = GenerateArithmetic(expressionRequest, parameters);
                if (null != result)
                    return result;
            }

            return null;
        }
コード例 #22
0
        private Expression GenerateCompareTo(IExpressionGenerationRequest request, Expression left, Expression right) {
            Contract.Requires(null != request);
            Contract.Requires(null != left);
            Contract.Requires(null != right);
            if (left.IsMemoryLocationOrConstant() && right.IsMemoryLocationOrConstant()) {
                var eq = request.TopLevelGenerator.GenerateOrThrow("EQUAL", left, right);
                var less = request.TopLevelGenerator.GenerateOrThrow("LESS", left, right);
                Contract.Assume(typeof(IComparable<>).GetGenericArguments() != null);
                Contract.Assume(typeof(IComparable<>).GetGenericArguments().Length == 1);
                Contract.Assume(typeof(IComparable<>).IsGenericTypeDefinition());
                var comparableType = typeof(IComparable<>).MakeGenericType(right.Type);

                if (left.Type.ImplementsInterface(comparableType)) {
                    var method = comparableType.GetPublicInstanceInvokableMethod(
                        "CompareTo",
                        new[] {right.Type}
                    );
                    Contract.Assume(method != null);
                    return method.BuildInstanceCallExpression(left, right);
                }

                return Expression.Condition(
                    eq,
                    Expression.Constant(0),
                    Expression.Condition(
                        less,
                        Expression.Constant(-1),
                        Expression.Constant(1)
                    )
                );
            }

            return new BlockExpressionBuilder().AddUsingMemoryLocationsOrConstants(locals => new[] {
                GenerateCompareTo(request, locals[0], locals[1])
            }, left, right).GetExpression();
        }