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)); } }
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); }
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); } } }
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"); } }
public override double ToNumber() { return(JsBoolean.BooleanToNumber(this.value)); }