1 // =================================
 2 // Copyright (c) 2020 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 #ifndef SNGCPP_SYMBOLS_SCOPE_INCLUDED
 7 #define SNGCPP_SYMBOLS_SCOPE_INCLUDED
 8 #include <sngcpp/symbols/SymbolsApi.hpp>
 9 #include <sngcpp/ast/Declaration.hpp>
10 #include <unordered_map>
11 #include <stdint.h>
12 
13 namespace sngcpp { namespace symbols {
14 
15 using namespace sngcpp::ast;
16 
17 enum class ScopeLookup : uint8_t 
18 {
19     none=  0
20     this_=  1 << 0
21     parent=  1 << 1
22     bases=  1 << 2
23     this_and_parent=  this_ | parent
24     this_and_bases=  this_ | bases
25     this_and_bases_and_parent=  this_ | bases | parent
26 };
27 
28 inline ScopeLookup operator&(ScopeLookup leftScopeLookup right)
29 {
30     return ScopeLookup(uint8_t(left) & uint8_t(right));
31 }
32 
33 inline ScopeLookup operator|(ScopeLookup leftScopeLookup right)
34 {
35     return ScopeLookup(uint8_t(left) | uint8_t(right));
36 }
37 
38 class Symbol;
39 class ContainerSymbol;
40 
41 class Scope 
42 {
43 public:
44     Scope();
45     Scope(const Scope&) = delete;
46     Scope(Scope&&) = delete;
47     Scope& operator=(const Scope&) = delete;
48     Scope& operator=(Scope&&) = delete;
49     virtual ~Scope();
50     virtual Symbol* Lookup(const std::u32string& name) = 0;
51     virtual Symbol* Lookup(const std::u32string& nameScopeLookup scopeLookup) = 0;
52     virtual Symbol* Lookup(const std::std::vector<std::u32string>&nameSequenceScopeLookupscopeLoookup) = 0;
53     Symbol* Lookup(Node* nameNode);
54     Symbol* Lookup(Node* nameNodeScopeLookup scopeLookup);
55 };
56 
57 class ContainerScope public Scope
58 {
59 public:
60     ContainerScope();
61     ContainerScope(ContainerSymbol* container_);
62     ContainerSymbol* Container() { return container; }
63     ContainerSymbol* GlobalNs();
64     void Install(Symbol* symbol);
65     Symbol* Lookup(const std::u32string& name) override;
66     Symbol* Lookup(const std::u32string& nameScopeLookup scopeLookup) override;
67     Symbol* Lookup(const std::std::vector<std::u32string>&nameSequenceScopeLookupscopeLoookup) override;
68 private:
69     ContainerSymbol* container;
70     std::unordered_map<std::u32stringSymbol*> symbolMap;
71 };
72 
73 class FileScope public Scope
74 {
75 public:
76     void Install(ContainerScope* containerScopeUsingDirectiveNode& usingDirectiveNode);
77     void Install(ContainerScope* containerScopeUsingDeclarationNode& usingDeclarationNode);
78     Symbol* Lookup(const std::u32string& name) override;
79     Symbol* Lookup(const std::u32string& nameScopeLookup scopeLookup) override;
80     Symbol* Lookup(const std::std::vector<std::u32string>&nameSequenceScopeLookupscopeLoookup) override;
81 private:
82     std::vector<ContainerScope*> containerScopes;
83     std::unordered_map<std::u32stringSymbol*> aliasSymbolMap;
84 };
85 
86 } } // namespace sngcpp::symbols
87 
88 #endif // SNGCPP_SYMBOLS_SCOPE_INCLUDED