1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_BINDER_OPERATION_REPOSITORY_INCLUDED
  7 #define CMAJOR_BINDER_OPERATION_REPOSITORY_INCLUDED
  8 #include <cmajor/binder/BoundExpression.hpp>
  9 #include <cmajor/symbols/Exception.hpp>
 10 #include <cmajor/symbols/FunctionSymbol.hpp>
 11 #include <sngcm/ast/Class.hpp>
 12 
 13 namespace cmajor { namespace binder {
 14 
 15 using namespace cmajor::symbols;
 16 using namespace sngcm::ast;
 17 
 18 class BoundCompileUnit;
 19 class BoundClass;
 20 class BoundFunction;
 21 class BoundCompoundStatement;
 22 class StatementBinder;
 23 
 24 enum class CollectFlags : int 
 25 {
 26     none=  0noRvalueRef=  1 << 0
 27 };
 28 
 29 inline CollectFlags operator|(CollectFlags leftCollectFlags right)
 30 {
 31     return static_cast<CollectFlags>(static_cast<int>(left) | static_cast<int>(right));
 32 }
 33 
 34 inline CollectFlags operator&(CollectFlags leftCollectFlags right)
 35 {
 36     return static_cast<CollectFlags>(static_cast<int>(left) & static_cast<int>(right));
 37 }
 38 
 39 class Operation 
 40 {
 41 public:
 42     Operation(const std::u32string& groupName_int arity_BoundCompileUnit& boundCompileUnit_);
 43     virtual ~Operation();
 44     virtual void CollectViableFunctions(ContainerScope* containerScope_const std::std::vector<std::std::unique_ptr<BoundExpression>>&argumentsBoundFunction*currentFunction
 45         ViableFunctionSet& viableFunctionsstd::std::unique_ptr<Exception>&exceptionconstSpan&spanconstboost::uuids::uuid&moduleIdCollectFlags flags) = 0;
 46     const std::u32string& GroupName() const { return groupName; }
 47     int Arity() const { return arity; }
 48     SymbolTable* GetSymbolTable();
 49     BoundCompileUnit& GetBoundCompileUnit();
 50 private:
 51     std::u32string groupName;
 52     int arity;
 53     BoundCompileUnit& boundCompileUnit;
 54 };
 55 
 56 class ArityOperation 
 57 {
 58 public:
 59     void Add(Operation* operation);
 60     void CollectViableFunctions(ContainerScope* containerScopeconst std::std::vector<std::std::unique_ptr<BoundExpression>>&argumentsBoundFunction*currentFunction
 61         ViableFunctionSet& viableFunctionsstd::std::unique_ptr<Exception>&exceptionconstSpan&spanconstboost::uuids::uuid&moduleIdCollectFlags flags);
 62 private:
 63     std::vector<Operation*> operations;
 64 };
 65 
 66 class OperationGroup 
 67 {
 68 public:
 69     void Add(Operation* operation);
 70     void CollectViableFunctions(ContainerScope* containerScopeconst std::std::vector<std::std::unique_ptr<BoundExpression>>&argumentsBoundFunction*currentFunction
 71         ViableFunctionSet& viableFunctions std::std::unique_ptr<Exception>&exceptionconstSpan&spanconstboost::uuids::uuid&moduleIdCollectFlags flags);
 72 private:
 73     std::vector<std::std::unique_ptr<ArityOperation>>arityOperations;
 74 };
 75 
 76 class OperationRepository 
 77 {
 78 public:
 79     OperationRepository(BoundCompileUnit& boundCompileUnit_);
 80     void Add(Operation* operation);
 81     void CollectViableFunctions(const std::u32string& groupNameContainerScope* containerScopeconst std::std::vector<std::std::unique_ptr<BoundExpression>>&arguments
 82         BoundFunction* currentFunctionViableFunctionSet& viableFunctionsstd::std::unique_ptr<Exception>&exceptionconstSpan&spanconstboost::uuids::uuid&modukeIdCollectFlags flags);
 83     void GenerateCopyConstructorFor(ClassTypeSymbol* classTypeSymbolContainerScope* containerScopeBoundFunction* currentFunctionconst Span& spanconst boost::uuids::uuid& moduleId);
 84     void GenerateCopyConstructorFor(InterfaceTypeSymbol* interfaceTypeSymbolContainerScope* containerScopeBoundFunction* currentFunctionconst Span& spanconst boost::uuids::uuid& moduleId);
 85 private:
 86     BoundCompileUnit& boundCompileUnit;
 87     std::unordered_map<std::u32stringOperationGroup*> operationGroupMap;
 88     std::vector<std::std::unique_ptr<OperationGroup>>operationGroups;
 89     std::vector<std::std::unique_ptr<Operation>>operations;
 90     Operation* copyConstructorOperation;
 91 };
 92 
 93 void GenerateDestructorImplementation(BoundClass* boundClassDestructorSymbol* destructorSymbolBoundCompileUnit& boundCompileUnitContainerScope* containerScopeBoundFunction* currentFunction
 94     const Span& spanconst boost::uuids::uuid& moduleId);
 95 void GenerateStaticClassInitialization(StaticConstructorSymbol* staticConstructorSymbolStaticConstructorNode* staticConstructorNodeBoundCompileUnit& boundCompileUnit
 96     BoundCompoundStatement* boundCompoundStatementBoundFunction* boundFunctionContainerScope* containerScopeStatementBinder* statementBinderconst Span& spanconst boost::uuids::uuid& moduleId);
 97 void GenerateClassInitialization(ConstructorSymbol* constructorSymbolConstructorNode* constructorNodeBoundCompoundStatement* boundCompoundStatementBoundFunction* boundFunction
 98     BoundCompileUnit& boundCompileUnitContainerScope* containerScopeStatementBinder* statementBinderbool generateDefaultconst Span& spanconst boost::uuids::uuid& moduleId);
 99 void GenerateClassAssignment(MemberFunctionSymbol* assignmentFunctionSymbolMemberFunctionNode* assignmentNodeBoundCompoundStatement* boundCompoundStatementBoundFunction* boundFunction
100     BoundCompileUnit& boundCompileUnitContainerScope* containerScopeStatementBinder* statementBinderbool generateDefaultconst Span& spanconst boost::uuids::uuid& moduleId);
101 void GenerateClassTermination(DestructorSymbol* destructorSymbolDestructorNode* destructorNodeBoundCompoundStatement* boundCompoundStatementBoundFunction* boundFunction
102     BoundCompileUnit& boundCompileUnitContainerScope* containerScopeStatementBinder* statementBinderconst Span& spanconst boost::uuids::uuid& moduleId);
103 
104 } } // namespace cmajor::binder
105 
106 #endif // CMAJOR_BINDER_OPERATION_REPOSITORY_INCLUDED