1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sngcm/ast/Template.hpp>
  7 #include <sngcm/ast/Identifier.hpp>
  8 #include <sngcm/ast/Visitor.hpp>
  9 
 10 namespace sngcm { namespace ast {
 11 
 12 TemplateIdNode::TemplateIdNode(const Span& span_) : Node(NodeType::templateIdNodespan_)
 13 {
 14 }
 15 
 16 TemplateIdNode::TemplateIdNode(const Span& span_Node* primary_) : Node(NodeType::templateIdNodespan_)primary(primary_)
 17 {
 18     primary->SetParent(this);
 19 }
 20 
 21 Node* TemplateIdNode::Clone(CloneContext& cloneContext) const
 22 {
 23     TemplateIdNode* clone = new TemplateIdNode(GetSpan()primary->Clone(cloneContext));
 24     int n = templateArguments.Count();
 25     for (int i = 0; i < n; ++i)
 26     {
 27         Node* templateArgument = templateArguments[i];
 28         clone->AddTemplateArgument(templateArgument->Clone(cloneContext));
 29     }
 30     return clone;
 31 }
 32 
 33 void TemplateIdNode::Accept(Visitor& visitor)
 34 {
 35     visitor.Visit(*this);
 36 }
 37 
 38 void TemplateIdNode::Write(AstWriter& writer)
 39 {
 40     Node::Write(writer);
 41     writer.Write(primary.get());
 42     templateArguments.Write(writer);
 43 }
 44 
 45 void TemplateIdNode::Read(AstReader& reader)
 46 {
 47     Node::Read(reader);
 48     primary.reset(reader.ReadNode());
 49     primary->SetParent(this);
 50     templateArguments.Read(reader);
 51     templateArguments.SetParent(this);
 52 }
 53 
 54 std::string TemplateIdNode::ToString() const
 55 {
 56     std::string s = primary->ToString();
 57     s.append("<");
 58     int n = templateArguments.Count();
 59     for (int i = 0; i < n; ++i)
 60     {
 61         if (i > 0)
 62         {
 63             s.append(", ");
 64         }
 65         s.append(templateArguments[i]->ToString());
 66     }
 67     s.append(">");
 68     return s;
 69 }
 70 
 71 void TemplateIdNode::AddTemplateArgument(Node* templateArgument)
 72 {
 73     templateArgument->SetParent(this);
 74     templateArguments.Add(templateArgument);
 75 }
 76 
 77 TemplateParameterNode::TemplateParameterNode(const Span& span_) : Node(NodeType::templateParameterNodespan_)id()
 78 {
 79 }
 80 
 81 TemplateParameterNode::TemplateParameterNode(const Span& span_IdentifierNode* id_Node* defaultTemplateArgument_) :
 82     Node(NodeType::templateParameterNodespan_)id(id_)defaultTemplateArgument(defaultTemplateArgument_)
 83 {
 84     id->SetParent(this);
 85     if (defaultTemplateArgument)
 86     {
 87         defaultTemplateArgument->SetParent(this);
 88     }
 89 }
 90 
 91 Node* TemplateParameterNode::Clone(CloneContext& cloneContext) const
 92 {
 93     Node* clonedDefaultTemplateArgument = nullptr;
 94     if (defaultTemplateArgument)
 95     {
 96         clonedDefaultTemplateArgument = defaultTemplateArgument->Clone(cloneContext);
 97     }
 98     return new TemplateParameterNode(GetSpan()static_cast<IdentifierNode*>(id->Clone(cloneContext))clonedDefaultTemplateArgument);
 99 }
100 
101 void TemplateParameterNode::Accept(Visitor& visitor)
102 {
103     visitor.Visit(*this);
104 }
105 
106 void TemplateParameterNode::Write(AstWriter& writer)
107 {
108     Node::Write(writer);
109     writer.Write(id.get());
110     bool hasDefaultTemplateArgument = defaultTemplateArgument != nullptr;
111     writer.GetBinaryWriter().Write(hasDefaultTemplateArgument);
112     if (hasDefaultTemplateArgument)
113     {
114         writer.Write(defaultTemplateArgument.get());
115     }
116 }
117 
118 void TemplateParameterNode::Read(AstReader& reader)
119 {
120     Node::Read(reader);
121     id.reset(reader.ReadIdentifierNode());
122     id->SetParent(this);
123     bool hasDefaultTemplateArgument = reader.GetBinaryReader().ReadBool();
124     if (hasDefaultTemplateArgument)
125     {
126         defaultTemplateArgument.reset(reader.ReadNode());
127         defaultTemplateArgument->SetParent(this);
128     }
129 }
130 
131 } } // namespace sngcm::ast