summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-01-29 12:03:02 +0200
committerAndreas Kling <kling@serenityos.org>2021-02-08 23:10:38 +0100
commit8ed65d7b486fdee170e98f727f2788769cb9c406 (patch)
tree0a85db082b8e6a347829295fbbbb01deaf4e0006
parente8f040139b8a8aef4b223a857b8e8ab0acb516b2 (diff)
downloadserenity-8ed65d7b486fdee170e98f727f2788769cb9c406.zip
LibCpp: Parse If statements
-rw-r--r--Userland/Libraries/LibCpp/AST.cpp28
-rw-r--r--Userland/Libraries/LibCpp/AST.h18
-rw-r--r--Userland/Libraries/LibCpp/Parser.cpp23
-rw-r--r--Userland/Libraries/LibCpp/Parser.h1
4 files changed, 70 insertions, 0 deletions
diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp
index a2b6db8cfe..b19689baab 100644
--- a/Userland/Libraries/LibCpp/AST.cpp
+++ b/Userland/Libraries/LibCpp/AST.cpp
@@ -379,4 +379,32 @@ NonnullRefPtrVector<Declaration> BlockStatement::declarations() const
return declarations;
}
+void IfStatement::dump(size_t indent) const
+{
+ ASTNode::dump(indent);
+ if (m_predicate) {
+ print_indent(indent + 1);
+ dbgprintf("Predicate:\n");
+ m_predicate->dump(indent + 1);
+ }
+ if (m_then) {
+ print_indent(indent + 1);
+ dbgprintf("Then:\n");
+ m_then->dump(indent + 1);
+ }
+ if (m_else) {
+ print_indent(indent + 1);
+ dbgprintf("Else:\n");
+ m_else->dump(indent + 1);
+ }
+}
+
+NonnullRefPtrVector<Declaration> IfStatement::declarations() const
+{
+ NonnullRefPtrVector<Declaration> declarations;
+ declarations.append(m_predicate->declarations());
+ declarations.append(m_then->declarations());
+ declarations.append(m_else->declarations());
+ return declarations;
+}
}
diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h
index 38a1f87824..62dfacf764 100644
--- a/Userland/Libraries/LibCpp/AST.h
+++ b/Userland/Libraries/LibCpp/AST.h
@@ -581,4 +581,22 @@ public:
virtual ~Comment() override = default;
virtual const char* class_name() const override { return "Comment"; }
};
+
+class IfStatement : public Statement {
+public:
+ IfStatement(ASTNode* parent, Optional<Position> start, Optional<Position> end)
+ : Statement(parent, start, end)
+ {
+ }
+
+ virtual ~IfStatement() override = default;
+ virtual const char* class_name() const override { return "IfStatement"; }
+ virtual void dump(size_t indent) const override;
+ virtual NonnullRefPtrVector<Declaration> declarations() const override;
+
+ RefPtr<Expression> m_predicate;
+ RefPtr<Statement> m_then;
+ RefPtr<Statement> m_else;
+};
+
}
diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp
index a3447d1b61..d9a5c8cc98 100644
--- a/Userland/Libraries/LibCpp/Parser.cpp
+++ b/Userland/Libraries/LibCpp/Parser.cpp
@@ -186,6 +186,10 @@ NonnullRefPtr<Statement> Parser::parse_statement(ASTNode& parent)
if (match_keyword("for")) {
consume_semicolumn.disarm();
return parse_for_statement(parent);
+ }
+ if (match_keyword("if")) {
+ consume_semicolumn.disarm();
+ return parse_if_statement(parent);
} else {
error("unexpected statement type");
consume_semicolumn.disarm();
@@ -997,4 +1001,23 @@ NonnullRefPtr<ForStatement> Parser::parse_for_statement(ASTNode& parent)
return for_statement;
}
+NonnullRefPtr<IfStatement> Parser::parse_if_statement(ASTNode& parent)
+{
+ SCOPE_LOGGER();
+ auto if_statement = create_ast_node<IfStatement>(parent, position(), {});
+ consume(Token::Type::Keyword);
+ consume(Token::Type::LeftParen);
+ if_statement->m_predicate = parse_expression(*if_statement);
+ consume(Token::Type::RightParen);
+ if_statement->m_then = parse_statement(*if_statement);
+ if (match_keyword("else")) {
+ consume(Token::Type::Keyword);
+ if_statement->m_else = parse_statement(*if_statement);
+ if_statement->set_end(if_statement->m_else->end());
+ } else {
+ if_statement->set_end(if_statement->m_then->end());
+ }
+ return if_statement;
+}
+
}
diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h
index 013d1ff697..b12c1a50a0 100644
--- a/Userland/Libraries/LibCpp/Parser.h
+++ b/Userland/Libraries/LibCpp/Parser.h
@@ -104,6 +104,7 @@ private:
NonnullRefPtr<ForStatement> parse_for_statement(ASTNode& parent);
NonnullRefPtr<BlockStatement> parse_block_statement(ASTNode& parent);
NonnullRefPtr<Comment> parse_comment(ASTNode& parent);
+ NonnullRefPtr<IfStatement> parse_if_statement(ASTNode& parent);
bool match(Token::Type);
Token consume(Token::Type);