summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-03-01 22:33:46 +0200
committerAndreas Kling <kling@serenityos.org>2021-03-02 12:50:37 +0100
commit1d3b5dabc3554f8c5dc40119d487baa3c7266d98 (patch)
tree49a8040e70b0a9e14065a9e90467735b48c6ca88 /Userland
parent5c79297b2c93171072129112ac328e2c2498978f (diff)
downloadserenity-1d3b5dabc3554f8c5dc40119d487baa3c7266d98.zip
LibCpp: Parse ellipsis
We can now parse the printf function declaration :^)
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibCpp/AST.cpp9
-rw-r--r--Userland/Libraries/LibCpp/AST.h4
-rw-r--r--Userland/Libraries/LibCpp/Parser.cpp48
-rw-r--r--Userland/Libraries/LibCpp/Parser.h3
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();
};
}