コード例 #1
0
        public bool AreEqualStrict(GlobalContext c)
        {
            if (ReferenceEquals(X, Y))
            {
                return(X != DoubleObj.NaN);
            }

            if (!ReferenceEquals(X.Type, Y.Type))
            {
                return(false);
            }
            Debug.Assert(X != RuntimeObj.Undefined && X != RuntimeObj.Null);

            if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber))
            {
                if (X == DoubleObj.NaN || Y == DoubleObj.NaN)
                {
                    return(false);
                }
                return(X.ToDouble() == Y.ToDouble());
            }
            if (ReferenceEquals(X.Type, RuntimeObj.TypeString))
            {
                return(X.ToString() == Y.ToString());
            }
            if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean))
            {
                return(X.ToBoolean() == Y.ToBoolean());
            }
            return(false);
        }
コード例 #2
0
 public bool AreEqual(GlobalContext c)
 {
     if (ReferenceEquals(X, Y))
     {
         return(X != JSEvalNumber.NaN);
     }
     if (ReferenceEquals(X.Type, Y.Type))
     {
         Debug.Assert(X != RuntimeObj.Undefined && X != RuntimeObj.Null, "This has been handled by the normalization and the above reference test.");
         if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber))
         {
             Debug.Assert(!(((JSEvalNumber)X).IsNaN && ((JSEvalNumber)Y).IsNaN));
             return(X.ToDouble() == Y.ToDouble());
         }
         else if (ReferenceEquals(X.Type, RuntimeObj.TypeString))
         {
             return(X.ToString() == Y.ToString());
         }
         else if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean))
         {
             return(X.ToBoolean() == Y.ToBoolean());
         }
         else
         {
             IComparable cmp;
             if (X.GetType() == Y.GetType() && (cmp = X as IComparable) != null)
             {
                 Debug.Assert((cmp.CompareTo(Y) == 0) == X.Equals(Y), "When IComparable is implemented, it must match Equals behavior.");
                 return(cmp.Equals(Y));
             }
         }
         return(false);
     }
     if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber) && ReferenceEquals(Y.Type, RuntimeObj.TypeString))
     {
         return(X.ToDouble() == Y.ToDouble());
     }
     if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean) || ReferenceEquals(Y.Type, RuntimeObj.TypeBoolean))
     {
         return(X.ToBoolean() == Y.ToBoolean());
     }
     return(false);
 }
コード例 #3
0
 public RuntimeObj CreateString(RuntimeObj o)
 {
     if (o == null)
     {
         return(RuntimeObj.Null);
     }
     if (o is JSEvalString)
     {
         return(o);
     }
     return(CreateString(o.ToString()));
 }
コード例 #4
0
            protected override PExpr DoVisit()
            {
                if (IsPendingOrSignal(ref _left, Expr.Left))
                {
                    return(PendingOrSignal(_left));
                }

                // Do not evaluate right expression if it is useless: short-circuit boolean evaluation.
                if ((Expr.BinaryOperatorToken == JSTokenizerToken.And && !_left.Result.ToBoolean()) ||
                    (Expr.BinaryOperatorToken == JSTokenizerToken.Or && _left.Result.ToBoolean()))
                {
                    return(SetResult(_left.Result));
                }

                if (IsPendingOrSignal(ref _right, Expr.Right))
                {
                    return(PendingOrSignal(_right));
                }

                RuntimeObj left  = _left.Result;
                RuntimeObj right = _right.Result;

                // Right value is the result for And and Or.
                RuntimeObj result = right;

                if (Expr.BinaryOperatorToken != JSTokenizerToken.And && Expr.BinaryOperatorToken != JSTokenizerToken.Or)
                {
                    if ((Expr.BinaryOperatorToken & JSTokenizerToken.IsCompareOperator) != 0)
                    {
                        #region ==, <, >, <=, >=, !=, === and !==
                        int compareValue;
                        switch ((int)Expr.BinaryOperatorToken & 15)
                        {
                        case (int)JSTokenizerToken.StrictEqual & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).AreEqualStrict(Global));
                            break;
                        }

                        case (int)JSTokenizerToken.StrictDifferent & 15:
                        {
                            result = Global.CreateBoolean(!new RuntimeObjComparer(left, right).AreEqualStrict(Global));
                            break;
                        }

                        case (int)JSTokenizerToken.Greater & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue > 0);
                            break;
                        }

                        case (int)JSTokenizerToken.GreaterOrEqual & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue >= 0);
                            break;
                        }

                        case (int)JSTokenizerToken.Less & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue < 0);
                            break;
                        }

                        case (int)JSTokenizerToken.LessOrEqual & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue <= 0);
                            break;
                        }

                        case (int)JSTokenizerToken.Equal & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).AreEqual(Global));
                            break;
                        }

                        case (int)JSTokenizerToken.Different & 15:
                        {
                            result = Global.CreateBoolean(!new RuntimeObjComparer(left, right).AreEqual(Global));
                            break;
                        }

                        default: throw UnsupportedOperatorException();
                        }
                        #endregion
                    }
                    else if ((Expr.BinaryOperatorToken & JSTokenizerToken.IsBinaryOperator) != 0)
                    {
                        #region |, ^, &, >>, <<, >>>, +, -, /, * and %.
                        switch ((int)Expr.BinaryOperatorToken & 15)
                        {
                        case (int)JSTokenizerToken.Plus & 15:
                        {
                            if (ReferenceEquals(left.Type, RuntimeObj.TypeNumber) && ReferenceEquals(right.Type, RuntimeObj.TypeNumber))
                            {
                                result = Global.CreateNumber(left.ToDouble() + right.ToDouble());
                            }
                            else
                            {
                                result = Global.CreateString(String.Concat(left.ToString(), right.ToString()));
                            }
                            break;
                        }

                        case (int)JSTokenizerToken.Minus & 15:
                        {
                            result = Global.CreateNumber(left.ToDouble() - right.ToDouble());
                            break;
                        }

                        case (int)JSTokenizerToken.Mult & 15:
                        {
                            result = Global.CreateNumber(left.ToDouble() * right.ToDouble());
                            break;
                        }

                        case (int)JSTokenizerToken.Divide & 15:
                        {
                            result = Global.CreateNumber(left.ToDouble() / right.ToDouble());
                            break;
                        }

                        case (int)JSTokenizerToken.Modulo & 15:
                        {
                            if (right == JSEvalNumber.Zero || left == JSEvalNumber.NegativeInfinity || left == JSEvalNumber.Infinity)
                            {
                                result = JSEvalNumber.NaN;
                            }
                            else if (left == JSEvalNumber.NegativeInfinity || left == JSEvalNumber.Infinity)
                            {
                                result = right;
                            }
                            else
                            {
                                result = Global.CreateNumber(left.ToDouble() % right.ToDouble());
                            }
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseAnd & 15:
                        {
                            Int64 l  = JSSupport.ToInt64(left.ToDouble());
                            Int64 rO = JSSupport.ToInt64(right.ToDouble());
                            result = Global.CreateNumber(l & rO);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseOr & 15:
                        {
                            Int64 l  = JSSupport.ToInt64(left.ToDouble());
                            Int64 rO = JSSupport.ToInt64(right.ToDouble());
                            result = Global.CreateNumber(l | rO);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseXOr & 15:
                        {
                            Int64 l  = JSSupport.ToInt64(left.ToDouble());
                            Int64 rO = JSSupport.ToInt64(right.ToDouble());
                            result = Global.CreateNumber(l ^ rO);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseShiftLeft & 15:
                        {
                            result = BitwiseShift(left, right, false);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseShiftRight & 15:
                        {
                            result = BitwiseShift(left, right, true);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseShiftRightNoSignBit & 15:
                        {
                            result = BitwiseShiftRightUnsigned(left, right);
                            break;
                        }

                        default: throw UnsupportedOperatorException();
                        }
                        #endregion
                    }
                    else
                    {
                        throw UnsupportedOperatorException();
                    }
                }
                return(SetResult(result));
            }
コード例 #5
0
 public RuntimeObj CreateString( RuntimeObj o )
 {
     if( o == null ) return RuntimeObj.Null;
     if( o is JSEvalString ) return o;
     return CreateString( o.ToString() );
 }
コード例 #6
0
 public override string ToString() => _value.ToString();
コード例 #7
0
 public override string ToString()
 {
     return(_value.ToString());
 }