Browse Source

LibJS: Implement logical expressions

Logical expressions are expressions which can return either true or
false according to a provided condition.
0xtechnobabble 5 years ago
parent
commit
a96bf2c22e
2 changed files with 68 additions and 0 deletions
  1. 34 0
      Libraries/LibJS/AST.cpp
  2. 34 0
      Libraries/LibJS/AST.h

+ 34 - 0
Libraries/LibJS/AST.cpp

@@ -114,6 +114,22 @@ Value BinaryExpression::execute(Interpreter& interpreter) const
 
 
     ASSERT_NOT_REACHED();
     ASSERT_NOT_REACHED();
 }
 }
+
+Value LogicalExpression::execute(Interpreter& interpreter) const
+{
+    auto lhs_result = m_lhs->execute(interpreter).as_bool();
+
+    if (m_op == LogicalOp::Not)
+        return Value(!lhs_result);
+
+    auto rhs_result = m_rhs->execute(interpreter).as_bool();
+    switch (m_op) {
+    case LogicalOp::And:
+        return Value(lhs_result && rhs_result);
+    case LogicalOp::Or:
+        return Value(lhs_result || rhs_result);
+    case LogicalOp::Not:
+        ASSERT_NOT_REACHED();
     }
     }
 
 
     ASSERT_NOT_REACHED();
     ASSERT_NOT_REACHED();
@@ -161,6 +177,24 @@ void BinaryExpression::dump(int indent) const
     m_rhs->dump(indent + 1);
     m_rhs->dump(indent + 1);
 }
 }
 
 
+void LogicalExpression::dump(int indent) const
+{
+    const char* op_string = nullptr;
+    switch (m_op) {
+    case LogicalOp::And:
+        op_string = "&&";
+        break;
+    case LogicalOp::Or:
+        op_string = "||";
+        break;
+    case LogicalOp::Not:
+        op_string = "!";
+        print_indent(indent);
+        printf("%s\n", class_name());
+        print_indent(indent + 1);
+        printf("%s\n", op_string);
+        m_lhs->dump(indent + 1);
+        return;
     }
     }
 
 
     print_indent(indent);
     print_indent(indent);

+ 34 - 0
Libraries/LibJS/AST.h

@@ -27,6 +27,7 @@
 #pragma once
 #pragma once
 
 
 #include <AK/NonnullOwnPtrVector.h>
 #include <AK/NonnullOwnPtrVector.h>
+#include <AK/OwnPtr.h>
 #include <AK/String.h>
 #include <AK/String.h>
 #include <LibJS/Forward.h>
 #include <LibJS/Forward.h>
 #include <LibJS/Value.h>
 #include <LibJS/Value.h>
@@ -152,6 +153,39 @@ private:
     NonnullOwnPtr<Expression> m_rhs;
     NonnullOwnPtr<Expression> m_rhs;
 };
 };
 
 
+enum class LogicalOp {
+    And,
+    Or,
+    Not
+};
+
+class LogicalExpression : public Expression {
+public:
+    LogicalExpression(LogicalOp op, NonnullOwnPtr<Expression> lhs, NonnullOwnPtr<Expression> rhs)
+        : m_op(op)
+        , m_lhs(move(lhs))
+        , m_rhs(move(rhs))
+    {
+    }
+
+    LogicalExpression(LogicalOp op, NonnullOwnPtr<Expression> lhs)
+        : m_op(op)
+        , m_lhs(move(lhs))
+    {
+        ASSERT(op == LogicalOp::Not);
+    }
+
+    virtual Value execute(Interpreter&) const override;
+    virtual void dump(int indent) const override;
+
+private:
+    virtual const char* class_name() const override { return "LogicalExpression"; }
+
+    LogicalOp m_op;
+    NonnullOwnPtr<Expression> m_lhs;
+    OwnPtr<Expression> m_rhs;
+};
+
 class Literal : public Expression {
 class Literal : public Expression {
 public:
 public:
     explicit Literal(Value value)
     explicit Literal(Value value)