diff options
author | Itamar <itamar8910@gmail.com> | 2021-03-27 19:19:53 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-06 21:51:58 +0200 |
commit | 1f9f6ea9d64ab412bd5a017c81aebe3602cde3e7 (patch) | |
tree | 8f778408492b7a152c1bde94c2acd7fc566e9756 | |
parent | ee35fc0da31a99d8d5198e9f141cd0b142d461dc (diff) | |
download | serenity-1f9f6ea9d64ab412bd5a017c81aebe3602cde3e7.zip |
LibCpp: Support parsing function qualifiers
-rw-r--r-- | Userland/Libraries/LibCpp/AST.cpp | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/AST.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.cpp | 58 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.h | 2 |
4 files changed, 58 insertions, 10 deletions
diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp index 9243099f90..a928a53afc 100644 --- a/Userland/Libraries/LibCpp/AST.cpp +++ b/Userland/Libraries/LibCpp/AST.cpp @@ -51,6 +51,13 @@ void TranslationUnit::dump(size_t indent) const void FunctionDeclaration::dump(size_t indent) const { ASTNode::dump(indent); + + String qualifiers_string; + if (!m_qualifiers.is_empty()) { + print_indent(indent+1); + outln("[{}]", String::join(" ", m_qualifiers)); + } + m_return_type->dump(indent + 1); if (!m_name.is_null()) { print_indent(indent + 1); diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index 1fab2109ed..1d749e348b 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -171,6 +171,7 @@ public: virtual NonnullRefPtrVector<Declaration> declarations() const override; + Vector<StringView> m_qualifiers; RefPtr<Type> m_return_type; NonnullRefPtrVector<Parameter> m_parameters; RefPtr<FunctionDefinition> m_definition; diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index 647adc9f75..42ca7f04dd 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -142,10 +142,17 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p { auto func = create_ast_node<FunctionDeclaration>(parent, position(), {}); - auto return_type_token = consume(Token::Type::KnownType); + func->m_qualifiers = parse_function_qualifiers(); + func->m_return_type = parse_type(*func); + auto function_name = consume(Token::Type::Identifier); + func->m_name = text_of_token(function_name); + consume(Token::Type::LeftParen); auto parameters = parse_parameter_list(*func); + if (parameters.has_value()) + func->m_parameters = move(parameters.value()); + consume(Token::Type::RightParen); RefPtr<FunctionDefinition> body; @@ -160,10 +167,6 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p consume(Token::Type::Semicolon); } - func->m_name = text_of_token(function_name); - func->m_return_type = create_ast_node<Type>(*func, return_type_token.start(), return_type_token.end(), text_of_token(return_type_token)); - if (parameters.has_value()) - func->m_parameters = move(parameters.value()); func->m_definition = move(body); func->set_end(func_end); return func; @@ -248,9 +251,8 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(ASTNode& parent) return block_statement; } -bool Parser::match_variable_declaration() +bool Parser::match_type() { - SCOPE_LOGGER(); save_state(); ScopeGuard state_guard = [this] { load_state(); }; @@ -258,7 +260,19 @@ bool Parser::match_variable_declaration() // Type if (!peek(Token::Type::KnownType).has_value() && !peek(Token::Type::Identifier).has_value()) return false; - consume(); + return true; +} + +bool Parser::match_variable_declaration() +{ + SCOPE_LOGGER(); + save_state(); + ScopeGuard state_guard = [this] { load_state(); }; + + if (!match_type()) + return false; + VERIFY(m_root_node); + parse_type(*m_root_node); // Identifier if (!peek(Token::Type::Identifier).has_value()) @@ -561,9 +575,12 @@ bool Parser::match_function_declaration() save_state(); ScopeGuard state_guard = [this] { load_state(); }; - if (!peek(Token::Type::KnownType).has_value()) + parse_function_qualifiers(); + + if (!match_type()) return false; - consume(); + VERIFY(m_root_node); + parse_type(*m_root_node); if (!peek(Token::Type::Identifier).has_value()) return false; @@ -1098,6 +1115,27 @@ Vector<StringView> Parser::parse_type_qualifiers() } return qualifiers; } + +Vector<StringView> Parser::parse_function_qualifiers() +{ + SCOPE_LOGGER(); + Vector<StringView> qualifiers; + while (!eof()) { + auto token = peek(); + if (token.type() != Token::Type::Keyword) + break; + auto text = text_of_token(token); + if (text == "static" || text == "inline") { + qualifiers.append(text); + consume(); + } else { + break; + } + } + return qualifiers; +} + + bool Parser::match_attribute_specification() { return text_of_token(peek()) == "__attribute__"; diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 2255fcbc29..2fe0bacd43 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -88,6 +88,7 @@ private: bool match_keyword(const String&); bool match_block_statement(); bool match_namespace_declaration(); + bool match_type(); Optional<NonnullRefPtrVector<Parameter>> parse_parameter_list(ASTNode& parent); Optional<Token> consume_whitespace(); @@ -163,6 +164,7 @@ private: void initialize_program_tokens(const StringView& program); void add_tokens_for_preprocessor(Token& replaced_token, Preprocessor::DefinedValue&); Vector<StringView> parse_type_qualifiers(); + Vector<StringView> parse_function_qualifiers(); Preprocessor::Definitions m_definitions; String m_filename; |