Inheritance: JsObject, ILiteral
Esempio n. 1
0
        public override double ToNumber()
        {
            if (this.Value == null)
            {
                return(0.0);
            }
            if (!(this.Value is IConvertible))
            {
                return(double.NaN);
            }
            switch (Convert.GetTypeCode(this.Value))
            {
            case TypeCode.Boolean:
                return(JsBoolean.BooleanToNumber((bool)this.Value));

            case TypeCode.Char:
            case TypeCode.String:
                return(JsString.StringToNumber((string)this.Value));

            case TypeCode.DateTime:
                return(JsDate.DateToDouble((DateTime)this.Value));

            default:
                return(Convert.ToDouble(this.Value));
            }
        }
Esempio n. 2
0
 public JsBooleanConstructor(IGlobal global)
     : base(global)
 {
     this.Name = "Boolean";
     this.DefineOwnProperty(JsFunction.PROTOTYPE, (JsInstance)global.ObjectClass.New((JsFunction)this), PropertyAttributes.ReadOnly | PropertyAttributes.DontEnum | PropertyAttributes.DontDelete);
     this.True  = this.New(true);
     this.False = this.New(false);
 }
        public JsBooleanConstructor(IGlobal global)
            : base(global) {
            Name = "Boolean";

            DefineOwnProperty(PROTOTYPE, global.ObjectClass.New(this), PropertyAttributes.DontEnum | PropertyAttributes.DontDelete | PropertyAttributes.ReadOnly);

            True = New(true);
            False = New(false);
        }
Esempio n. 4
0
        public JsBooleanConstructor(IGlobal global)
            : base(global)
        {
            Name = "Boolean";

            DefineOwnProperty(PROTOTYPE, global.ObjectClass.New(this), PropertyAttributes.DontEnum | PropertyAttributes.DontDelete | PropertyAttributes.ReadOnly);

            True  = New(true);
            False = New(false);
        }
Esempio n. 5
0
        public override double ToNumber()
        {
            if (Value == null)
            {
                return(0);
            }

            switch (Convert.GetTypeCode(Value))
            {
            case TypeCode.Boolean:
                return(JsBoolean.BooleanToNumber((bool)Value));

            case TypeCode.Char:
            case TypeCode.String:
                return(JsString.StringToNumber((string)Value));

            case TypeCode.DateTime:
                return(JsDate.DateToDouble((DateTime)Value));

            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.SByte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Single:
                return(Convert.ToDouble(Value));

            case TypeCode.Object:
                return(Convert.ToDouble(Value));

            case TypeCode.DBNull:
            case TypeCode.Empty:
            default:
                if (value is IConvertible)
                {
                    return(Convert.ToDouble(Value));
                }
                else
                {
                    return(double.NaN);
                }
            }
        }
Esempio n. 6
0
        public void Visit(BinaryExpression expression)
        {
            JsInstance old = Result;

            // Evaluates the left expression and saves the value
            expression.LeftExpression.Accept(this);
            JsInstance left = Result;

            //prevents execution of the right hand side if false
            if (expression.Type == BinaryExpressionType.And && !left.ToBoolean())
            {
                Result = left;
                return;
            }

            //prevents execution of the right hand side if true
            if (expression.Type == BinaryExpressionType.Or && left.ToBoolean())
            {
                Result = left;
                return;
            }

            Result = null;

            // Evaluates the right expression and saves the value
            expression.RightExpression.Accept(this);
            JsInstance right = Result;

            Result = old;

            switch (expression.Type)
            {
                case BinaryExpressionType.And:

                    if (left.ToBoolean())
                    {
                        Result = right;
                    }
                    else
                    {
                        Result = JsBoolean.False;
                    }

                    break;

                case BinaryExpressionType.Or:
                    if (left.ToBoolean())
                    {
                        Result = left;
                    }
                    else
                    {
                        Result = right;
                    }

                    break;

                case BinaryExpressionType.Div:
                    var rightNumber = right.ToNumber();
                    var leftNumber = left.ToNumber();

                    if (right == Global.NumberClass["NEGATIVE_INFINITY"] || right == Global.NumberClass["POSITIVE_INFINITY"])
                    {
                        Result = new JsNumber(0);
                    }
                    else if (rightNumber == 0)
                    {
                        Result = leftNumber > 0 ? Global.NumberClass["POSITIVE_INFINITY"] : Global.NumberClass["NEGATIVE_INFINITY"];
                    }
                    else
                    {
                        Result = Global.NumberClass.New(leftNumber / rightNumber);
                    }
                    break;

                case BinaryExpressionType.Equal:
                    if (left == JsUndefined.Instance && right == JsUndefined.Instance || left == JsNull.Instance && right == JsNull.Instance)
                    {
                        Result = JsBoolean.True;
                    }
                    else
                    {
                        if (left == JsUndefined.Instance && right != JsUndefined.Instance || left == JsNull.Instance && right != JsNull.Instance)
                        {
                            Result = JsBoolean.False;
                        }
                        else
                            if (left != JsUndefined.Instance && right == JsUndefined.Instance || left != JsNull.Instance && right == JsNull.Instance)
                            {
                                Result = JsBoolean.False;
                            }
                            else
                            {
                                if (left.Class == JsNumber.TYPEOF || left.Class == JsBoolean.TYPEOF ||
                                    right.Class == JsNumber.TYPEOF || right.Class == JsBoolean.TYPEOF)
                                {
                                    Result = Global.BooleanClass.New(left.ToNumber() == right.ToNumber());
                                }
                                else if (left.Class == JsString.TYPEOF || right.Class == JsString.TYPEOF)
                                {
                                    Result = Global.BooleanClass.New(left.ToString() == right.ToString());
                                }
                                else if (left.Value != null)
                                {
                                    Result = Global.BooleanClass.New(left.Value.Equals(right.Value));
                                }
                                else
                                {
                                    Result = Global.BooleanClass.New(left == right);
                                }
                            }

                    }
                    break;

                case BinaryExpressionType.Greater:
                    // Use the type of the left operand to make the comparison
                    Result = Global.BooleanClass.New(left.ToNumber() > right.ToNumber());
                    break;

                case BinaryExpressionType.GreaterOrEqual:
                    // Use the type of the left operand to make the comparison
                    Result = Global.BooleanClass.New(left.ToNumber() >= right.ToNumber());
                    break;

                case BinaryExpressionType.Lesser:
                    // Use the type of the left operand to make the comparison
                    Result = Global.BooleanClass.New(left.ToNumber() < right.ToNumber());
                    break;

                case BinaryExpressionType.LesserOrEqual:
                    // Use the type of the left operand to make the comparison
                    Result = Global.BooleanClass.New(left.ToNumber() <= right.ToNumber());
                    break;

                case BinaryExpressionType.Minus:
                    Result = Global.NumberClass.New(left.ToNumber() - right.ToNumber());
                    break;

                case BinaryExpressionType.Modulo:
                    if (right == Global.NumberClass["NEGATIVE_INFINITY"] || right == Global.NumberClass["POSITIVE_INFINITY"])
                    {
                        Result = Global.NumberClass["POSITIVE_INFINITY"];
                    }
                    else if (right.ToNumber() == 0)
                    {
                        Result = Global.NumberClass["NaN"];
                    }
                    else
                    {
                        Result = Global.NumberClass.New(left.ToNumber() % right.ToNumber());
                    }
                    break;

                case BinaryExpressionType.NotEqual:

                    if (left == JsUndefined.Instance && right == JsUndefined.Instance || left == JsNull.Instance && right == JsNull.Instance)
                    {
                        Result = JsBoolean.False;
                    }
                    else
                    {
                        if (left == JsUndefined.Instance && right != JsUndefined.Instance || left == JsNull.Instance && right != JsNull.Instance)
                        {
                            Result = JsBoolean.True;
                        }
                        else
                            if (left != JsUndefined.Instance && right == JsUndefined.Instance || left != JsNull.Instance && right == JsNull.Instance)
                            {
                                Result = JsBoolean.True;
                            }
                            else
                            {
                                Result = Global.BooleanClass.New(!left.Value.Equals(right.Value));
                            }
                    }
                    break;

                case BinaryExpressionType.Plus:
                    if (left.Class == JsString.TYPEOF || right.Class == JsString.TYPEOF)
                    {
                        Result = Global.StringClass.New(String.Concat(left.ToString(), right.ToString()));
                    }
                    else
                    {
                        Result = Global.NumberClass.New(left.ToNumber() + right.ToNumber());
                    }
                    break;

                case BinaryExpressionType.Times:
                    Result = Global.NumberClass.New(left.ToNumber() * right.ToNumber());
                    break;

                case BinaryExpressionType.Pow:
                    Result = Global.NumberClass.New(Math.Pow(left.ToNumber(), right.ToNumber()));
                    break;

                case BinaryExpressionType.BitwiseAnd:
                    Result = Global.NumberClass.New(Convert.ToUInt64(left.ToNumber()) & Convert.ToUInt64(right.ToNumber()));
                    break;

                case BinaryExpressionType.BitwiseOr:
                    Result = Global.NumberClass.New(Convert.ToUInt64(left.ToNumber()) | Convert.ToUInt64(right.ToNumber()));
                    break;

                case BinaryExpressionType.BitwiseXOr:
                    Result = Global.NumberClass.New(Convert.ToUInt64(left.ToNumber()) ^ Convert.ToUInt64(right.ToNumber()));
                    break;

                case BinaryExpressionType.Same:
                    // 11.9.6 The Strict Equality Comparison Algorithm
                    if (left.Class != right.Class)
                    {
                        Result = JsBoolean.False;
                    }
                    else if (left.Class == JsUndefined.TYPEOF)
                    {
                        Result = JsBoolean.True;
                    }
                    else if (left.Class == JsNull.TYPEOF)
                    {
                        Result = JsBoolean.True;
                    }
                    else if (left.Class == JsNumber.TYPEOF)
                    {
                        if (left == Global.NumberClass["NaN"] || right == Global.NumberClass["NaN"])
                        {
                            Result = JsBoolean.False;
                        }
                        else if (left.ToNumber() == right.ToNumber())
                        {
                            Result = JsBoolean.True;
                        }
                        else
                            Result = JsBoolean.False;
                    }
                    else if (left.Class == JsString.TYPEOF)
                    {
                        Result = new JsBoolean(left.ToString() == right.ToString());
                    }
                    else if (left.Class == JsBoolean.TYPEOF)
                    {
                        Result = new JsBoolean(left.ToBoolean() == right.ToBoolean());
                    }
                    else if (left == right)
                    {
                        Result = JsBoolean.True;
                    }
                    else
                    {
                        Result = JsBoolean.False;
                    }

                    break;

                case BinaryExpressionType.NotSame:
                    new BinaryExpression(BinaryExpressionType.Same, expression.LeftExpression, expression.RightExpression).Accept(this);
                    Result = new JsBoolean(!Result.ToBoolean());
                    break;

                case BinaryExpressionType.LeftShift:
                    Result = Global.NumberClass.New(Convert.ToUInt64(left.ToNumber()) << Convert.ToUInt16(right.ToNumber()));
                    break;

                case BinaryExpressionType.RightShift:
                    Result = Global.NumberClass.New(Convert.ToUInt64(left.ToNumber()) >> Convert.ToUInt16(right.ToNumber()));
                    break;

                case BinaryExpressionType.UnsignedRightShift:
                    Result = Global.NumberClass.New(Convert.ToUInt64(left.ToNumber()) >> Convert.ToUInt16(right.ToNumber()));
                    break;

                case BinaryExpressionType.InstanceOf:
                    Result = new JsBoolean(left.Class == right.ToString());
                    break;

                case BinaryExpressionType.In:
                    if (right is JsDictionaryObject)
                    {
                        ((JsDictionaryObject)right).HasProperty(left);
                    }
                    else
                    {
                        throw new JintException("Cannot apply 'in' operator to the specified member.");
                    }

                    break;

                default:
                    throw new NotSupportedException("Unkown binary operator");
            }
        }
Esempio n. 7
0
 public override double ToNumber()
 {
     return(JsBoolean.BooleanToNumber(this.value));
 }