Ejemplo n.º 1
0
        /// <summary>
        /// Returns the index of the given search element in the array, searching backwards from
        /// <paramref name="fromIndex"/>.
        /// </summary>
        /// <param name="searchElement"> The value to search for. </param>
        /// <param name="fromIndex"> The array index to start searching. </param>
        /// <returns> The index of the given search element in the array, or <c>-1</c> if the
        /// element wasn't found. </returns>
        public int LastIndexOf(object searchElement, int fromIndex)
        {
            // If fromIndex is less than zero, it is an offset from the end of the array.
            if (fromIndex < 0)
            {
                fromIndex += Length;
            }

            for (int i = Math.Min(Length - 1, fromIndex); i >= 0; i--)
            {
                // Get the value of the array element.
                object elementValue = this[i];

                // Compare the given search element with the array element.
                if (elementValue != null && TypeComparer.StrictEquals(searchElement, elementValue) == true)
                {
                    return(i);
                }
            }

            // The search element wasn't found.
            return(-1);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Evaluates the expression, if possible.
        /// </summary>
        /// <returns> The result of evaluating the expression, or <c>null</c> if the expression can
        /// not be evaluated. </returns>
        public override object Evaluate()
        {
            // Evaluate the operands.
            var left = this.Left.Evaluate();

            if (left == null)
            {
                return(null);
            }
            var right = this.Right.Evaluate();

            if (right == null)
            {
                return(null);
            }

            // Apply the binary operator logic.
            switch (this.OperatorType)
            {
            case OperatorType.Add:
            {
                var leftPrimitive  = TypeConverter.ToPrimitive(left, PrimitiveTypeHint.None);
                var rightPrimitive = TypeConverter.ToPrimitive(right, PrimitiveTypeHint.None);
                if (TypeUtilities.IsString(leftPrimitive) == true || TypeUtilities.IsString(rightPrimitive) == true)
                {
                    return(TypeConverter.ToString(leftPrimitive) + TypeConverter.ToString(rightPrimitive));
                }
                return(TypeConverter.ToNumber(leftPrimitive) + TypeConverter.ToNumber(rightPrimitive));
            }

            // Arithmetic operations.
            case OperatorType.Subtract:
                return(TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right));

            case OperatorType.Multiply:
                return(TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right));

            case OperatorType.Divide:
                return(TypeConverter.ToNumber(left) / TypeConverter.ToNumber(right));

            case OperatorType.Modulo:
                return(TypeConverter.ToNumber(left) % TypeConverter.ToNumber(right));

            case OperatorType.Exponentiation:
                return(Library.MathObject.Pow(TypeConverter.ToNumber(left), TypeConverter.ToNumber(right)));

            // Bitwise operations.
            case OperatorType.BitwiseAnd:
                return(TypeConverter.ToInt32(left) & TypeConverter.ToInt32(right));

            case OperatorType.BitwiseOr:
                return(TypeConverter.ToInt32(left) | TypeConverter.ToInt32(right));

            case OperatorType.BitwiseXor:
                return(TypeConverter.ToInt32(left) ^ TypeConverter.ToInt32(right));

            case OperatorType.LeftShift:
                return(TypeConverter.ToInt32(left) << (int)(TypeConverter.ToUint32(right) & 0x1F));

            case OperatorType.SignedRightShift:
                return(TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F));

            case OperatorType.UnsignedRightShift:
                return((uint)TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F));

            // Relational operations.
            case OperatorType.LessThan:
            case OperatorType.LessThanOrEqual:
            case OperatorType.GreaterThan:
            case OperatorType.GreaterThanOrEqual:
                return(PrimitiveType.Bool);

            // Equality operations.
            case OperatorType.Equal:
                return(TypeComparer.Equals(left, right) == true);

            case OperatorType.StrictlyEqual:
                return(TypeComparer.StrictEquals(left, right) == true);

            case OperatorType.NotEqual:
                return(TypeComparer.Equals(left, right) == false);

            case OperatorType.StrictlyNotEqual:
                return(TypeComparer.StrictEquals(left, right) == false);

            // Logical operations.
            case OperatorType.LogicalAnd:
                if (TypeConverter.ToBoolean(left) == false)
                {
                    return(left);
                }
                return(right);

            case OperatorType.LogicalOr:
                if (TypeConverter.ToBoolean(left) == true)
                {
                    return(left);
                }
                return(right);

            // Misc
            case OperatorType.InstanceOf:
            case OperatorType.In:
                return(null);

            default:
                throw new NotImplementedException(string.Format("Unsupported operator {0}", this.OperatorType));
            }
        }
Ejemplo n.º 3
0
        public void StrictEquals()
        {
            var engine = new ScriptEngine();

            // Undefined.
            Assert.AreEqual(true, TypeComparer.StrictEquals(Undefined.Value, Undefined.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, Null.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, false));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, true));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, 0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, 0.0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, 5.5));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, double.NaN));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, ""));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, " "));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, "5.5"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, "foo"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Undefined.Value, engine.Object.Construct()));

            // Null.
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, Undefined.Value));
            Assert.AreEqual(true, TypeComparer.StrictEquals(Null.Value, Null.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, false));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, true));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, 0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, 0.0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, 5.5));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, double.NaN));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, ""));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, " "));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, "5.5"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, "foo"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(Null.Value, engine.Object.Construct()));

            // Boolean.
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, Undefined.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, Null.Value));
            Assert.AreEqual(true, TypeComparer.StrictEquals(false, false));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, true));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, 0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, 0.0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, 5.5));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, double.NaN));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, ""));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, " "));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, "5.5"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, "foo"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, engine.Object.Construct()));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, engine.Boolean.Construct(false)));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, engine.Boolean.Construct(true)));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, engine.Number.Construct(0)));
            Assert.AreEqual(false, TypeComparer.StrictEquals(false, engine.Number.Construct(1)));

            // Number.
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, Undefined.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, Null.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, false));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, true));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, 0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, 0.0));
            Assert.AreEqual(true, TypeComparer.StrictEquals(5.5, 5.5));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, double.NaN));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, ""));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, " "));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, "5.5"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, "foo"));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, engine.Object.Construct()));
            Assert.AreEqual(false, TypeComparer.StrictEquals(5.5, engine.Number.Construct(5.5)));
            Assert.AreEqual(true, TypeComparer.StrictEquals(0, 0.0));
            Assert.AreEqual(true, TypeComparer.StrictEquals(5, 5.0));
            Assert.AreEqual(false, TypeComparer.StrictEquals(double.NaN, double.NaN));

            // String.
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", Undefined.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", Null.Value));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", false));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", true));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", 0));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", 0.0));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", 5.5));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", double.NaN));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", ""));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", " "));
            Assert.AreEqual(true, TypeComparer.StrictEquals("5.5", "5.5"));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", "foo"));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", engine.Object.Construct()));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", engine.Number.Construct(5.5)));
            Assert.AreEqual(false, TypeComparer.StrictEquals("5.5", engine.String.Construct("5.5")));

            // Object.
            var temp = engine.Object.Construct();

            Assert.AreEqual(true, TypeComparer.StrictEquals(temp, temp));
            Assert.AreEqual(false, TypeComparer.StrictEquals(engine.Object.Construct(), engine.Object.Construct()));
            Assert.AreEqual(false, TypeComparer.StrictEquals(engine.Number.Construct(5.5), engine.Number.Construct(5.5)));
            Assert.AreEqual(false, TypeComparer.StrictEquals(engine.String.Construct("5.5"), engine.String.Construct("5.5")));
        }