1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:07:35 +00:00

LibJS: Implement basic boolean coercion

We can't expect the conditionals in "if" and "while" statements to
always return a bool, so we need to know how to boolify a JS::Value.
This commit is contained in:
Andreas Kling 2020-03-10 08:46:20 +01:00
parent 386867da9f
commit dc0b091c31
3 changed files with 24 additions and 5 deletions

View file

@ -70,7 +70,7 @@ Value IfStatement::execute(Interpreter& interpreter) const
{ {
auto predicate_result = m_predicate->execute(interpreter); auto predicate_result = m_predicate->execute(interpreter);
if (predicate_result.as_bool()) if (predicate_result.to_boolean())
return interpreter.run(*m_consequent); return interpreter.run(*m_consequent);
else else
return interpreter.run(*m_alternate); return interpreter.run(*m_alternate);
@ -79,7 +79,7 @@ Value IfStatement::execute(Interpreter& interpreter) const
Value WhileStatement::execute(Interpreter& interpreter) const Value WhileStatement::execute(Interpreter& interpreter) const
{ {
Value last_value = js_undefined(); Value last_value = js_undefined();
while (m_predicate->execute(interpreter).as_bool()) { while (m_predicate->execute(interpreter).to_boolean()) {
last_value = interpreter.run(*m_body); last_value = interpreter.run(*m_body);
} }
@ -213,9 +213,8 @@ Value BinaryExpression::execute(Interpreter& interpreter) const
Value LogicalExpression::execute(Interpreter& interpreter) const Value LogicalExpression::execute(Interpreter& interpreter) const
{ {
auto lhs_result = m_lhs->execute(interpreter).as_bool(); auto lhs_result = m_lhs->execute(interpreter).to_boolean();
auto rhs_result = m_rhs->execute(interpreter).to_boolean();
auto rhs_result = m_rhs->execute(interpreter).as_bool();
switch (m_op) { switch (m_op) {
case LogicalOp::And: case LogicalOp::And:
return Value(lhs_result && rhs_result); return Value(lhs_result && rhs_result);

View file

@ -53,6 +53,25 @@ String Value::to_string() const
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
bool Value::to_boolean() const
{
switch (m_type) {
case Type::Boolean:
return m_value.as_bool;
case Type::Number:
return m_value.as_double == 0 || m_value.as_double == -0;
case Type::Null:
case Type::Undefined:
return false;
case Type::String:
return String(as_string()).is_empty();
case Type::Object:
return true;
default:
ASSERT_NOT_REACHED();
}
}
const LogStream& operator<<(const LogStream& stream, const Value& value) const LogStream& operator<<(const LogStream& stream, const Value& value)
{ {
return stream << value.to_string(); return stream << value.to_string();

View file

@ -113,6 +113,7 @@ public:
} }
String to_string() const; String to_string() const;
bool to_boolean() const;
private: private:
Type m_type { Type::Undefined }; Type m_type { Type::Undefined };