mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-13 11:42:38 +03:00
LibJS: Implement abstract equality and inequality
This commit is contained in:
parent
4d22a142f7
commit
dfbaa8e543
Notes:
sideshowbarker
2024-07-19 08:16:45 +09:00
Author: https://github.com/0xtechnobabble Commit: https://github.com/SerenityOS/serenity/commit/dfbaa8e5432 Pull-request: https://github.com/SerenityOS/serenity/pull/1470 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/oriko1010
12
Base/home/anon/js/type-play.js
Normal file
12
Base/home/anon/js/type-play.js
Normal file
@ -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]");
|
@ -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;
|
||||
|
@ -248,6 +248,8 @@ enum class BinaryOp {
|
||||
Slash,
|
||||
TypedEquals,
|
||||
TypedInequals,
|
||||
AbstractEquals,
|
||||
AbstractInequals,
|
||||
GreaterThan,
|
||||
GreaterThanEquals,
|
||||
LessThan,
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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&);
|
||||
|
Loading…
Reference in New Issue
Block a user