diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index f6c9847bb3..591301b257 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -91,8 +91,11 @@ Value IfStatement::execute(Interpreter& interpreter) const if (predicate_result.to_boolean()) return interpreter.run(*m_consequent); - else + + if (m_alternate) return interpreter.run(*m_alternate); + + return js_undefined(); } Value WhileStatement::execute(Interpreter& interpreter) const @@ -427,9 +430,11 @@ void IfStatement::dump(int indent) const printf("If\n"); predicate().dump(indent + 1); consequent().dump(indent + 1); - print_indent(indent); - printf("Else\n"); - alternate().dump(indent + 1); + if (alternate()) { + print_indent(indent); + printf("Else\n"); + alternate()->dump(indent + 1); + } } void WhileStatement::dump(int indent) const diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index a1bac10849..2ff6a06722 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -211,7 +211,7 @@ private: class IfStatement : public Statement { public: - IfStatement(NonnullRefPtr predicate, NonnullRefPtr consequent, NonnullRefPtr alternate) + IfStatement(NonnullRefPtr predicate, NonnullRefPtr consequent, RefPtr alternate) : m_predicate(move(predicate)) , m_consequent(move(consequent)) , m_alternate(move(alternate)) @@ -220,7 +220,7 @@ public: const Expression& predicate() const { return *m_predicate; } const ScopeNode& consequent() const { return *m_consequent; } - const ScopeNode& alternate() const { return *m_alternate; } + const ScopeNode* alternate() const { return m_alternate; } virtual Value execute(Interpreter&) const override; virtual void dump(int indent) const override; @@ -230,7 +230,7 @@ private: NonnullRefPtr m_predicate; NonnullRefPtr m_consequent; - NonnullRefPtr m_alternate; + RefPtr m_alternate; }; class WhileStatement : public Statement { diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index badcd97268..7ef64a3d2b 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -194,6 +194,8 @@ NonnullRefPtr Parser::parse_statement() return parse_variable_declaration(); case TokenType::For: return parse_for_statement(); + case TokenType::If: + return parse_if_statement(); default: if (match_expression()) return adopt(*new ExpressionStatement(parse_expression(0))); @@ -512,6 +514,17 @@ NonnullRefPtr Parser::parse_variable_declaration() return create_ast_node(create_ast_node(name), move(initializer), declaration_type); } +NonnullRefPtr Parser::parse_if_statement() +{ + consume(TokenType::If); + consume(TokenType::ParenOpen); + auto predicate = parse_expression(0); + consume(TokenType::ParenClose); + auto consequent = parse_block_statement(); + // FIXME: Parse "else" + return create_ast_node(move(predicate), move(consequent), nullptr); +} + NonnullRefPtr Parser::parse_for_statement() { consume(TokenType::For); diff --git a/Libraries/LibJS/Parser.h b/Libraries/LibJS/Parser.h index 746e599578..e7b3833d47 100644 --- a/Libraries/LibJS/Parser.h +++ b/Libraries/LibJS/Parser.h @@ -51,6 +51,7 @@ public: NonnullRefPtr parse_return_statement(); NonnullRefPtr parse_variable_declaration(); NonnullRefPtr parse_for_statement(); + NonnullRefPtr parse_if_statement(); NonnullRefPtr parse_expression(int min_precedence, Associativity associate = Associativity::Right); NonnullRefPtr parse_primary_expression();