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