diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibCpp/AST.cpp | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/AST.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.cpp | 48 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.h | 3 |
4 files changed, 42 insertions, 22 deletions
diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp index d214ef5e44..22de331e36 100644 --- a/Userland/Libraries/LibCpp/AST.cpp +++ b/Userland/Libraries/LibCpp/AST.cpp @@ -83,7 +83,7 @@ void Type::dump(size_t indent) const ASTNode::dump(indent); print_indent(indent + 1); String qualifiers_string; - if(!m_qualifiers.is_empty()) + if (!m_qualifiers.is_empty()) qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers)); outln("{}{}", qualifiers_string, m_name); } @@ -91,11 +91,16 @@ void Type::dump(size_t indent) const void Parameter::dump(size_t indent) const { ASTNode::dump(indent); + if (m_is_ellipsis) { + print_indent(indent + 1); + outln("..."); + } if (!m_name.is_null()) { print_indent(indent); outln("{}", m_name); } - m_type->dump(indent + 1); + if (m_type) + m_type->dump(indent + 1); } void FunctionDefinition::dump(size_t indent) const diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index 604356b21c..7eef26643e 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -202,13 +202,15 @@ public: virtual const char* class_name() const override { return "Parameter"; } virtual void dump(size_t indent) const override; - Parameter(ASTNode* parent, Optional<Position> start, Optional<Position> end, StringView name, const String& filename) + Parameter(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename, StringView name) : VariableOrParameterDeclaration(parent, start, end, filename) { m_name = name; } virtual bool is_parameter() const override { return true; } + + bool m_is_ellipsis { false }; }; class Type : public ASTNode { diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index 8f67ac8cce..7bbffe7276 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -24,9 +24,6 @@ * 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 @@ -560,20 +557,30 @@ Optional<NonnullRefPtrVector<Parameter>> Parser::parse_parameter_list(ASTNode& p SCOPE_LOGGER(); NonnullRefPtrVector<Parameter> parameters; while (peek().m_type != Token::Type::RightParen && !eof()) { - auto type = parse_type(parent); + if (match_ellipsis()) { + auto last_dot = consume(); + while (peek().type() == Token::Type::Dot) + last_dot = consume(); + auto param = create_ast_node<Parameter>(parent, position(), last_dot.end(), StringView {}); + param->m_is_ellipsis = true; + parameters.append(move(param)); + } else { + auto type = parse_type(parent); - auto name_identifier = peek(Token::Type::Identifier); - if (name_identifier.has_value()) - consume(Token::Type::Identifier); + auto name_identifier = peek(Token::Type::Identifier); + if (name_identifier.has_value()) + consume(Token::Type::Identifier); - StringView name; - if (name_identifier.has_value()) - name = text_of_token(name_identifier.value()); + StringView name; + if (name_identifier.has_value()) + name = text_of_token(name_identifier.value()); - auto param = create_ast_node<Parameter>(parent, type->start(), name_identifier.has_value() ? name_identifier.value().m_end : type->end(), name); + auto param = create_ast_node<Parameter>(parent, type->start(), name_identifier.has_value() ? name_identifier.value().m_end : type->end(), name); + + param->m_type = move(type); + parameters.append(move(param)); + } - param->m_type = move(type); - parameters.append(move(param)); if (peek(Token::Type::Comma).has_value()) consume(Token::Type::Comma); } @@ -640,12 +647,11 @@ Token Parser::consume() return m_tokens[m_state.token_index++]; } -Token Parser::peek() const +Token Parser::peek(size_t offset) const { - if (eof()) { + if (m_state.token_index + offset >= m_tokens.size()) return { Token::Type::EOF_TOKEN, position(), position() }; - } - return m_tokens[m_state.token_index]; + return m_tokens[m_state.token_index + offset]; } Optional<Token> Parser::peek(Token::Type type) const @@ -1081,10 +1087,16 @@ void Parser::consume_attribute_specification() if (token.type() == Token::Type::RightParen) { --left_count; } - if(left_count == 0) + if (left_count == 0) return; } } +bool Parser::match_ellipsis() +{ + if (m_state.token_index > m_tokens.size() - 3) + return false; + return peek().type() == Token::Type::Dot && peek().type() == Token::Type::Dot && peek().type() == Token::Type::Dot; +} } diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 15676dd92c..12cf2ffd12 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -111,7 +111,7 @@ private: Token consume(Token::Type); Token consume(); Token consume_keyword(const String&); - Token peek() const; + Token peek(size_t offset = 0) const; Optional<Token> peek(Token::Type) const; Position position() const; StringView text_of_range(Position start, Position end) const; @@ -163,6 +163,7 @@ private: Vector<StringView> parse_type_qualifiers(); bool match_attribute_specification(); void consume_attribute_specification(); + bool match_ellipsis(); }; } |