diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-07-28 06:04:51 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-02 01:03:59 +0200 |
commit | 5f66874ea06e965c094a0679bee8634012e85739 (patch) | |
tree | 2ca88d0da92878b3ba1b222d39a22a5a9b6534e3 | |
parent | b3cbe1456969586994c0612f46a5ce9c55a41f25 (diff) | |
download | serenity-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.cpp | 34 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/AST.h | 20 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.cpp | 12 |
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; } |