diff options
author | 0xtechnobabble <0xtechnobabble@protonmail.com> | 2020-03-08 07:55:44 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-08 11:15:07 +0100 |
commit | a96bf2c22e80581b173285dbd71b9c29e78dfaed (patch) | |
tree | 6674aeb7c8a4a808eea4335befd4747b4af2779b | |
parent | 4e62dcd6e695740ff0e1e09b69d09713b473e9a7 (diff) | |
download | serenity-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.cpp | 34 | ||||
-rw-r--r-- | Libraries/LibJS/AST.h | 34 |
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) |