diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index b6862f594c..49d7a25e49 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -71,6 +71,16 @@ Value IfStatement::execute(Interpreter& interpreter) const return interpreter.run(*m_alternate); } +Value WhileStatement::execute(Interpreter& interpreter) const +{ + Value last_value = js_undefined(); + while (m_predicate->execute(interpreter).as_bool()) { + last_value = interpreter.run(*m_body); + } + + return last_value; +} + Value add(Value lhs, Value rhs) { ASSERT(lhs.is_number()); @@ -259,4 +269,14 @@ void IfStatement::dump(int indent) const alternate().dump(indent + 1); } +void WhileStatement::dump(int indent) const +{ + ASTNode::dump(indent); + + print_indent(indent); + printf("While\n"); + predicate().dump(indent + 1); + body().dump(indent + 1); +} + } diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index 1f510e9864..b6a4d85560 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -151,6 +151,27 @@ private: NonnullOwnPtr m_alternate; }; +class WhileStatement : public ASTNode { +public: + WhileStatement(NonnullOwnPtr predicate, NonnullOwnPtr body) + : m_predicate(move(predicate)) + , m_body(move(body)) + { + } + + const Expression& predicate() const { return *m_predicate; } + const ScopeNode& body() const { return *m_body; } + + virtual Value execute(Interpreter&) const override; + virtual void dump(int indent) const override; + +private: + virtual const char* class_name() const override { return "WhileStatement"; } + + NonnullOwnPtr m_predicate; + NonnullOwnPtr m_body; +}; + enum class BinaryOp { Plus, Minus,