Beispiel #1
0
        /// <summary>
        /// Tries to evaluate an application of a standard arithmetic operator.
        /// </summary>
        /// <param name="prototype">
        /// The full intrinsic prototype for the arithmetic operator.
        /// </param>
        /// <param name="arguments">
        /// The operator application's arguments.
        /// </param>
        /// <param name="result">
        /// The operator application's result, if it can be computed.
        /// </param>
        /// <returns>
        /// <c>true</c> if the operator application can be evaluated; otherwise,
        /// <c>false</c>.
        /// </returns>
        public static bool TryEvaluate(
            IntrinsicPrototype prototype,
            IReadOnlyList <Constant> arguments,
            out Constant result)
        {
            string operatorName;
            bool   isChecked;

            if (!TryParseArithmeticIntrinsicName(prototype.Name, out operatorName, out isChecked))
            {
                throw new InvalidOperationException($"Cannot evaluate non-arithmetic intrinsic '{prototype.Name}'.");
            }
            else if (TryEvaluateUnchecked(operatorName, prototype, arguments, out result))
            {
                if (isChecked)
                {
                    return(result is IntegerConstant && ((IntegerConstant)result).IsValid);
                }
                else
                {
                    return(true);
                }
            }
            else
            {
                result = null;
                return(false);
            }
        }
Beispiel #2
0
 /// <summary>
 /// Creates a memory intrinsic prototype.
 /// </summary>
 /// <param name="operatorName">
 /// The name of the operator represented by the memory intrinsic.
 /// </param>
 /// <param name="resultType">
 /// The type of value produced by the intrinsic to create.
 /// </param>
 /// <param name="parameterTypes">
 /// The types of the values the intrinsic takes as arguments.
 /// </param>
 /// <returns>
 /// A memory intrinsic prototype.
 /// </returns>
 public static IntrinsicPrototype CreatePrototype(
     string operatorName,
     IType resultType,
     IReadOnlyList <IType> parameterTypes)
 {
     return(IntrinsicPrototype.Create(
                Namespace.GetIntrinsicName(operatorName),
                resultType,
                parameterTypes));
 }
Beispiel #3
0
 /// <summary>
 /// Creates an arithmetic intrinsic prototype.
 /// </summary>
 /// <param name="operatorName">
 /// The name of the operator represented by the arithmetic intrinsic.
 /// </param>
 /// <param name="isChecked">
 /// Tells if the arithmetic intrinsic is checked, that is,
 /// if it throws on overflow.
 /// </param>
 /// <param name="resultType">
 /// The type of value produced by the intrinsic to create.
 /// </param>
 /// <param name="parameterTypes">
 /// The types of the values the intrinsic takes as arguments.
 /// </param>
 /// <returns>
 /// An arithmetic intrinsic prototype.
 /// </returns>
 public static IntrinsicPrototype CreatePrototype(
     string operatorName,
     bool isChecked,
     IType resultType,
     IReadOnlyList <IType> parameterTypes)
 {
     return(IntrinsicPrototype.Create(
                GetArithmeticIntrinsicName(operatorName, isChecked),
                resultType,
                parameterTypes));
 }
 /// <summary>
 /// Creates an arithmetic intrinsic prototype.
 /// </summary>
 /// <param name="operatorName">
 /// The name of the operator represented by the arithmetic intrinsic.
 /// </param>
 /// <param name="resultType">
 /// The type of value produced by the intrinsic to create.
 /// </param>
 /// <param name="parameterTypes">
 /// The types of the values the intrinsic takes as arguments.
 /// </param>
 /// <returns>
 /// An arithmetic intrinsic prototype.
 /// </returns>
 public static IntrinsicPrototype CreatePrototype(
     string operatorName,
     IType resultType,
     IReadOnlyList <IType> parameterTypes)
 {
     // TODO: exception specification?
     return(IntrinsicPrototype.Create(
                GetArithmeticIntrinsicName(operatorName),
                resultType,
                parameterTypes));
 }
Beispiel #5
0
        private static bool TryEvaluateUnchecked(
            string operatorName,
            IntrinsicPrototype prototype,
            IReadOnlyList <Constant> arguments,
            out Constant result)
        {
            if (arguments.Count == 2)
            {
                var lhs = arguments[0];
                var rhs = arguments[1];
                if (prototype.ResultType.IsIntegerType() &&
                    lhs is IntegerConstant &&
                    rhs is IntegerConstant)
                {
                    var resultSpec = prototype.ResultType.GetIntegerSpecOrNull();
                    var intLhs     = (IntegerConstant)lhs;
                    var intRhs     = (IntegerConstant)rhs;
                    var maxIntSpec = UnionIntSpecs(
                        resultSpec,
                        intLhs.Spec,
                        intRhs.Spec);

                    Func <IntegerConstant, IntegerConstant, IntegerConstant> impl;
                    if (intBinaryOps.TryGetValue(operatorName, out impl))
                    {
                        result = impl(
                            intLhs.Cast(maxIntSpec),
                            intRhs.Cast(maxIntSpec)).Cast(resultSpec);
                        return(true);
                    }
                }
                else if (prototype.ResultType == prototype.ParameterTypes[0] &&
                         lhs is Float64Constant &&
                         rhs is Float64Constant)
                {
                    Func <double, double, double?> impl;
                    if (doubleBinaryOps.TryGetValue(operatorName, out impl))
                    {
                        var maybeResult = impl(
                            ((Float64Constant)lhs).Value,
                            ((Float64Constant)rhs).Value);

                        if (maybeResult.HasValue)
                        {
                            result = new Float64Constant(maybeResult.Value);
                            return(true);
                        }
                    }
                }
                else if (prototype.ResultType == prototype.ParameterTypes[0] &&
                         lhs is Float32Constant &&
                         rhs is Float32Constant)
                {
                    Func <float, float, float?> impl;
                    if (floatBinaryOps.TryGetValue(operatorName, out impl))
                    {
                        var maybeResult = impl(
                            ((Float32Constant)lhs).Value,
                            ((Float32Constant)rhs).Value);

                        if (maybeResult.HasValue)
                        {
                            result = new Float32Constant(maybeResult.Value);
                            return(true);
                        }
                    }
                }
            }
            else if (arguments.Count == 1)
            {
                var operand = arguments[0];
                if (operatorName == Operators.Convert &&
                    operand is IntegerConstant &&
                    prototype.ResultType.IsIntegerType())
                {
                    result = ((IntegerConstant)operand).Cast(
                        prototype.ResultType.GetIntegerSpecOrNull());
                    return(true);
                }
            }
            result = null;
            return(false);
        }