/// <summary>
        /// Subtract operator.
        /// </summary>
        public static PhpNumber Sub(PhpValue x, PhpNumber y)
        {
            PhpNumber x_number;

            var x_info = x.ToNumber(out x_number);

            if ((x_info & (Convert.NumberInfo.Unconvertible | Convert.NumberInfo.IsPhpArray)) != 0)
            {
                throw new ArgumentException();  // return 0
            }

            //
            return(x_number - y);
        }
Пример #2
0
        public static double Multiply(double dx, PhpValue y)
        {
            PhpNumber ynumber;

            if ((y.ToNumber(out ynumber) & (Convert.NumberInfo.Unconvertible | Convert.NumberInfo.IsPhpArray)) != 0)
            {
                //PhpException.UnsupportedOperandTypes();
                //return 0.0;
                throw new ArgumentException();
            }

            //
            return(dx * ynumber.ToDouble());
        }
        /// <summary>
        /// Subtract operator.
        /// </summary>
        public static double Sub(double dx, PhpValue y)
        {
            PhpNumber y_number;

            var y_info = y.ToNumber(out y_number);

            if ((y_info & (Convert.NumberInfo.Unconvertible | Convert.NumberInfo.IsPhpArray)) != 0)
            {
                throw new ArgumentException();  // return 0
            }

            //
            return(dx - y_number.ToDouble());
        }
        /// <summary>
        /// Implements <c>+</c> operator on numbers.
        /// </summary>
        public static double Add(double x, PhpValue y)
        {
            PhpNumber number;

            if ((y.ToNumber(out number) & (Convert.NumberInfo.Unconvertible | Convert.NumberInfo.IsPhpArray)) != 0)
            {
                //PhpException.UnsupportedOperandTypes();
                //return 0.0;
                throw new ArgumentException();  // TODO: ErrCode & return 0
            }

            //
            return(x + number.ToDouble());
        }
        /// <summary>
        /// Multiply operator.
        /// </summary>
        public static double Multiply(PhpValue x, double dy)
        {
            PhpNumber xnumber;

            if (((x.ToNumber(out xnumber)) & (Convert.NumberInfo.Unconvertible | Convert.NumberInfo.IsPhpArray)) != 0)
            {
                //PhpException.UnsupportedOperandTypes();
                //return 0.0;
                throw new ArgumentException();
            }

            //
            return(xnumber.ToDouble() * dy);
        }
Пример #6
0
        /// <summary>
        /// Performs division according to PHP semantics.
        /// </summary>
        /// <remarks>The division operator ("/") returns a float value unless the two operands are integers
        /// (or strings that get converted to integers) and the numbers are evenly divisible,
        /// in which case an integer value will be returned.</remarks>
        internal static PhpNumber Div(ref PhpValue x, ref PhpValue y)
        {
            PhpNumber nx, ny;
            var       info = x.ToNumber(out nx) | y.ToNumber(out ny);

            if ((info & Convert.NumberInfo.IsPhpArray) != 0)
            {
                //PhpException.UnsupportedOperandTypes();
                //return PhpNumber.Create(0.0);
                throw new NotImplementedException();     // PhpException
            }

            // TODO: // division by zero:
            //if (y == 0)
            //{
            //    PhpException.Throw(PhpError.Warning, CoreResources.GetString("division_by_zero"));
            //    return false;
            //}

            return(nx / ny);
        }
Пример #7
0
 public Convert.NumberInfo ToNumber(out PhpNumber number) => Value.ToNumber(out number);
Пример #8
0
        /// <summary>
        /// Checks whether a dereferenced variable is numeric.
        /// </summary>
        /// <param name="variable">The variable.</param>
        /// <returns>Whether <paramref name="variable"/> is integer, double or numeric string.
        /// <seealso cref="PHP.Core.Convert.StringToNumber"/></returns>
        public static bool is_numeric(PhpValue variable)
        {
            switch (variable.TypeCode)
            {
                case PhpTypeCode.Int32:
                case PhpTypeCode.Long:
                case PhpTypeCode.Double:
                    return true;

                case PhpTypeCode.String:
                case PhpTypeCode.WritableString:
                    PhpNumber tmp;
                    return (variable.ToNumber(out tmp) & Core.Convert.NumberInfo.IsNumber) != 0;

                default:
                    return false;
            }
        }
Пример #9
0
        /// <summary>
        /// Creates an array containing range of elements with arbitrary step.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="low">Lower bound of the interval.</param>
        /// <param name="high">Upper bound of the interval.</param>
        /// <param name="step">The step.</param>
        /// <returns>The array.</returns>
        /// <remarks>
        /// Implements PHP awful range function. The result depends on types and 
        /// content of parameters under the following rules:
        /// <list type="number">
        /// <item>
        ///   <description>
        ///   If at least one parameter (low, high or step) is of type double or is a string wholly representing 
        ///       double value (i.e. whole string is converted to a number and no chars remains, 
        ///       e.g. "1.5" is wholly representing but the value "1.5x" is not)
        ///    than
        ///       range of double values is generated with a step treated as a double value
        ///       (e.g. <c>range("1x","2.5x","0.5") = array(1.0, 1.5, 2.0, 2.5)</c> etc.)
        ///    otherwise 
        ///   </description>
        /// </item>
        /// <item>
        ///   <description>
        ///    if at least one bound (i.e. low or high parameter) is of type int or is a string wholly representing
        ///       integer value 
        ///    than 
        ///       range of integer values is generated with a step treated as integer value
        ///       (e.g. <c>range("1x","2","1.5") = array(1, 2, 3, 4)</c> etc.)
        ///    otherwise
        ///   </description>
        /// </item>
        /// <item>
        ///   <description>
        ///    low and high are both non-empty strings (otherwise one of the two previous conditions would be true),
        ///    so the first characters of these strings are taken and a sequence of characters is generated.
        ///   </description>     
        /// </item>
        /// </list>
        /// Moreover, if <paramref name="low"/> is greater than <paramref name="high"/> then descending sequence is generated 
        /// and ascending one otherwise. If <paramref name="step"/> is less than zero than an absolute value is used.
        /// </remarks>
        /// <exception cref="PhpException">Thrown if the <paramref name="step"/> argument is zero (or its absolute value less than 1 in the case 2).</exception>
        public static PhpArray range(Context ctx, PhpValue low, PhpValue high, PhpValue step)
        {
            PhpNumber num_low, num_high, num_step;

            // converts each parameter to a number, determines what type of number it is (int/double)
            // and whether it wholly represents that number:
            var info_step = step.ToNumber(out num_step);
            var info_low = low.ToNumber(out num_low);
            var info_high = high.ToNumber(out num_high);

            var is_step_double = (info_step & Core.Convert.NumberInfo.Double) != 0;
            var is_low_double = (info_low & Core.Convert.NumberInfo.Double) != 0;
            var is_high_double = (info_high & Core.Convert.NumberInfo.Double) != 0;

            var w_step = (info_step & Core.Convert.NumberInfo.IsNumber) != 0;
            var w_low = (info_low & Core.Convert.NumberInfo.IsNumber) != 0;
            var w_high = (info_high & Core.Convert.NumberInfo.IsNumber) != 0;

            // at least one parameter is a double or its numeric value is wholly double:
            if (is_low_double && w_low || is_high_double && w_high || is_step_double && w_step)
            {
                return RangeOfDoubles(num_low.ToDouble(), num_high.ToDouble(), num_step.ToDouble());
            }

            // at least one bound is wholly integer (doesn't matter what the step is):
            if (!is_low_double && w_low || !is_high_double && w_high)
            {
                // at least one long integer:
                return RangeOfLongInts(num_low.ToLong(), num_high.ToLong(), num_step.ToLong());
            }

            // both bounds are strings which are not wholly representing numbers (other types wholly represents a number):

            string slow = low.ToString(ctx);
            string shigh = high.ToString(ctx);

            // because each string doesn't represent a number it isn't empty:
            Debug.Assert(slow != "" && shigh != "");

            return RangeOfChars(slow[0], shigh[0], (int)num_step.ToLong());
        }
Пример #10
0
        /// <summary>
        /// Performs division according to PHP semantics.
        /// </summary>
        /// <remarks>The division operator ("/") returns a float value unless the two operands are integers
        /// (or strings that get converted to integers) and the numbers are evenly divisible,
        /// in which case an integer value will be returned.</remarks>
        internal static PhpNumber Div(ref PhpValue x, ref PhpValue y)
        {
            PhpNumber nx, ny;
            var info = x.ToNumber(out nx) | y.ToNumber(out ny);

            if ((info & Convert.NumberInfo.IsPhpArray) != 0)
            {
                //PhpException.UnsupportedOperandTypes();
                //return PhpNumber.Create(0.0);
                throw new NotImplementedException();     // PhpException
            }

            // TODO: // division by zero:
            //if (y == 0)
            //{
            //    PhpException.Throw(PhpError.Warning, CoreResources.GetString("division_by_zero"));
            //    return false;
            //}

            return nx / ny;
        }
Пример #11
0
        /// <summary>
        /// Performs conversion of a value to a number.
        /// Additional conversion warnings may be thrown.
        /// </summary>
        public static PhpNumber ToNumber(PhpValue value)
        {
            PhpNumber n;
            if ((value.ToNumber(out n) & NumberInfo.IsNumber) == 0)
            {
                // TODO: Err
            }

            return n;
        }