forked from lcompilers/lpython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
asr_scopes.h
103 lines (83 loc) · 3.13 KB
/
asr_scopes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifndef LFORTRAN_SEMANTICS_ASR_SCOPES_H
#define LFORTRAN_SEMANTICS_ASR_SCOPES_H
#include <map>
#include <libasr/alloc.h>
#include <libasr/containers.h>
namespace LCompilers {
namespace ASR {
struct asr_t;
struct stmt_t;
struct symbol_t;
}
struct SymbolTable {
private:
std::map<std::string, ASR::symbol_t*> scope;
public:
SymbolTable *parent;
// The ASR node (either symbol_t or TranslationUnit_t) that contains this
// SymbolTable as m_symtab member. One of:
// * symbol_symtab(down_cast<symbol_t>(this->asr_owner)) == this
// * down_cast2<TranslationUnit_t>(this->asr_owner)->m_symtab == this
ASR::asr_t *asr_owner = nullptr;
unsigned int counter;
SymbolTable(SymbolTable *parent);
// Determines a stable hash based on the content of the symbol table
uint32_t get_hash_uint32(); // Returns the hash as an integer
std::string get_counter() { // Returns a unique ID as a string
return std::to_string(counter);
}
static void reset_global_counter(); // Resets the internal global counter
// Resolves the symbol `name` recursively in current and parent scopes.
// Returns `nullptr` if symbol not found.
ASR::symbol_t* resolve_symbol(const std::string &name) {
if (scope.find(name) == scope.end()) {
if (parent) {
return parent->resolve_symbol(name);
} else {
return nullptr;
}
}
return scope[name];
}
const std::map<std::string, ASR::symbol_t*>& get_scope() const {
return scope;
}
// Obtains the symbol `name` from the current symbol table
// Returns `nullptr` if symbol not found.
ASR::symbol_t* get_symbol(const std::string &name) const {
//auto it = scope.find(to_lower(name));
auto it = scope.find(name);
if (it == scope.end()) {
return nullptr;
} else {
return it->second;
}
}
void erase_symbol(const std::string &name) {
//auto it = scope.find(to_lower(name));
LCOMPILERS_ASSERT(scope.find(name) != scope.end())
scope.erase(name);
}
// Add a new symbol that did not exist before
void add_symbol(const std::string &name, ASR::symbol_t* symbol) {
LCOMPILERS_ASSERT(scope.find(name) == scope.end())
scope[name] = symbol;
}
// Overwrite an existing symbol
void overwrite_symbol(const std::string &name, ASR::symbol_t* symbol) {
LCOMPILERS_ASSERT(scope.find(name) != scope.end())
scope[name] = symbol;
}
// Use as the last resort, prefer to always either add a new symbol
// or overwrite an existing one, not both
void add_or_overwrite_symbol(const std::string &name, ASR::symbol_t* symbol) {
scope[name] = symbol;
}
// Marks all variables as external
void mark_all_variables_external(Allocator &al);
ASR::symbol_t *find_scoped_symbol(const std::string &name,
size_t n_scope_names, char **m_scope_names);
std::string get_unique_name(const std::string &name, bool use_unique_id=true);
};
} // namespace LCompilers
#endif // LFORTRAN_SEMANTICS_ASR_SCOPES_H