From b6307beb6ef581584603f92b2ce4af1382fff646 Mon Sep 17 00:00:00 2001 From: 0xtechnobabble <0xtechnobabble@protonmail.com> Date: Sun, 8 Mar 2020 07:58:58 +0200 Subject: [PATCH] LibJS: Implement if statements If statements execute a certain action or an alternative one depending on whether the tested condition is true or false, this commit helps establish basic control flow capabilities in the AST. --- Libraries/LibJS/AST.cpp | 23 +++++++++++++++++++++++ Libraries/LibJS/AST.h | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index cc2004895a..49bc943ec4 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -61,6 +61,16 @@ Value ReturnStatement::execute(Interpreter& interpreter) const return value; } +Value IfStatement::execute(Interpreter& interpreter) const +{ + auto predicate_result = m_predicate->execute(interpreter); + + if (predicate_result.as_bool()) + return interpreter.run(*m_consequent); + else + return interpreter.run(*m_alternate); +} + Value add(Value lhs, Value rhs) { ASSERT(lhs.is_number()); @@ -236,4 +246,17 @@ void ReturnStatement::dump(int indent) const argument().dump(indent + 1); } +void IfStatement::dump(int indent) const +{ + ASTNode::dump(indent); + + print_indent(indent); + printf("If\n"); + predicate().dump(indent + 1); + consequent().dump(indent + 1); + print_indent(indent); + printf("Else\n"); + alternate().dump(indent + 1); +} + } diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index f200f7e451..1f510e9864 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -127,6 +127,30 @@ private: NonnullOwnPtr m_argument; }; +class IfStatement : public ASTNode { +public: + explicit IfStatement(NonnullOwnPtr predicate, NonnullOwnPtr consequent, NonnullOwnPtr alternate) + : m_predicate(move(predicate)) + , m_consequent(move(consequent)) + , m_alternate(move(alternate)) + { + } + + const Expression& predicate() const { return *m_predicate; } + const ScopeNode& consequent() const { return *m_consequent; } + const ScopeNode& alternate() const { return *m_alternate; } + + virtual Value execute(Interpreter&) const override; + virtual void dump(int indent) const override; + +private: + virtual const char* class_name() const override { return "IfStatement"; } + + NonnullOwnPtr m_predicate; + NonnullOwnPtr m_consequent; + NonnullOwnPtr m_alternate; +}; + enum class BinaryOp { Plus, Minus,