mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:17:35 +00:00
LibCpp: Support parsing function qualifiers
This commit is contained in:
parent
ee35fc0da3
commit
1f9f6ea9d6
4 changed files with 58 additions and 10 deletions
|
@ -51,6 +51,13 @@ void TranslationUnit::dump(size_t indent) const
|
||||||
void FunctionDeclaration::dump(size_t indent) const
|
void FunctionDeclaration::dump(size_t indent) const
|
||||||
{
|
{
|
||||||
ASTNode::dump(indent);
|
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);
|
m_return_type->dump(indent + 1);
|
||||||
if (!m_name.is_null()) {
|
if (!m_name.is_null()) {
|
||||||
print_indent(indent + 1);
|
print_indent(indent + 1);
|
||||||
|
|
|
@ -171,6 +171,7 @@ public:
|
||||||
|
|
||||||
virtual NonnullRefPtrVector<Declaration> declarations() const override;
|
virtual NonnullRefPtrVector<Declaration> declarations() const override;
|
||||||
|
|
||||||
|
Vector<StringView> m_qualifiers;
|
||||||
RefPtr<Type> m_return_type;
|
RefPtr<Type> m_return_type;
|
||||||
NonnullRefPtrVector<Parameter> m_parameters;
|
NonnullRefPtrVector<Parameter> m_parameters;
|
||||||
RefPtr<FunctionDefinition> m_definition;
|
RefPtr<FunctionDefinition> m_definition;
|
||||||
|
|
|
@ -142,10 +142,17 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p
|
||||||
{
|
{
|
||||||
auto func = create_ast_node<FunctionDeclaration>(parent, position(), {});
|
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);
|
auto function_name = consume(Token::Type::Identifier);
|
||||||
|
func->m_name = text_of_token(function_name);
|
||||||
|
|
||||||
consume(Token::Type::LeftParen);
|
consume(Token::Type::LeftParen);
|
||||||
auto parameters = parse_parameter_list(*func);
|
auto parameters = parse_parameter_list(*func);
|
||||||
|
if (parameters.has_value())
|
||||||
|
func->m_parameters = move(parameters.value());
|
||||||
|
|
||||||
consume(Token::Type::RightParen);
|
consume(Token::Type::RightParen);
|
||||||
|
|
||||||
RefPtr<FunctionDefinition> body;
|
RefPtr<FunctionDefinition> body;
|
||||||
|
@ -160,10 +167,6 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p
|
||||||
consume(Token::Type::Semicolon);
|
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->m_definition = move(body);
|
||||||
func->set_end(func_end);
|
func->set_end(func_end);
|
||||||
return func;
|
return func;
|
||||||
|
@ -248,9 +251,8 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(ASTNode& parent)
|
||||||
return block_statement;
|
return block_statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::match_variable_declaration()
|
bool Parser::match_type()
|
||||||
{
|
{
|
||||||
SCOPE_LOGGER();
|
|
||||||
save_state();
|
save_state();
|
||||||
ScopeGuard state_guard = [this] { load_state(); };
|
ScopeGuard state_guard = [this] { load_state(); };
|
||||||
|
|
||||||
|
@ -258,7 +260,19 @@ bool Parser::match_variable_declaration()
|
||||||
// Type
|
// Type
|
||||||
if (!peek(Token::Type::KnownType).has_value() && !peek(Token::Type::Identifier).has_value())
|
if (!peek(Token::Type::KnownType).has_value() && !peek(Token::Type::Identifier).has_value())
|
||||||
return false;
|
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
|
// Identifier
|
||||||
if (!peek(Token::Type::Identifier).has_value())
|
if (!peek(Token::Type::Identifier).has_value())
|
||||||
|
@ -561,9 +575,12 @@ bool Parser::match_function_declaration()
|
||||||
save_state();
|
save_state();
|
||||||
ScopeGuard state_guard = [this] { load_state(); };
|
ScopeGuard state_guard = [this] { load_state(); };
|
||||||
|
|
||||||
if (!peek(Token::Type::KnownType).has_value())
|
parse_function_qualifiers();
|
||||||
|
|
||||||
|
if (!match_type())
|
||||||
return false;
|
return false;
|
||||||
consume();
|
VERIFY(m_root_node);
|
||||||
|
parse_type(*m_root_node);
|
||||||
|
|
||||||
if (!peek(Token::Type::Identifier).has_value())
|
if (!peek(Token::Type::Identifier).has_value())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1098,6 +1115,27 @@ Vector<StringView> Parser::parse_type_qualifiers()
|
||||||
}
|
}
|
||||||
return 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()
|
bool Parser::match_attribute_specification()
|
||||||
{
|
{
|
||||||
return text_of_token(peek()) == "__attribute__";
|
return text_of_token(peek()) == "__attribute__";
|
||||||
|
|
|
@ -88,6 +88,7 @@ private:
|
||||||
bool match_keyword(const String&);
|
bool match_keyword(const String&);
|
||||||
bool match_block_statement();
|
bool match_block_statement();
|
||||||
bool match_namespace_declaration();
|
bool match_namespace_declaration();
|
||||||
|
bool match_type();
|
||||||
|
|
||||||
Optional<NonnullRefPtrVector<Parameter>> parse_parameter_list(ASTNode& parent);
|
Optional<NonnullRefPtrVector<Parameter>> parse_parameter_list(ASTNode& parent);
|
||||||
Optional<Token> consume_whitespace();
|
Optional<Token> consume_whitespace();
|
||||||
|
@ -163,6 +164,7 @@ private:
|
||||||
void initialize_program_tokens(const StringView& program);
|
void initialize_program_tokens(const StringView& program);
|
||||||
void add_tokens_for_preprocessor(Token& replaced_token, Preprocessor::DefinedValue&);
|
void add_tokens_for_preprocessor(Token& replaced_token, Preprocessor::DefinedValue&);
|
||||||
Vector<StringView> parse_type_qualifiers();
|
Vector<StringView> parse_type_qualifiers();
|
||||||
|
Vector<StringView> parse_function_qualifiers();
|
||||||
|
|
||||||
Preprocessor::Definitions m_definitions;
|
Preprocessor::Definitions m_definitions;
|
||||||
String m_filename;
|
String m_filename;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue