Example #1
0
            /// <summary>
            /// Takes a TNumber and returns its absolute value.
            /// </summary>
            /// <param name="interpreter">The interpreter that the method is being called from.</param>
            /// <param name="value">The TNumber to get the absolute value of.</param>
            /// <returns>
            /// The TType resulting from the operation. An MExcpetion or null is returned when there is an error.
            /// </returns>
            public static TType Modulus(Interpreter interpreter, TType value)
            {
                TNumber    number;
                TException exception = AssignNumberValue(interpreter, out number, value);

                if (exception != null)
                {
                    return(exception);
                }

                // No errors yet, but make sure it's not a string
                if (number == null)
                {
                    return(new TException(interpreter, "Strings cannot be used in modulus operations"));
                }

                switch (number.TypeName)
                {
                case TType.T_INTEGER_TYPENAME:
                    return(new TInteger(System.Math.Abs(number.TIntegerValue)));

                case TType.T_REAL_TYPENAME:
                    return(new TReal(System.Math.Abs(number.TRealValue)));

                case TType.T_FRACTION_TYPENAME:
                    TFraction fraction = number as TFraction;
                    return(new TFraction(System.Math.Abs(fraction.Numerator), fraction.Denominator));
                    // No need to abs denominator as TFraction denominators are automatically kept positive
                }

                return(null);
            }
Example #2
0
            /// <summary>
            /// Takes two TNumbers and returns the first one to the power of the other.
            /// </summary>
            /// <param name="interpreter">The interpreter that the method is being called from.</param>
            /// <param name="a">The left hand operand of the operation.</param>
            /// <param name="b">The right hand operand of the operation.</param>
            /// <returns>
            /// The TType resulting from the operation. An MExcpetion or null is returned when there is an error.
            /// </returns>
            public static TType Pow(Interpreter interpreter, TType a, TType b)
            {
                // Try to get TNumber values from the TType arguments
                TNumber    numberA, numberB;
                TException exception = AssignNumberValue(interpreter, out numberA, a);

                if (exception != null)
                {
                    return(exception);
                }
                exception = AssignNumberValue(interpreter, out numberB, b);
                if (exception != null)
                {
                    return(exception);
                }

                // No errors, but one or both of the arguments could be a TString; check them
                if ((numberA == null) || (numberB == null))
                {
                    return(new TException(interpreter, "Strings cannot be used in exponentiation operations"));
                }

                switch (numberA.TypeName)
                {
                case TType.T_INTEGER_TYPENAME:
                    return(new TInteger(
                               (long)System.Math.Round(System.Math.Pow(numberA.TRealValue, numberB.TRealValue))));

                case TType.T_REAL_TYPENAME:
                    return(new TReal(System.Math.Pow(numberA.TRealValue, numberB.TRealValue)));

                case TType.T_FRACTION_TYPENAME:
                    TFraction fraction  = numberA as TFraction;
                    long      numerator =
                        (long)System.Math.Round(System.Math.Pow(fraction.Numerator, numberB.TRealValue));
                    long denominator =
                        (long)System.Math.Round(System.Math.Pow(fraction.Denominator, numberB.TRealValue));
                    return(new TFraction(numerator, denominator));
                }

                return(null);
            }
Example #3
0
            /// <summary>
            /// Takes two TNumbers or two TStrings (or up to two TVariables containing TNumbers or TStrings) and
            /// adds them together.
            /// </summary>
            /// <param name="interpreter">The interpreter that the method is being called from.</param>
            /// <param name="a">The left hand operand of the operation.</param>
            /// <param name="b">The right hand operand of the operation.</param>
            /// <returns>
            /// The TType resulting from the operation. An MExcpetion or null is returned when there is an error.
            /// </returns>
            public static TType Add(Interpreter interpreter, TType a, TType b)
            {
                // Convert arguments 'a' and 'b' into either a TNumber or a TString
                TNumber numberA, numberB;
                TString strA = null, strB = null;

                TException exception = AssignNumberValue(interpreter, out numberA, a);

                if (exception != null)
                {
                    return(exception);
                }

                if (numberA == null)
                {
                    // No errors yet, and numberA is null, so argument 'a' could be a TString or a TVariable
                    // containing a TString
                    strA = a as TString;
                    if (strA == null)
                    {
                        TVariable variable = a as TVariable;
                        if (variable != null)
                        {
                            strA = variable.Value as TString;
                        }
                    }
                }
                if ((numberA == null) && (strA == null)) // Nothing useful, return a TException
                {
                    return(new TException(interpreter, "Value is not a number or string"));
                }


                // Same procedure for argument 'b'
                exception = AssignNumberValue(interpreter, out numberB, b);
                if (exception != null)
                {
                    return(exception);
                }
                if (numberB == null)
                {
                    strB = b as TString;
                    if (strB == null)
                    {
                        TVariable variable = b as TVariable;
                        if (variable != null)
                        {
                            strB = variable.Value as TString;
                        }
                    }
                }
                if ((numberB == null) && (strB == null))
                {
                    return(new TException(interpreter, "Value is not a number or string"));
                }

                // Attempt addition if both operands are the same type, otherwise return a TException
                if ((numberB == null) && (strA == null))
                {
                    return(new TException(interpreter, "Attempted addition of a string to a number"));
                }
                else if ((numberA == null) && (strB == null))
                {
                    return(new TException(interpreter, "Attempted addition of a number to a string"));
                }
                else if ((numberA == null) && (numberB == null))
                {
                    return(new TString(strA.Value + strB.Value));
                }
                else
                {
                    //The left hand operand decides the type of the returned value
                    switch (numberA.TypeName)
                    {
                    case TType.T_INTEGER_TYPENAME:
                    {
                        // If the other operand is a fraction, treat this integer as a fraction (i.e. value/1)
                        TFraction fraction = numberB as TFraction;
                        if (fraction != null)
                        {
                            // Copy the right hand fraction and add the left hand integer to it
                            fraction = new TFraction(fraction.Numerator, fraction.Denominator);
                            fraction.Add(numberA.TIntegerValue, 1);
                            return(fraction);
                        }
                        return(new TInteger(numberA.TIntegerValue + numberB.TIntegerValue));
                    }

                    case TType.T_REAL_TYPENAME:
                        return(new TReal(numberA.TRealValue + numberB.TRealValue));

                    case TType.T_FRACTION_TYPENAME:
                    {
                        // Create a copy of the left hand fraction
                        TFraction fraction = numberA as TFraction;
                        fraction = new TFraction(fraction.Numerator, fraction.Denominator);

                        // Convert the right hand operand to a fraction
                        long      numerator, denominator;
                        TFraction otherFraction = numberB as TFraction;
                        if (otherFraction != null)         // If it's a fraction, simply copy the values
                        {
                            numerator   = otherFraction.Numerator;
                            denominator = otherFraction.Denominator;
                        }
                        else
                        {
                            // Check if it's a TInteger first. It might not need to use DoubleToFraction
                            if (numberB is TInteger)
                            {
                                numerator   = numberB.TIntegerValue;
                                denominator = 1;
                            }
                            else
                            {
                                Operations.Misc.DoubleToFraction(numberB.TRealValue, out numerator,
                                                                 out denominator);
                            }
                        }

                        fraction.Add(numerator, denominator);
                        return(fraction);
                    }
                    }
                }

                return(null);
            }
Example #4
0
            /// <summary>
            /// Takes two TNumbers and divides one by the other.
            /// </summary>
            /// <param name="interpreter">The interpreter that the method is being called from.</param>
            /// <param name="a">The left hand operand of the operation.</param>
            /// <param name="b">The right hand operand of the operation.</param>
            /// <returns>
            /// The TType resulting from the operation. An MExcpetion or null is returned when there is an error.
            /// </returns>
            public static TType Divide(Interpreter interpreter, TType a, TType b)
            {
                // Try to get TNumber values from the TType arguments
                TNumber    numberA, numberB;
                TException exception = AssignNumberValue(interpreter, out numberA, a);

                if (exception != null)
                {
                    return(exception);
                }
                exception = AssignNumberValue(interpreter, out numberB, b);
                if (exception != null)
                {
                    return(exception);
                }

                // No errors, but one or both of the arguments could be a TString; check them
                if ((numberA == null) || (numberB == null))
                {
                    return(new TException(interpreter, "Strings cannot be used in division operations"));
                }

                switch (numberA.TypeName)
                {
                case TType.T_INTEGER_TYPENAME:
                {
                    // If the other operand is a fraction, treat this integer as a fraction (i.e. value/1)
                    TFraction rhsFraction = numberB as TFraction;
                    if (rhsFraction != null)
                    {
                        // Order of fractions matters in this case
                        TFraction lhsFraction = new TFraction(numberA.TIntegerValue, 1);
                        lhsFraction.Divide(rhsFraction.Numerator, rhsFraction.Denominator);
                        return(lhsFraction);
                    }
                    if (numberB.TypeName == TType.T_INTEGER_TYPENAME)
                    {
                        return(new TFraction(numberA.TIntegerValue, numberB.TIntegerValue));
                    }
                    return(new TInteger(numberA.TIntegerValue / numberB.TIntegerValue));
                }

                case TType.T_REAL_TYPENAME:
                    return(new TReal(numberA.TRealValue / numberB.TRealValue));

                case TType.T_FRACTION_TYPENAME:
                {
                    // Create a copy of the left hand fraction
                    TFraction fraction = numberA as TFraction;
                    fraction = new TFraction(fraction.Numerator, fraction.Denominator);

                    // Convert the right hand operand to a fraction
                    long      numerator, denominator;
                    TFraction otherFraction = numberB as TFraction;
                    if (otherFraction != null)         // If it's a fraction, simply copy the values
                    {
                        numerator   = otherFraction.Numerator;
                        denominator = otherFraction.Denominator;
                    }
                    else
                    {
                        // Check if it's a TInteger first. It might not need to use DoubleToFraction
                        if (numberB is TInteger)
                        {
                            numerator   = numberB.TIntegerValue;
                            denominator = 1;
                        }
                        else
                        {
                            Operations.Misc.DoubleToFraction(numberB.TRealValue, out numerator,
                                                             out denominator);
                        }
                    }

                    fraction.Divide(numerator, denominator);
                    return(fraction);
                }
                }

                return(null);
            }