1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_SYMBOLS_SCOPE_INCLUDED
  7 #define CMAJOR_SYMBOLS_SCOPE_INCLUDED
  8 #include <cmajor/symbols/SymbolsApi.hpp>
  9 #include <sngcm/ast/Namespace.hpp>
 10 #include <unordered_map>
 11 #include <unordered_set>
 12 
 13 namespace cmajor { namespace symbols {
 14 
 15 using soulng::lexer::Span;
 16 using namespace sngcm::ast;
 17 
 18 class Symbol;
 19 class ContainerSymbol;
 20 class NamespaceSymbol;
 21 class FunctionSymbol;
 22 class Module;
 23 class ViableFunctionSet;
 24 
 25 enum class ScopeLookup : uint8_t 
 26 {
 27     none=  0
 28     this_=  1 << 0
 29     base=  1 << 1
 30     parent=  1 << 2
 31     this_and_base=  this_ | base
 32     this_and_parent=  this_ | parent
 33     this_and_base_and_parent=  this_ | base | parent
 34     fileScopes=  1 << 3
 35 };
 36 
 37 inline ScopeLookup operator&(ScopeLookup leftScopeLookup right)
 38 {
 39     return ScopeLookup(uint8_t(left) & uint8_t(right));
 40 }
 41 
 42 inline ScopeLookup operator~(ScopeLookup subject)
 43 {
 44     return ScopeLookup(~uint8_t(subject));
 45 }
 46 
 47 struct CCSymbolEntry 
 48 {
 49     CCSymbolEntry(Symbol* symbol_int ccPrefixLen_const std::u32string& replacement_) : symbol(symbol_)ccPrefixLen(ccPrefixLen_)replacement(replacement_) {}
 50     Symbol* symbol;
 51     int ccPrefixLen;
 52     std::u32string replacement;
 53 };
 54 
 55 void AddMatches(std::std::vector<CCSymbolEntry>&matchesstd::std::vector<CCSymbolEntry>&matchesToAdd);
 56 
 57 enum class CCComponentSeparator : int8_t 
 58 {
 59     dot=  0arrow=  1
 60 };
 61 
 62 struct CCComponent 
 63 {
 64     CCComponent(CCComponentSeparator separator_const std::u32string& str_) : separator(separator_)str(str_) {}
 65     CCComponentSeparator separator;
 66     std::u32string str;
 67 };
 68 
 69 class Scope 
 70 {
 71 public:
 72     virtual ~Scope();
 73     virtual Symbol* Lookup(const std::u32string& name) const = 0;
 74     virtual Symbol* Lookup(const std::u32string& nameScopeLookup lookup) const = 0;
 75     virtual std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix) const = 0;
 76     virtual std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefixScopeLookup lookup) const = 0;
 77 };
 78 
 79 class ContainerScope public Scope
 80 {
 81 public:
 82     ContainerScope();
 83     ContainerScope* BaseScope() const;
 84     ContainerScope* ParentScope() const;
 85     void SetParentScope(ContainerScope* parentScope_) { parentScope = parentScope_; }
 86     ContainerSymbol* Container() { return container; }
 87     const ContainerSymbol* Container() const { return container; }
 88     void SetContainer(ContainerSymbol* container_) { container = container_; }
 89     void Install(Symbol* symbol);
 90     void Uninstall(Symbol* symbol);
 91     Symbol* Lookup(const std::u32string& name) const override;
 92     Symbol* Lookup(const std::u32string& nameScopeLookup lookup) const override;
 93     Symbol* LookupQualified(const std::std::vector<std::u32string>&componentsScopeLookuplookup) const;
 94     std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix) const override;
 95     std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefixScopeLookup lookup) const override;
 96     std::vector<CCSymbolEntry> LookupQualifiedBeginWith(const std::std::vector<CCComponent>&componentsScopeLookuplookup) const;
 97     const NamespaceSymbol* Ns() const;
 98     NamespaceSymbol* Ns();
 99     void Clear();
100     NamespaceSymbol* CreateNamespace(const std::u32string& qualifiedNsNameconst Span& spanconst boost::uuids::uuid& sourceModuleId);
101     void CollectViableFunctions(int arityconst std::u32string& groupNamestd::std::unordered_set<ContainerScope*>&scopesLookedUpScopeLookupscopeLookup
102         ViableFunctionSet& viableFunctionsModule* module);
103     const std::std::map<std::u32stringSymbol*>&SymbolMap() const{returnsymbolMap;}
104 private:
105     ContainerSymbol* container;
106     ContainerScope* parentScope;
107     std::map<std::u32stringSymbol*> symbolMap;
108 };
109 
110 class FileScope public Scope
111 {
112 public:
113     FileScope();
114     void InstallAlias(ContainerScope* containerScopeAliasNode* aliasNode);
115     void AddContainerScope(ContainerScope* containerScope);
116     void InstallNamespaceImport(ContainerScope* containerScopeNamespaceImportNode* namespaceImportNode);
117     Symbol* Lookup(const std::u32string& name) const override;
118     Symbol* Lookup(const std::u32string& nameScopeLookup lookup) const override;
119     std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix) const override;
120     std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefixScopeLookup lookup) const override;
121     void CollectViableFunctions(int arityconst std::u32string&  groupNamestd::std::unordered_set<ContainerScope*>&scopesLookedUpViableFunctionSet&viableFunctions
122         Module* module);
123 private:
124     std::vector<ContainerScope*> containerScopes;
125     std::map<std::u32stringSymbol*> aliasSymbolMap;
126 };
127 
128 } } // namespace cmajor::symbols
129 
130 #endif // CMAJOR_SYMBOLS_SCOPE_INCLUDED