summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author0xtechnobabble <0xtechnobabble@protonmail.com>2020-03-08 07:55:44 +0200
committerAndreas Kling <kling@serenityos.org>2020-03-08 11:15:07 +0100
commita96bf2c22e80581b173285dbd71b9c29e78dfaed (patch)
tree6674aeb7c8a4a808eea4335befd4747b4af2779b
parent4e62dcd6e695740ff0e1e09b69d09713b473e9a7 (diff)
downloadserenity-a96bf2c22e80581b173285dbd71b9c29e78dfaed.zip
LibJS: Implement logical expressions
Logical expressions are expressions which can return either true or false according to a provided condition.
-rw-r--r--Libraries/LibJS/AST.cpp34
-rw-r--r--Libraries/LibJS/AST.h34
2 files changed, 68 insertions, 0 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp
index 1b8a666d31..cc2004895a 100644
--- a/Libraries/LibJS/AST.cpp
+++ b/Libraries/LibJS/AST.cpp
@@ -114,6 +114,22 @@ Value BinaryExpression::execute(Interpreter& interpreter) const
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();
@@ -161,6 +177,24 @@ void BinaryExpression::dump(int indent) const
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);
diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h
index 6d8fbd66c8..f200f7e451 100644
--- a/Libraries/LibJS/AST.h
+++ b/Libraries/LibJS/AST.h
@@ -27,6 +27,7 @@
#pragma once
#include <AK/NonnullOwnPtrVector.h>
+#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <LibJS/Forward.h>
#include <LibJS/Value.h>
@@ -152,6 +153,39 @@ private:
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 {
public:
explicit Literal(Value value)