diff options
-rw-r--r-- | Base/home/anon/js/type-play.js | 12 | ||||
-rw-r--r-- | Libraries/LibJS/AST.cpp | 12 | ||||
-rw-r--r-- | Libraries/LibJS/AST.h | 2 | ||||
-rw-r--r-- | Libraries/LibJS/Parser.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibJS/Value.cpp | 31 | ||||
-rw-r--r-- | Libraries/LibJS/Value.h | 1 |
6 files changed, 64 insertions, 2 deletions
diff --git a/Base/home/anon/js/type-play.js b/Base/home/anon/js/type-play.js new file mode 100644 index 0000000000..038841397c --- /dev/null +++ b/Base/home/anon/js/type-play.js @@ -0,0 +1,12 @@ +const object = {}; + +print(true == 1); +print(null == undefined); +print("12" == 12); +print(1 + "12"); +print(12 / "12" == true); +print(2 * "12"); +print(~"24"); +print(~true); +print(2*2 + "4"); +print(object == "[object Object]"); diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index ad3fc2cf1e..a431c6fdac 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -155,7 +155,11 @@ Value BinaryExpression::execute(Interpreter& interpreter) const case BinaryOp::TypedEquals: return typed_eq(lhs_result, rhs_result); case BinaryOp::TypedInequals: - return Value(!typed_eq(lhs_result, rhs_result).to_boolean()); + return Value(!typed_eq(lhs_result, rhs_result).as_bool()); + case BinaryOp::AbstractEquals: + return eq(lhs_result, rhs_result); + case BinaryOp::AbstractInequals: + return Value(!eq(lhs_result, rhs_result).as_bool()); case BinaryOp::GreaterThan: return greater_than(lhs_result, rhs_result); case BinaryOp::GreaterThanEquals: @@ -247,6 +251,12 @@ void BinaryExpression::dump(int indent) const case BinaryOp::TypedInequals: op_string = "!=="; break; + case BinaryOp::AbstractEquals: + op_string = "=="; + break; + case BinaryOp::AbstractInequals: + op_string = "!="; + break; case BinaryOp::GreaterThan: op_string = ">"; break; diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index 575e501139..596b025984 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -248,6 +248,8 @@ enum class BinaryOp { Slash, TypedEquals, TypedInequals, + AbstractEquals, + AbstractInequals, GreaterThan, GreaterThanEquals, LessThan, diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 25982cc590..754b251caa 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -334,6 +334,12 @@ NonnullOwnPtr<Expression> Parser::parse_secondary_expression(NonnullOwnPtr<Expre case TokenType::ExclamationMarkEqualsEquals: consume(); return make<BinaryExpression>(BinaryOp::TypedInequals, move(lhs), parse_expression(min_precedence, associativity)); + case TokenType::EqualsEquals: + consume(); + return make<BinaryExpression>(BinaryOp::AbstractEquals, move(lhs), parse_expression(min_precedence, associativity)); + case TokenType::ExclamationMarkEquals: + consume(); + return make<BinaryExpression>(BinaryOp::AbstractInequals, move(lhs), parse_expression(min_precedence, associativity)); case TokenType::ParenOpen: return parse_call_expression(move(lhs)); case TokenType::Equals: @@ -543,6 +549,8 @@ bool Parser::match_secondary_expression() const || type == TokenType::Equals || type == TokenType::EqualsEqualsEquals || type == TokenType::ExclamationMarkEqualsEquals + || type == TokenType::EqualsEquals + || type == TokenType::ExclamationMarkEquals || type == TokenType::GreaterThan || type == TokenType::GreaterThanEquals || type == TokenType::LessThan diff --git a/Libraries/LibJS/Value.cpp b/Libraries/LibJS/Value.cpp index b9ba4ede1f..ce84a77f74 100644 --- a/Libraries/LibJS/Value.cpp +++ b/Libraries/LibJS/Value.cpp @@ -209,7 +209,7 @@ Value typed_eq(Value lhs, Value rhs) case Value::Type::Number: return Value(lhs.as_double() == rhs.as_double()); case Value::Type::String: - return Value(lhs.as_string() == rhs.as_string()); + return Value(lhs.as_string()->string() == rhs.as_string()->string()); case Value::Type::Boolean: return Value(lhs.as_bool() == rhs.as_bool()); case Value::Type::Object: @@ -219,6 +219,35 @@ Value typed_eq(Value lhs, Value rhs) ASSERT_NOT_REACHED(); } +Value eq(Value lhs, Value rhs) +{ + if (lhs.type() == rhs.type()) + return typed_eq(lhs, rhs); + + if ((lhs.is_undefined() || lhs.is_null()) && (rhs.is_undefined() || rhs.is_null())) + return Value(true); + + if (lhs.is_object() && rhs.is_boolean()) + return eq(lhs.as_object()->to_primitive(), rhs.to_number()); + + if (lhs.is_boolean() && rhs.is_object()) + return eq(lhs.to_number(), rhs.as_object()->to_primitive()); + + if (lhs.is_object()) + return eq(lhs.as_object()->to_primitive(), rhs); + + if (rhs.is_object()) + return eq(lhs, rhs.as_object()->to_primitive()); + + if (lhs.is_number() || rhs.is_number()) + return Value(lhs.to_number().as_double() == rhs.to_number().as_double()); + + if ((lhs.is_string() && rhs.is_boolean()) || (lhs.is_string() && rhs.is_boolean())) + return Value(lhs.to_number().as_double() == rhs.to_number().as_double()); + + return Value(false); +} + const LogStream& operator<<(const LogStream& stream, const Value& value) { return stream << value.to_string(); diff --git a/Libraries/LibJS/Value.h b/Libraries/LibJS/Value.h index 3f06b73e66..ada26761c6 100644 --- a/Libraries/LibJS/Value.h +++ b/Libraries/LibJS/Value.h @@ -174,6 +174,7 @@ Value add(Value lhs, Value rhs); Value sub(Value lhs, Value rhs); Value mul(Value lhs, Value rhs); Value div(Value lhs, Value rhs); +Value eq(Value lhs, Value rhs); Value typed_eq(Value lhs, Value rhs); const LogStream& operator<<(const LogStream&, const Value&); |