diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp index 87b61c6340..d214ef5e44 100644 --- a/Userland/Libraries/LibCpp/AST.cpp +++ b/Userland/Libraries/LibCpp/AST.cpp @@ -82,7 +82,10 @@ void Type::dump(size_t indent) const { ASTNode::dump(indent); print_indent(indent + 1); - outln("{}", m_name); + String qualifiers_string; + if(!m_qualifiers.is_empty()) + qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers)); + outln("{}{}", qualifiers_string, m_name); } void Parameter::dump(size_t indent) const diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index ce797609ba..604356b21c 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -226,6 +226,7 @@ public: } StringView m_name; + Vector m_qualifiers; }; class Pointer : public Type { diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index 1a592a4ff3..ea75be8aab 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -24,6 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#undef CPP_DEBUG +#define CPP_DEBUG 1 + #ifdef CPP_DEBUG # define DEBUG_SPAM #endif @@ -226,9 +229,11 @@ NonnullRefPtr Parser::parse_block_statement(ASTNode& parent) bool Parser::match_variable_declaration() { + SCOPE_LOGGER(); save_state(); ScopeGuard state_guard = [this] { load_state(); }; + parse_type_qualifiers(); // Type if (!peek(Token::Type::KnownType).has_value() && !peek(Token::Type::Identifier).has_value()) return false; @@ -255,12 +260,12 @@ NonnullRefPtr Parser::parse_variable_declaration(ASTNode& p { SCOPE_LOGGER(); auto var = create_ast_node(parent, position(), {}); - auto type_token = consume(); - if (type_token.type() != Token::Type::KnownType && type_token.type() != Token::Type::Identifier) { + if (!match_variable_declaration()) { error("unexpected token for variable type"); - var->set_end(type_token.end()); + var->set_end(position()); return var; } + var->m_type = parse_type(var); auto identifier_token = consume(Token::Type::Identifier); RefPtr initial_value; @@ -270,7 +275,6 @@ NonnullRefPtr Parser::parse_variable_declaration(ASTNode& p } var->set_end(position()); - var->m_type = create_ast_node(var, type_token.m_start, type_token.m_end, text_of_token(type_token)); var->m_name = text_of_token(identifier_token); var->m_initial_value = move(initial_value); @@ -983,8 +987,10 @@ bool Parser::match_boolean_literal() NonnullRefPtr Parser::parse_type(ASTNode& parent) { SCOPE_LOGGER(); + auto qualifiers = parse_type_qualifiers(); auto token = consume(); auto type = create_ast_node(parent, token.start(), token.end(), text_of_token(token)); + type->m_qualifiers = move(qualifiers); if (token.type() != Token::Type::KnownType && token.type() != Token::Type::Identifier) { error(String::formatted("unexpected token for type: {}", token.to_string())); return type; @@ -1033,4 +1039,22 @@ NonnullRefPtr Parser::parse_if_statement(ASTNode& parent) } return if_statement; } +Vector Parser::parse_type_qualifiers() +{ + SCOPE_LOGGER(); + Vector qualifiers; + while (!done()) { + auto token = peek(); + if (token.type() != Token::Type::Keyword) + break; + auto text = text_of_token(token); + if (text == "static" || text == "const") { + qualifiers.append(text); + consume(); + } else { + break; + } + } + return qualifiers; +} } diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 91e3580792..6b28f4a817 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -160,6 +160,7 @@ private: RefPtr m_root_node; NonnullRefPtrVector m_nodes; Vector m_errors; + Vector parse_type_qualifiers(); }; }