1 // =================================
  2 // Copyright (c) 2021 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_const boost::uuids::uuid& moduleId_) : Node(NodeType::templateIdNodespan_moduleId_)
 13 {
 14 }
 15 
 16 TemplateIdNode::TemplateIdNode(const Span& span_const boost::uuids::uuid& moduleId_Node* primary_) :
 17     Node(NodeType::templateIdNodespan_moduleId_)primary(primary_)
 18 {
 19     primary->SetParent(this);
 20 }
 21 
 22 Node* TemplateIdNode::Clone(CloneContext& cloneContext) const
 23 {
 24     TemplateIdNode* clone = new TemplateIdNode(GetSpan()ModuleId()primary->Clone(cloneContext));
 25     int n = templateArguments.Count();
 26     for (int i = 0; i < n; ++i)
 27     {
 28         Node* templateArgument = templateArguments[i];
 29         clone->AddTemplateArgument(templateArgument->Clone(cloneContext));
 30     }
 31     return clone;
 32 }
 33 
 34 void TemplateIdNode::Accept(Visitor& visitor)
 35 {
 36     visitor.Visit(*this);
 37 }
 38 
 39 void TemplateIdNode::Write(AstWriter& writer)
 40 {
 41     Node::Write(writer);
 42     writer.Write(primary.get());
 43     templateArguments.Write(writer);
 44 }
 45 
 46 void TemplateIdNode::Read(AstReader& reader)
 47 {
 48     Node::Read(reader);
 49     primary.reset(reader.ReadNode());
 50     primary->SetParent(this);
 51     templateArguments.Read(reader);
 52     templateArguments.SetParent(this);
 53 }
 54 
 55 std::string TemplateIdNode::ToString() const
 56 {
 57     std::string s = primary->ToString();
 58     s.append("<");
 59     int n = templateArguments.Count();
 60     for (int i = 0; i < n; ++i)
 61     {
 62         if (i > 0)
 63         {
 64             s.append(", ");
 65         }
 66         s.append(templateArguments[i]->ToString());
 67     }
 68     s.append(">");
 69     return s;
 70 }
 71 
 72 void TemplateIdNode::AddTemplateArgument(Node* templateArgument)
 73 {
 74     templateArgument->SetParent(this);
 75     templateArguments.Add(templateArgument);
 76 }
 77 
 78 TemplateParameterNode::TemplateParameterNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::templateParameterNodespan_moduleId_)id()
 79 {
 80 }
 81 
 82 TemplateParameterNode::TemplateParameterNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_Node* defaultTemplateArgument_) :
 83     Node(NodeType::templateParameterNodespan_moduleId_)id(id_)defaultTemplateArgument(defaultTemplateArgument_)
 84 {
 85     id->SetParent(this);
 86     if (defaultTemplateArgument)
 87     {
 88         defaultTemplateArgument->SetParent(this);
 89     }
 90 }
 91 
 92 Node* TemplateParameterNode::Clone(CloneContext& cloneContext) const
 93 {
 94     Node* clonedDefaultTemplateArgument = nullptr;
 95     if (defaultTemplateArgument)
 96     {
 97         clonedDefaultTemplateArgument = defaultTemplateArgument->Clone(cloneContext);
 98     }
 99     TemplateParameterNode* clone = new TemplateParameterNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(id->Clone(cloneContext))clonedDefaultTemplateArgument);
100     return clone;
101 }
102 
103 void TemplateParameterNode::Accept(Visitor& visitor)
104 {
105     visitor.Visit(*this);
106 }
107 
108 void TemplateParameterNode::Write(AstWriter& writer)
109 {
110     Node::Write(writer);
111     writer.Write(id.get());
112     bool hasDefaultTemplateArgument = defaultTemplateArgument != nullptr;
113     writer.GetBinaryWriter().Write(hasDefaultTemplateArgument);
114     if (hasDefaultTemplateArgument)
115     {
116         writer.Write(defaultTemplateArgument.get());
117     }
118 }
119 
120 void TemplateParameterNode::Read(AstReader& reader)
121 {
122     Node::Read(reader);
123     id.reset(reader.ReadIdentifierNode());
124     id->SetParent(this);
125     bool hasDefaultTemplateArgument = reader.GetBinaryReader().ReadBool();
126     if (hasDefaultTemplateArgument)
127     {
128         defaultTemplateArgument.reset(reader.ReadNode());
129         defaultTemplateArgument->SetParent(this);
130     }
131 }
132 
133 FullInstantiationRequestNode::FullInstantiationRequestNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::fullInstantiationRequestNodespan_moduleId_)templateId()
134 {
135 }
136 
137 FullInstantiationRequestNode::FullInstantiationRequestNode(const Span& span_const boost::uuids::uuid& moduleId_TemplateIdNode* templateId_) :
138     Node(NodeType::fullInstantiationRequestNodespan_moduleId_)templateId(templateId_)
139 {
140 }
141 
142 Node* FullInstantiationRequestNode::Clone(CloneContext& cloneContext) const
143 {
144     return new FullInstantiationRequestNode(GetSpan()ModuleId()static_cast<TemplateIdNode*>(templateId->Clone(cloneContext)));
145 }
146 
147 void FullInstantiationRequestNode::Accept(Visitor& visitor)
148 {
149     visitor.Visit(*this);
150 }
151 
152 void FullInstantiationRequestNode::Write(AstWriter& writer)
153 {
154     Node::Write(writer);
155     writer.Write(templateId.get());
156 }
157 
158 void FullInstantiationRequestNode::Read(AstReader& reader)
159 {
160     Node::Read(reader);
161     templateId.reset(reader.ReadTemplateIdNode());
162 }
163 
164 } } // namespace sngcm::ast