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     boolNode, sbyteNode, byteNode, shortNode, ushortNode, intNode, uintNode, longNode, ulongNode, floatNode, doubleNode, charNode, wcharNode, ucharNode, voidNode, 
 29     booleanLiteralNode, sbyteLiteralNode, byteLiteralNode, shortLiteralNode, ushortLiteralNode, intLiteralNode, uintLiteralNode, longLiteralNode, ulongLiteralNode, 
 30     floatLiteralNode, doubleLiteralNode, charLiteralNode, wcharLiteralNode, ucharLiteralNode, stringLiteralNode, wstringLiteralNode, ustringLiteralNode, nullLiteralNode, arrayLiteralNode, structuredLiteralNode, 
 31     compileUnitNode, namespaceNode, aliasNode, namespaceImportNode, identifierNode, templateIdNode, functionNode, 
 32     classNode, thisInitializerNode, baseInitializerNode, memberInitializerNode, staticConstructorNode, constructorNode, destructorNode, memberFunctionNode, conversionFunctionNode, 
 33     memberVariableNode, 
 34     interfaceNode, delegateNode, classDelegateNode, 
 35     parenthesizedConstraintNode, disjunctiveConstraintNode, conjunctiveConstraintNode, whereConstraintNode, predicateConstraintNode, isConstraintNode, multiParamConstraintNode, typeNameConstraintNode, 
 36     constructorConstraintNode, destructorConstraintNode, memberFunctionConstraintNode, functionConstraintNode, 
 37     sameConstraintNode, derivedConstraintNode, convertibleConstraintNode, explicitlyConvertibleConstraintNode, commonConstraintNode, nonreferenceTypeConstraintNode, 
 38     axiomStatementNode, axiomNode, conceptIdNode, conceptNode, 
 39     sameConceptNode, derivedConceptNode, convertibleConceptNode, explicitlyConvertibleConceptNode, commonConceptNode, nonreferenceTypeConceptNode, 
 40     labelNode, compoundStatementNode, returnStatementNode, ifStatementNode, whileStatementNode, doStatementNode, forStatementNode, breakStatementNode, continueStatementNode, 
 41     gotoStatementNode, constructionStatementNode, deleteStatementNode, destroyStatementNode, assignmentStatementNode, expressionStatementNode, emptyStatementNode, 
 42     rangeForStatementNode, switchStatementNode, caseStatementNode, defaultStatementNode, gotoCaseStatementNode, gotoDefaultStatementNode, 
 43     throwStatementNode, catchNode, tryStatementNode, assertStatementNode, 
 44     typedefNode, constantNode, enumTypeNode, enumConstantNode, parameterNode, templateParameterNode, 
 45     constNode, lvalueRefNode, rvalueRefNode, pointerNode, arrayNode, 
 46     dotNode, arrowNode, equivalenceNode, implicationNode, disjunctionNode, conjunctionNode, bitOrNode, bitXorNode, bitAndNode, 
 47     equalNode, notEqualNode, lessNode, greaterNode, lessOrEqualNode, greaterOrEqualNode, shiftLeftNode, shiftRightNode, 
 48     addNode, subNode, mulNode, divNode, remNode, notNode, unaryPlusNode, unaryMinusNode, prefixIncrementNode, prefixDecrementNode, complementNode, derefNode, addrOfNode, 
 49     isNode, asNode, indexingNode, invokeNode, postfixIncrementNode, postfixDecrementNode, sizeOfNode, typeNameNode, typeIdNode, castNode, constructNode, newNode, thisNode, baseNode, 
 50     conditionalCompilationDisjunctionNode, conditionalCompilationConjunctionNode, conditionalCompilationNotNode, conditionalCompilationPrimaryNode, conditionalCompilationPartNode, conditionalCompilationStatementNode, 
 51     uuidLiteralNode, cursorIdNode, parenthesizedExpressionNode, globalVariableNode, parenthesizedCondCompExpressionNode, labeledStatementNode, commentNode, 
 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 nodeType, const Span& span_);
 99     UnaryNode(NodeType nodeType, const 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 nodeType, const Span& span_);
113     BinaryNode(NodeType nodeType, const 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 nodeType, NodeCreator* creator);
145     Node* CreateNode(NodeType nodeType, const 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