1
2
3
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 left, ScopeLookup 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>&matches, std::std::vector<CCSymbolEntry>&matchesToAdd);
56
57 enum class CCComponentSeparator : int8_t
58 {
59 dot= 0, arrow= 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& name, ScopeLookup lookup) const = 0;
75 virtual std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix) const = 0;
76 virtual std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix, ScopeLookup 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& name, ScopeLookup lookup) const override;
93 Symbol* LookupQualified(const std::std::vector<std::u32string>&components, ScopeLookuplookup) const;
94 std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix) const override;
95 std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix, ScopeLookup lookup) const override;
96 std::vector<CCSymbolEntry> LookupQualifiedBeginWith(const std::std::vector<CCComponent>&components, ScopeLookuplookup) const;
97 const NamespaceSymbol* Ns() const;
98 NamespaceSymbol* Ns();
99 void Clear();
100 NamespaceSymbol* CreateNamespace(const std::u32string& qualifiedNsName, const Span& span, const boost::uuids::uuid& sourceModuleId);
101 void CollectViableFunctions(int arity, const std::u32string& groupName, std::std::unordered_set<ContainerScope*>&scopesLookedUp, ScopeLookupscopeLookup,
102 ViableFunctionSet& viableFunctions, Module* module);
103 const std::std::map<std::u32string, Symbol*>&SymbolMap() const{returnsymbolMap;}
104 private:
105 ContainerSymbol* container;
106 ContainerScope* parentScope;
107 std::map<std::u32string, Symbol*> symbolMap;
108 };
109
110 class FileScope : public Scope
111 {
112 public:
113 FileScope();
114 void InstallAlias(ContainerScope* containerScope, AliasNode* aliasNode);
115 void AddContainerScope(ContainerScope* containerScope);
116 void InstallNamespaceImport(ContainerScope* containerScope, NamespaceImportNode* namespaceImportNode);
117 Symbol* Lookup(const std::u32string& name) const override;
118 Symbol* Lookup(const std::u32string& name, ScopeLookup lookup) const override;
119 std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix) const override;
120 std::vector<CCSymbolEntry> LookupBeginWith(const std::u32string& prefix, ScopeLookup lookup) const override;
121 void CollectViableFunctions(int arity, const std::u32string& groupName, std::std::unordered_set<ContainerScope*>&scopesLookedUp, ViableFunctionSet&viableFunctions,
122 Module* module);
123 private:
124 std::vector<ContainerScope*> containerScopes;
125 std::map<std::u32string, Symbol*> aliasSymbolMap;
126 };
127
128 } }
129
130 #endif // CMAJOR_SYMBOLS_SCOPE_INCLUDED