summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-07-28 06:04:51 +0430
committerAndreas Kling <kling@serenityos.org>2021-08-02 01:03:59 +0200
commit5f66874ea06e965c094a0679bee8634012e85739 (patch)
tree2ca88d0da92878b3ba1b222d39a22a5a9b6534e3
parentb3cbe1456969586994c0612f46a5ce9c55a41f25 (diff)
downloadserenity-5f66874ea06e965c094a0679bee8634012e85739.zip
LibCpp: Add support for parsing function types
This makes it work with types like `Function<T(U, V)>`.
-rw-r--r--Userland/Libraries/LibCpp/AST.cpp34
-rw-r--r--Userland/Libraries/LibCpp/AST.h20
-rw-r--r--Userland/Libraries/LibCpp/Parser.cpp12
3 files changed, 66 insertions, 0 deletions
diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp
index 3187911794..ad0bf407b4 100644
--- a/Userland/Libraries/LibCpp/AST.cpp
+++ b/Userland/Libraries/LibCpp/AST.cpp
@@ -113,6 +113,27 @@ String Reference::to_string() const
return builder.to_string();
}
+String FunctionType::to_string() const
+{
+ StringBuilder builder;
+ builder.append(m_return_type->to_string());
+ builder.append("(");
+ bool first = true;
+ for (auto& parameter : m_parameters) {
+ if (first)
+ first = false;
+ else
+ builder.append(", ");
+ builder.append(parameter.type()->to_string());
+ if (!parameter.name().is_empty()) {
+ builder.append(" ");
+ builder.append(parameter.name());
+ }
+ }
+ builder.append(")");
+ return builder.to_string();
+}
+
void Parameter::dump(FILE* output, size_t indent) const
{
ASTNode::dump(output, indent);
@@ -382,6 +403,19 @@ void Reference::dump(FILE* output, size_t indent) const
}
}
+void FunctionType::dump(FILE* output, size_t indent) const
+{
+ ASTNode::dump(output, indent);
+ if (m_return_type)
+ m_return_type->dump(output, indent + 1);
+ print_indent(output, indent + 1);
+ outln("(");
+ for (auto& parameter : m_parameters)
+ parameter.dump(output, indent + 2);
+ print_indent(output, indent + 1);
+ outln(")");
+}
+
void MemberExpression::dump(FILE* output, size_t indent) const
{
ASTNode::dump(output, indent);
diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h
index 7bb9b36490..1505ef109b 100644
--- a/Userland/Libraries/LibCpp/AST.h
+++ b/Userland/Libraries/LibCpp/AST.h
@@ -308,6 +308,26 @@ private:
Kind m_kind;
};
+class FunctionType : public Type {
+public:
+ virtual ~FunctionType() override = default;
+ virtual const char* class_name() const override { return "FunctionType"; }
+ virtual void dump(FILE* = stdout, size_t indent = 0) const override;
+ virtual String to_string() const override;
+
+ FunctionType(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
+ : Type(parent, start, end, filename)
+ {
+ }
+
+ void set_return_type(Type& type) { m_return_type = type; }
+ void set_parameters(NonnullRefPtrVector<Parameter> parameters) { m_parameters = move(parameters); }
+
+private:
+ RefPtr<Type> m_return_type;
+ NonnullRefPtrVector<Parameter> m_parameters;
+};
+
class FunctionDefinition : public ASTNode {
public:
virtual ~FunctionDefinition() override = default;
diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp
index d41bb415be..0279e8e83d 100644
--- a/Userland/Libraries/LibCpp/Parser.cpp
+++ b/Userland/Libraries/LibCpp/Parser.cpp
@@ -1255,7 +1255,19 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
type = ref;
}
+ if (peek().type() == Token::Type::LeftParen) {
+ consume();
+ auto fn_type = create_ast_node<FunctionType>(parent, type->start(), position());
+ fn_type->set_return_type(*type);
+ type->set_parent(*fn_type);
+ if (auto parameters = parse_parameter_list(*type); parameters.has_value())
+ fn_type->set_parameters(parameters.release_value());
+ consume(Token::Type::RightParen);
+ type = fn_type;
+ }
+
type->set_end(position());
+
return type;
}