Browse Source

LibCpp: Add support for parsing reference types

Ali Mohammad Pur 4 years ago
parent
commit
3319114127

+ 23 - 0
Userland/Libraries/LibCpp/AST.cpp

@@ -100,6 +100,19 @@ String Pointer::to_string() const
     return builder.to_string();
     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
 void Parameter::dump(FILE* output, size_t indent) const
 {
 {
     ASTNode::dump(output, indent);
     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
 void MemberExpression::dump(FILE* output, size_t indent) const
 {
 {
     ASTNode::dump(output, indent);
     ASTNode::dump(output, indent);

+ 27 - 0
Userland/Libraries/LibCpp/AST.h

@@ -281,6 +281,33 @@ private:
     RefPtr<Type> m_pointee;
     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 {
 class FunctionDefinition : public ASTNode {
 public:
 public:
     virtual ~FunctionDefinition() override = default;
     virtual ~FunctionDefinition() override = default;

+ 10 - 0
Userland/Libraries/LibCpp/Parser.cpp

@@ -1237,6 +1237,16 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
         type = ptr;
         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());
     type->set_end(position());
     return type;
     return type;
 }
 }