diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-07-28 05:37:24 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-02 01:03:59 +0200 |
commit | 331911412745eded57f5e5c461d4cd7fbcdedb68 (patch) | |
tree | ec656901541a13962cb7eb3e07634f24c3d5809b | |
parent | 3c1422d774f2b18d687a276d5ca1a459ed60b8e3 (diff) | |
download | serenity-331911412745eded57f5e5c461d4cd7fbcdedb68.zip |
LibCpp: Add support for parsing reference types
-rw-r--r-- | Userland/Libraries/LibCpp/AST.cpp | 23 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/AST.h | 27 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.cpp | 10 |
3 files changed, 60 insertions, 0 deletions
diff --git a/Userland/Libraries/LibCpp/AST.cpp b/Userland/Libraries/LibCpp/AST.cpp index 40f960b785..3187911794 100644 --- a/Userland/Libraries/LibCpp/AST.cpp +++ b/Userland/Libraries/LibCpp/AST.cpp @@ -100,6 +100,19 @@ String Pointer::to_string() const return builder.to_string(); } +String Reference::to_string() const +{ + if (!m_referenced_type) + return {}; + StringBuilder builder; + builder.append(m_referenced_type->to_string()); + if (m_kind == Kind::Lvalue) + builder.append("&"); + else + builder.append("&&"); + return builder.to_string(); +} + void Parameter::dump(FILE* output, size_t indent) const { ASTNode::dump(output, indent); @@ -359,6 +372,16 @@ void Pointer::dump(FILE* output, size_t indent) const } } +void Reference::dump(FILE* output, size_t indent) const +{ + ASTNode::dump(output, indent); + print_indent(output, indent + 1); + outln(output, "{}", m_kind == Kind::Lvalue ? "&" : "&&"); + if (!m_referenced_type.is_null()) { + m_referenced_type->dump(output, indent + 1); + } +} + 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 912312770a..7bb9b36490 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -281,6 +281,33 @@ private: RefPtr<Type> m_pointee; }; +class Reference : public Type { +public: + virtual ~Reference() override = default; + virtual const char* class_name() const override { return "Reference"; } + virtual void dump(FILE* = stdout, size_t indent = 0) const override; + virtual String to_string() const override; + + enum class Kind { + Lvalue, + Rvalue, + }; + + Reference(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename, Kind kind) + : Type(parent, start, end, filename) + , m_kind(kind) + { + } + + const Type* referenced_type() const { return m_referenced_type.ptr(); } + void set_referenced_type(RefPtr<Type>&& pointee) { m_referenced_type = move(pointee); } + Kind kind() const { return m_kind; } + +private: + RefPtr<Type const> m_referenced_type; + Kind m_kind; +}; + class FunctionDefinition : public ASTNode { public: virtual ~FunctionDefinition() override = default; diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index c3a630f0db..64c814d717 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -1237,6 +1237,16 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent) type = ptr; } + if (!eof() && (peek().type() == Token::Type::And || peek().type() == Token::Type::AndAnd)) { + type->set_end(position()); + auto ref_token = consume(); + auto ref = create_ast_node<Reference>(parent, type->start(), ref_token.end(), ref_token.type() == Token::Type::And ? Reference::Kind::Lvalue : Reference::Kind::Rvalue); + type->set_parent(*ref); + ref->set_referenced_type(type); + ref->set_end(position()); + type = ref; + } + type->set_end(position()); return type; } |