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:
parent
386867da9f
commit
dc0b091c31
3 changed files with 24 additions and 5 deletions
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue