1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGCM_AST_CONCEPT_INCLUDED
  7 #define SNGCM_AST_CONCEPT_INCLUDED
  8 #include <sngcm/ast/Parameter.hpp>
  9 #include <sngcm/ast/NodeList.hpp>
 10 
 11 namespace sngcm { namespace ast {
 12 
 13 class ConstraintNode public Node
 14 {
 15 public:
 16     ConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
 17     bool NodeIsConstraintNode() const override { return true; }
 18     virtual bool IsHeaderConstraint() const { return false; }
 19 };
 20 
 21 class ParenthesizedConstraintNode public ConstraintNode
 22 {
 23 public:
 24     ParenthesizedConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
 25     ParenthesizedConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* constraint_);
 26     Node* Clone(CloneContext& cloneContext) const override;
 27     void Accept(Visitor& visitor) override;
 28     void Write(AstWriter& writer) override;
 29     void Read(AstReader& reader) override;
 30     const ConstraintNode* Constraint() const { return constraint.get(); }
 31     ConstraintNode* Constraint() { return constraint.get(); }
 32     std::string ToString() const override;
 33 private:
 34     std::unique_ptr<ConstraintNode> constraint;
 35 };
 36 
 37 class BinaryConstraintNode public ConstraintNode
 38 {
 39 public:
 40     BinaryConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
 41     BinaryConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* left_ConstraintNode* right_);
 42     void Write(AstWriter& writer) override;
 43     void Read(AstReader& reader) override;
 44     const ConstraintNode* Left() const { return left.get(); }
 45     ConstraintNode* Left() { return left.get(); }
 46     const ConstraintNode* Right() const { return right.get(); }
 47     ConstraintNode* Right() { return right.get(); }
 48 private:
 49     std::unique_ptr<ConstraintNode> left;
 50     std::unique_ptr<ConstraintNode> right;
 51 };
 52 
 53 class DisjunctiveConstraintNode public BinaryConstraintNode
 54 {
 55 public:
 56     DisjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
 57     DisjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* left_ConstraintNode* right_);
 58     Node* Clone(CloneContext& cloneContext) const override;
 59     void Accept(Visitor& visitor) override;
 60     std::string ToString() const override;
 61 };
 62 
 63 class ConjunctiveConstraintNode public BinaryConstraintNode
 64 {
 65 public:
 66     ConjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
 67     ConjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* left_ConstraintNode* right_);
 68     Node* Clone(CloneContext& cloneContext) const override;
 69     void Accept(Visitor& visitor) override;
 70     std::string ToString() const override;
 71 };
 72 
 73 class WhereConstraintNode public ConstraintNode
 74 {
 75 public:
 76     WhereConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
 77     WhereConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* constraint_);
 78     Node* Clone(CloneContext& cloneContext) const override;
 79     void Accept(Visitor& visitor) override;
 80     void Write(AstWriter& writer) override;
 81     void Read(AstReader& reader) override;
 82     const ConstraintNode* Constraint() const { return constraint.get(); }
 83     ConstraintNode* Constraint() { return constraint.get(); }
 84     std::string ToString() const override;
 85     void SetHeaderConstraint() { headerConstraint = true; }
 86     bool IsHeaderConstraint() const override { return headerConstraint; }
 87     void SetSemicolon() { semicolon = true; }
 88     bool Semicolon() const { return semicolon; }
 89 private:
 90     std::unique_ptr<ConstraintNode> constraint;
 91     bool headerConstraint;
 92     bool semicolon;
 93 };
 94 
 95 class PredicateConstraintNode public ConstraintNode
 96 {
 97 public:
 98     PredicateConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
 99     PredicateConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* invokeExpr_);
100     Node* Clone(CloneContext& cloneContext) const override;
101     void Accept(Visitor& visitor) override;
102     void Write(AstWriter& writer) override;
103     void Read(AstReader& reader) override;
104     const Node* InvokeExpr() const { return invokeExpr.get(); }
105     Node* InvokeExpr() { return invokeExpr.get(); }
106     std::string ToString() const override;
107 private:
108     std::unique_ptr<Node> invokeExpr;
109 };
110 
111 class IsConstraintNode public ConstraintNode
112 {
113 public:
114     IsConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
115     IsConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeExpr_Node* conceptOrTypeName_);
116     Node* Clone(CloneContext& cloneContext) const override;
117     void Accept(Visitor& visitor) override;
118     void Write(AstWriter& writer) override;
119     void Read(AstReader& reader) override;
120     const Node* TypeExpr() const { return typeExpr.get(); }
121     Node* TypeExpr() { return typeExpr.get(); }
122     const Node* ConceptOrTypeName() const { return conceptOrTypeName.get(); }
123     Node* ConceptOrTypeName() { return conceptOrTypeName.get(); }
124     std::string ToString() const override;
125 private:
126     std::unique_ptr<Node> typeExpr;
127     std::unique_ptr<Node> conceptOrTypeName;
128 };
129 
130 class MultiParamConstraintNode public ConstraintNode
131 {
132 public:
133     MultiParamConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
134     MultiParamConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* conceptId_);
135     Node* Clone(CloneContext& cloneContext) const override;
136     void Accept(Visitor& visitor) override;
137     void Write(AstWriter& writer) override;
138     void Read(AstReader& reader) override;
139     const IdentifierNode* ConceptId() const { return conceptId.get(); }
140     IdentifierNode* ConceptId() { return conceptId.get(); }
141     const NodeList<Node>& TypeExprs() const { return typeExprs; }
142     void AddTypeExpr(Node* typeExpr);
143     std::string ToString() const override;
144 private:
145     std::unique_ptr<IdentifierNode> conceptId;
146     NodeList<Node> typeExprs;
147 };
148 
149 class TypeNameConstraintNode public ConstraintNode
150 {
151 public:
152     TypeNameConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
153     TypeNameConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeId_);
154     Node* Clone(CloneContext& cloneContext) const override;
155     void Accept(Visitor& visitor) override;
156     void Write(AstWriter& writer) override;
157     void Read(AstReader& reader) override;
158     const Node* TypeId() const { return typeId.get(); }
159     Node* TypeId() { return typeId.get(); }
160     std::string ToString() const override;
161 private:
162     std::unique_ptr<Node> typeId;
163 };
164 
165 class SignatureConstraintNode public ConstraintNode
166 {
167 public:
168     SignatureConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
169 };
170 
171 class ConstructorConstraintNode public SignatureConstraintNode
172 {
173 public:
174     ConstructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
175     ConstructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* typeParamId_);
176     Node* Clone(CloneContext& cloneContext) const override;
177     void Accept(Visitor& visitor) override;
178     void Write(AstWriter& writer) override;
179     void Read(AstReader& reader) override;
180     void AddParameter(ParameterNode* parameter) override;
181     const IdentifierNode* TypeParamId() const { return typeParamId.get(); }
182     IdentifierNode* TypeParamId() { return typeParamId.get(); }
183     const NodeList<ParameterNode>& Parameters() const { return parameters; }
184     std::string ToString() const override;
185 private:
186     std::unique_ptr<IdentifierNode> typeParamId;
187     NodeList<ParameterNode> parameters;
188 };
189 
190 class DestructorConstraintNode public SignatureConstraintNode
191 {
192 public:
193     DestructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
194     DestructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* typeParamId_);
195     Node* Clone(CloneContext& cloneContext) const override;
196     void Accept(Visitor& visitor) override;
197     void Write(AstWriter& writer) override;
198     void Read(AstReader& reader) override;
199     IdentifierNode* TypeParamId() { return typeParamId.get(); }
200     std::string ToString() const override;
201 private:
202     std::unique_ptr<IdentifierNode> typeParamId;
203 };
204 
205 class MemberFunctionConstraintNode public SignatureConstraintNode
206 {
207 public:
208     MemberFunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
209     MemberFunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* returnTypeExpr_IdentifierNode* typeParamId_const std::u32string& groupId_);
210     Node* Clone(CloneContext& cloneContext) const override;
211     void Accept(Visitor& visitor) override;
212     void Write(AstWriter& writer) override;
213     void Read(AstReader& reader) override;
214     void AddParameter(ParameterNode* parameter) override;
215     const Node* ReturnTypeExpr() const { return returnTypeExpr.get(); }
216     Node* ReturnTypeExpr() { return returnTypeExpr.get(); }
217     const IdentifierNode* TypeParamId() const { return typeParamId.get(); }
218     IdentifierNode* TypeParamId() { return typeParamId.get(); }
219     const std::u32string& GroupId() const { return groupId; }
220     const NodeList<ParameterNode>& Parameters() const { return parameters; }
221     std::string ToString() const override;
222 private:
223     std::unique_ptr<Node> returnTypeExpr;
224     std::unique_ptr<IdentifierNode> typeParamId;
225     std::u32string groupId;
226     NodeList<ParameterNode> parameters;
227 };
228 
229 class FunctionConstraintNode public SignatureConstraintNode
230 {
231 public:
232     FunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
233     FunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* returnTypeExpr_const std::u32string& groupId_);
234     Node* Clone(CloneContext& cloneContext) const override;
235     void Accept(Visitor& visitor) override;
236     void Write(AstWriter& writer) override;
237     void Read(AstReader& reader) override;
238     void AddParameter(ParameterNode* parameter) override;
239     const Node* ReturnTypeExpr() const { return returnTypeExpr.get(); }
240     Node* ReturnTypeExpr() { return returnTypeExpr.get(); }
241     const std::u32string& GroupId() const { return groupId; }
242     const NodeList<ParameterNode>& Parameters() const { return parameters; }
243     std::string ToString() const override;
244 private:
245     std::unique_ptr<Node> returnTypeExpr;
246     std::u32string groupId;
247     NodeList<ParameterNode> parameters;
248 };
249 
250 class AxiomStatementNode public Node
251 {
252 public:
253     AxiomStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
254     AxiomStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* expression_const std::u32string& text_);
255     Node* Clone(CloneContext& cloneContext) const override;
256     void Accept(Visitor& visitor) override;
257     void Write(AstWriter& writer) override;
258     void Read(AstReader& reader) override;
259     const Node* Expression() const { return expression.get(); }
260     Node* Expression() { return expression.get(); }
261     const std::u32string& Text() const { return text; }
262     std::string ToString() const override;
263 private:
264     std::unique_ptr<Node> expression;
265     std::u32string text;
266 };
267 
268 class AxiomNode public Node
269 {
270 public:
271     AxiomNode(const Span& span_const boost::uuids::uuid& moduleId_);
272     AxiomNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_);
273     Node* Clone(CloneContext& cloneContext) const override;
274     void Accept(Visitor& visitor) override;
275     void Write(AstWriter& writer) override;
276     void Read(AstReader& reader) override;
277     void AddParameter(ParameterNode* parameter) override;
278     void AddStatement(AxiomStatementNode* statement);
279     const IdentifierNode* Id() const { return id.get(); }
280     IdentifierNode* Id() { return id.get(); }
281     const NodeList<ParameterNode>& Parameters() const { return parameters; }
282     const NodeList<AxiomStatementNode>& Statements() const { return statements; }
283     void SetBeginBraceSpan(const Span& beginBraceSpan_) { beginBraceSpan = beginBraceSpan_; }
284     const Span& BeginBraceSpan() const { return beginBraceSpan; }
285     void SetEndBraceSpan(const Span& endBraceSpan_) { endBraceSpan = endBraceSpan_; }
286     const Span& EndBraceSpan() const { return endBraceSpan; }
287 private:
288     Span beginBraceSpan;
289     Span endBraceSpan;
290     std::unique_ptr<IdentifierNode> id;
291     NodeList<ParameterNode> parameters;
292     NodeList<AxiomStatementNode> statements;
293 };
294 
295 class ConceptIdNode public Node
296 {
297 public:
298     ConceptIdNode(const Span& span_const boost::uuids::uuid& moduleId_);
299     ConceptIdNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_);
300     Node* Clone(CloneContext& cloneContext) const override;
301     void Accept(Visitor& visitor) override;
302     void Write(AstWriter& writer) override;
303     void Read(AstReader& reader) override;
304     const IdentifierNode* Id() const { return id.get(); }
305     IdentifierNode* Id() { return id.get(); }
306     const NodeList<Node>& TypeParameters() const { return typeParameters; }
307     void AddTypeParameter(Node* typeParameter);
308     int Arity() const { return typeParameters.Count(); }
309     std::string ToString() const override;
310 private:
311     std::unique_ptr<IdentifierNode> id;
312     NodeList<Node> typeParameters;
313 };
314 
315 class ConceptNode public Node
316 {
317 public:
318     ConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
319     ConceptNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
320     ConceptNode(const Span& span_const boost::uuids::uuid& moduleId_Specifiers specifiers_IdentifierNode* id_);
321     ConceptNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_Specifiers specifiers_IdentifierNode* id_);
322     Node* Clone(CloneContext& cloneContext) const override;
323     void Accept(Visitor& visitor) override;
324     void Write(AstWriter& writer) override;
325     void Read(AstReader& reader) override;
326     bool IsConceptNode() const override { return true; }
327     virtual bool IsCommonConceptNode() const { return false; }
328     const IdentifierNode* Id() const { return id.get(); }
329     IdentifierNode* Id() { return id.get(); }
330     int Arity() const { return typeParameters.Count(); }
331     const NodeList<IdentifierNode>& TypeParameters() const { return typeParameters; }
332     void AddTypeParameter(IdentifierNode* typeParameter);
333     void SetRefinement(ConceptIdNode* refinement_);
334     ConceptIdNode* Refinement() { return refinement.get(); }
335     void AddConstraint(ConstraintNode* constraint);
336     const NodeList<ConstraintNode>& Constraints() const { return constraints; }
337     void AddAxiom(AxiomNode* axiom_);
338     const NodeList<AxiomNode>& Axioms() const { return axioms; }
339     Specifiers GetSpecifiers() const override { return specifiers; }
340     void SetBeginBraceSpan(const Span& beginBraceSpan_) { beginBraceSpan = beginBraceSpan_; }
341     const Span& BeginBraceSpan() const { return beginBraceSpan; }
342     void SetEndBraceSpan(const Span& endBraceSpan_) { endBraceSpan = endBraceSpan_; }
343     const Span& EndBraceSpan() const { return endBraceSpan; }
344 private:
345     Specifiers specifiers;
346     Span beginBraceSpan;
347     Span endBraceSpan;
348     std::unique_ptr<IdentifierNode> id;
349     NodeList<IdentifierNode> typeParameters;
350     std::unique_ptr<ConceptIdNode> refinement;
351     NodeList<ConstraintNode> constraints;
352     NodeList<AxiomNode> axioms;
353 };
354 
355 class IntrinsicConstraintNode public ConstraintNode
356 {
357 public:
358     IntrinsicConstraintNode(NodeType nodeType_);
359 };
360 
361 class SameConstraintNode public IntrinsicConstraintNode
362 {
363 public:
364     SameConstraintNode();
365     SameConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
366     void Accept(Visitor& visitor) override;
367     Node* Clone(CloneContext& cloneContext) const override;
368 };
369 
370 class DerivedConstraintNode public IntrinsicConstraintNode
371 {
372 public:
373     DerivedConstraintNode();
374     DerivedConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
375     void Accept(Visitor& visitor) override;
376     Node* Clone(CloneContext& cloneContext) const override;
377 };
378 
379 class ConvertibleConstraintNode public IntrinsicConstraintNode
380 {
381 public:
382     ConvertibleConstraintNode();
383     ConvertibleConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
384     void Accept(Visitor& visitor) override;
385     Node* Clone(CloneContext& cloneContext) const override;
386 };
387 
388 class ExplicitlyConvertibleConstraintNode public IntrinsicConstraintNode
389 {
390 public:
391     ExplicitlyConvertibleConstraintNode();
392     ExplicitlyConvertibleConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
393     void Accept(Visitor& visitor) override;
394     Node* Clone(CloneContext& cloneContext) const override;
395 };
396 
397 class CommonConstraintNode public IntrinsicConstraintNode
398 {
399 public:
400     CommonConstraintNode();
401     CommonConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
402     void Accept(Visitor& visitor) override;
403     Node* Clone(CloneContext& cloneContext) const override;
404 };
405 
406 class NonreferenceTypeConstraintNode public IntrinsicConstraintNode
407 {
408 public:
409     NonreferenceTypeConstraintNode();
410     NonreferenceTypeConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_);
411     void Accept(Visitor& visitor) override;
412     Node* Clone(CloneContext& cloneContext) const override;
413 };
414 
415 class SameConceptNode public ConceptNode
416 {
417 public:
418     SameConceptNode();
419     SameConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
420     bool IsIntrinsicConceptNode() const override { return true; }
421 };
422 
423 class DerivedConceptNode public ConceptNode
424 {
425 public:
426     DerivedConceptNode();
427     DerivedConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
428     bool IsIntrinsicConceptNode() const override { return true; }
429 };
430 
431 class ConvertibleConceptNode public ConceptNode
432 {
433 public:
434     ConvertibleConceptNode();
435     ConvertibleConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
436     bool IsIntrinsicConceptNode() const override { return true; }
437 };
438 
439 class ExplicitlyConvertibleConceptNode public ConceptNode
440 {
441 public:
442     ExplicitlyConvertibleConceptNode();
443     ExplicitlyConvertibleConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
444     bool IsIntrinsicConceptNode() const override { return true; }
445 };
446 
447 class CommonConceptNode public ConceptNode
448 {
449 public:
450     CommonConceptNode();
451     CommonConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
452     bool IsCommonConceptNode() const override { return true; }
453     bool IsIntrinsicConceptNode() const override { return true; }
454 };
455 
456 class NonreferenceTypeConceptNode public ConceptNode
457 {
458 public:
459     NonreferenceTypeConceptNode();
460     NonreferenceTypeConceptNode(const Span& span_const boost::uuids::uuid& moduleId_);
461     bool IsIntrinsicConceptNode() const override { return true; }
462 };
463 
464 } } // namespace sngcm::ast
465 
466 #endif // SNGCM_AST_CONCEPT_INCLUDED