1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGCM_AST_NODE_INCLUDED
  7 #define SNGCM_AST_NODE_INCLUDED
  8 #include <sngcm/ast/AstApi.hpp>
  9 #include <soulng/lexer/Span.hpp>
 10 #include <sngcm/ast/Clone.hpp>
 11 #include <sngcm/ast/Specifier.hpp>
 12 #include <soulng/util/Error.hpp>
 13 #include <memory>
 14 #include <stdint.h>
 15 
 16 namespace sngcm { namespace ast {
 17 
 18 using soulng::lexer::Span;
 19 
 20 class Visitor;
 21 class AstWriter;
 22 class AstReader;
 23 class ParameterNode;
 24 class TemplateParameterNode;
 25 
 26 enum class NodeType : uint8_t 
 27 {
 28     boolNodesbyteNodebyteNodeshortNodeushortNodeintNodeuintNodelongNodeulongNodefloatNodedoubleNodecharNodewcharNodeucharNodevoidNode
 29     booleanLiteralNodesbyteLiteralNodebyteLiteralNodeshortLiteralNodeushortLiteralNodeintLiteralNodeuintLiteralNodelongLiteralNodeulongLiteralNode
 30     floatLiteralNodedoubleLiteralNodecharLiteralNodewcharLiteralNodeucharLiteralNodestringLiteralNodewstringLiteralNodeustringLiteralNodenullLiteralNodearrayLiteralNodestructuredLiteralNode
 31     compileUnitNodenamespaceNodealiasNodenamespaceImportNodeidentifierNodetemplateIdNodefunctionNode
 32     classNodethisInitializerNodebaseInitializerNodememberInitializerNodestaticConstructorNodeconstructorNodedestructorNodememberFunctionNodeconversionFunctionNode
 33     memberVariableNode
 34     interfaceNodedelegateNodeclassDelegateNode
 35     parenthesizedConstraintNodedisjunctiveConstraintNodeconjunctiveConstraintNodewhereConstraintNodepredicateConstraintNodeisConstraintNodemultiParamConstraintNodetypeNameConstraintNode
 36     constructorConstraintNodedestructorConstraintNodememberFunctionConstraintNodefunctionConstraintNode
 37     sameConstraintNodederivedConstraintNodeconvertibleConstraintNodeexplicitlyConvertibleConstraintNodecommonConstraintNodenonreferenceTypeConstraintNode
 38     axiomStatementNodeaxiomNodeconceptIdNodeconceptNode
 39     sameConceptNodederivedConceptNodeconvertibleConceptNodeexplicitlyConvertibleConceptNodecommonConceptNodenonreferenceTypeConceptNode
 40     labelNodecompoundStatementNodereturnStatementNodeifStatementNodewhileStatementNodedoStatementNodeforStatementNodebreakStatementNodecontinueStatementNode
 41     gotoStatementNodeconstructionStatementNodedeleteStatementNodedestroyStatementNodeassignmentStatementNodeexpressionStatementNodeemptyStatementNode
 42     rangeForStatementNodeswitchStatementNodecaseStatementNodedefaultStatementNodegotoCaseStatementNodegotoDefaultStatementNode
 43     throwStatementNodecatchNodetryStatementNodeassertStatementNode
 44     typedefNodeconstantNodeenumTypeNodeenumConstantNodeparameterNodetemplateParameterNode
 45     constNodelvalueRefNodervalueRefNodepointerNodearrayNode
 46     dotNodearrowNodeequivalenceNodeimplicationNodedisjunctionNodeconjunctionNodebitOrNodebitXorNodebitAndNode
 47     equalNodenotEqualNodelessNodegreaterNodelessOrEqualNodegreaterOrEqualNodeshiftLeftNodeshiftRightNode
 48     addNodesubNodemulNodedivNoderemNodenotNodeunaryPlusNodeunaryMinusNodeprefixIncrementNodeprefixDecrementNodecomplementNodederefNodeaddrOfNode
 49     isNodeasNodeindexingNodeinvokeNodepostfixIncrementNodepostfixDecrementNodesizeOfNodetypeNameNodetypeIdNodecastNodeconstructNodenewNodethisNodebaseNode
 50     conditionalCompilationDisjunctionNodeconditionalCompilationConjunctionNodeconditionalCompilationNotNodeconditionalCompilationPrimaryNodeconditionalCompilationPartNodeconditionalCompilationStatementNode
 51     uuidLiteralNodecursorIdNodeparenthesizedExpressionNodeglobalVariableNodeparenthesizedCondCompExpressionNodelabeledStatementNodecommentNode
 52     maxNode
 53 };
 54 
 55 std::string NodeTypeStr(NodeType nodeType);
 56 
 57 class Node 
 58 {
 59 public:
 60     Node(NodeType nodeType_const Span& span_);
 61     virtual ~Node();
 62     Node(const Node&) = delete;
 63     Node& operator=(const Node&) = delete;
 64     NodeType GetNodeType() const { return nodeType; }
 65     virtual Node* Clone(CloneContext& cloneContext) const = 0;
 66     virtual void Accept(Visitor& visitor) = 0;
 67     virtual void Write(AstWriter& writer);
 68     virtual void Read(AstReader& reader);
 69     virtual void SetFullSpan();
 70     virtual std::string ToString() const { return std::string(); }
 71     virtual void AddArgument(Node* argument) { Assert(false"AddArgument not overridden");  }
 72     virtual void AddParameter(ParameterNode* parameter) { Assert(false"AddParameter not overridden"); }
 73     virtual void AddTemplateParameter(TemplateParameterNode* templateParameter) { Assert(false"AddTemplateParameter not overridden"); }
 74     virtual bool IsUnsignedTypeNode() const { return false; }
 75     virtual bool IsStatementNode() const { return false; }
 76     virtual bool NodeIsConstraintNode() const { return false; }
 77     virtual bool IsConceptNode() const { return false; }
 78     virtual bool IsFunctionNode() const { return false; }
 79     virtual bool IsIntrinsicConceptNode() const { return false; }
 80     virtual bool IsConditionalCompilationExpressionNode() const { return false; }
 81     virtual Specifiers GetSpecifiers() const { return Specifiers::none; }
 82     const Span& GetSpan() const { return span; }
 83     void SetSpan(const Span& span_) { span = span_; }
 84     void SetSpanStart(int32_t spanStart) { span.start = spanStart; }
 85     void SetSpanEnd(int end) { span.end = end; }
 86     const Node* Parent() const { return parent; }
 87     Node* Parent() { return parent; }
 88     void SetParent(Node* parent_);
 89 private:
 90     NodeType nodeType;
 91     Span span;
 92     Node* parent;
 93 };
 94 
 95 class UnaryNode public Node
 96 {
 97 public:
 98     UnaryNode(NodeType nodeTypeconst Span& span_);
 99     UnaryNode(NodeType nodeTypeconst Span& span_Node* subject_);
100     void Write(AstWriter& writer) override;
101     void Read(AstReader& reader) override;
102     void SetFullSpan() override;
103     const Node* Subject() const { return subject.get(); }
104     Node* Subject() { return subject.get(); }
105 private:
106     std::unique_ptr<Node> subject;
107 };
108 
109 class BinaryNode public Node
110 {
111 public:
112     BinaryNode(NodeType nodeTypeconst Span& span_);
113     BinaryNode(NodeType nodeTypeconst Span& span_Node* left_Node* right_);
114     void Write(AstWriter& writer) override;
115     void Read(AstReader& reader) override;
116     void SetFullSpan() override;
117     const Node* Left() const { return left.get(); }
118     Node* Left() { return left.get(); }
119     const Node* Right() const { return right.get(); }
120     Node* Right() { return right.get(); }
121 private:
122     std::unique_ptr<Node> left;
123     std::unique_ptr<Node> right;
124 };
125 
126 class NodeCreator 
127 {
128 public:
129     NodeCreator();
130     NodeCreator(const NodeCreator&) = delete;
131     NodeCreator& operator=(const NodeCreator&) = delete;
132     virtual ~NodeCreator();
133     virtual Node* CreateNode(const Span& span) = 0;
134 };
135 
136 class NodeFactory 
137 {
138 public:
139     NodeFactory(const NodeFactory&) = delete;
140     NodeFactory& operator=(const NodeFactory&) = delete;
141     static NodeFactory& Instance() { Assert(instance"node factory not initialized"); return *instance; }
142     static void Init();
143     static void Done();
144     void Register(NodeType nodeTypeNodeCreator* creator);
145     Node* CreateNode(NodeType nodeTypeconst Span& span);
146 private:
147     static std::unique_ptr<NodeFactory> instance;
148     std::vector<std::std::unique_ptr<NodeCreator>>creators;
149     NodeFactory();
150 };
151 
152 void NodeInit();
153 void NodeDone();
154 
155 } } // namespace sngcm::ast
156 
157 #endif // SNGCM_AST_NODE_INCLUDED