예제 #1
0
        /// <summary>
        /// Calculate the square root of a float
        /// </summary>
        /// <param name="expr"> The float</param>
        /// <returns> The sqrt of the input float</returns>
        private static Variable sqrtFunction(Expression expr)
        {
            Variable v = expr.evaluate();

            if (v is Integer)
            {
                int raw_int = v.getValue();
                // ReSharper disable once RedundantCast
                float raw_float = (float)raw_int;
                v = new FloatVar(raw_float);
            }
            Debugging.assert(v is FloatVar);
            double real      = (double)v.getValue();
            float  real_sqrt = (float)Math.Sqrt(real);

            return(new FloatVar(real_sqrt));
        }
예제 #2
0
        /// <summary>
        /// Applies an arithmetical or logical operation on two <see cref="Variable"/>s
        /// <para/>result = (variable1) op (variable2)
        /// </summary>
        /// <param name="v1"> var 1</param>
        /// <param name="v2"> var 2</param>
        /// <param name="op"> operator (e.g. '+', '-', '&')</param>
        /// <returns> result <see cref="Variable"/></returns>
        /// <exception cref="AquilaExceptions.InvalidTypeError"> Invalid type with this operator</exception>
        /// <exception cref="AquilaExceptions.SyntaxExceptions.SyntaxError"> Unknown operator char</exception>
        private static Variable applyOperator(Variable v1, Variable v2, char op)
        {
            int comparison;

            Debugging.print("applyOperator: ", v1.ToString(), " ", op, " ", v2.ToString(), " (", v1.getTypeString(), " ", op, " ", v2.getTypeString(), ")");
            // Debugging.assert(v1.hasSameParent(v2)); // operations between same classes/subclasses
            if (!v1.hasSameParent(v2))
            {
                if (v2.isConst())
                {
                    if (v2 is Integer)
                    {
                        Debugging.print("Converting int to float because of const status: ", v1.ToString());
                        Debugging.assert(v1 is FloatVar, new AquilaExceptions.InvalidTypeError($"The type \"{v1.getTypeString()}\" was not expected. \"{v1.getTypeString()}\" expected")); // if this is not a float, operation is not permitted !
                        v2 = new FloatVar((float)v2.getValue());
                    }
                }
                else
                {
                    throw new AquilaExceptions.InvalidTypeError($"The type \"{v1.getTypeString()}\" was not expected");
                }
            }
            switch (op)
            {
            // arithmetic
            case '+':
                if (v1 is NumericalValue)
                {
                    return(((NumericalValue)v1).addition((NumericalValue)v2));
                }
                else
                {
                    throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\"");
                }

            case '-':
                if (v1 is NumericalValue)
                {
                    return(((NumericalValue)v1).subtraction((NumericalValue)v2));
                }
                else
                {
                    throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\"");
                }

            case '/':
                if (v1 is NumericalValue)
                {
                    return(((NumericalValue)v1).division((NumericalValue)v2));
                }
                else
                {
                    throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\"");
                }

            case '*':
                if (v1 is NumericalValue)
                {
                    return(((NumericalValue)v1).mult((NumericalValue)v2));
                }
                else
                {
                    throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\"");
                }

            case '%':
                if (v1 is Integer)
                {
                    return(((Integer)v1).modulo((Integer)v2));
                }
                else
                {
                    throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\"");
                }

            // logic
            case '<':
                Debugging.assert(v1 is Integer || v1 is FloatVar);
                comparison = v1 is Integer
                        ? ((Integer)v1).compare(v2 as Integer)
                        : ((FloatVar)v1).compare(v2 as FloatVar);
                return(new BooleanVar(comparison == -1));

            case '>':
                Debugging.assert(v1 is Integer || v1 is FloatVar);
                comparison = v1 is Integer
                        ? ((Integer)v1).compare(v2 as Integer)
                        : ((FloatVar)v1).compare(v2 as FloatVar);
                return(new BooleanVar(comparison == 1));

            case '{':
                Debugging.assert(v1 is Integer || v1 is FloatVar);
                comparison = v1 is Integer
                        ? ((Integer)v1).compare(v2 as Integer)
                        : ((FloatVar)v1).compare(v2 as FloatVar);
                return(new BooleanVar(comparison != 1));

            case '}':
                Debugging.assert(v1 is Integer || v1 is FloatVar);
                comparison = v1 is Integer
                        ? ((Integer)v1).compare(v2 as Integer)
                        : ((FloatVar)v1).compare(v2 as FloatVar);
                return(new BooleanVar(comparison != -1));

            case '~':
                Debugging.assert(v1 is Integer || v1 is FloatVar);
                comparison = v1 is Integer
                        ? ((Integer)v1).compare(v2 as Integer)
                        : ((FloatVar)v1).compare(v2 as FloatVar);
                return(new BooleanVar(comparison == 0));

            case ':':
                Debugging.assert(v1 is Integer || v1 is FloatVar);
                comparison = v1 is Integer
                        ? ((Integer)v1).compare(v2 as Integer)
                        : ((FloatVar)v1).compare(v2 as FloatVar);
                return(new BooleanVar(comparison != 0));

            case '|':
                Debugging.assert(v1 is BooleanVar);
                return(((BooleanVar)v1).or((BooleanVar)v2));

            case '^':
                Debugging.assert(v1 is BooleanVar);
                return(((BooleanVar)v1).xor((BooleanVar)v2));

            case '&':
                Debugging.assert(v1 is BooleanVar);
                return(((BooleanVar)v1).and((BooleanVar)v2));

            default:
                throw new AquilaExceptions.SyntaxExceptions.SyntaxError("Unknown operand " + op);
            }
        }