Files
mysysy/olddef.h

62 lines
1.5 KiB
C++

class SymbolTable{
private:
enum Kind
{
kModule,
kFunction,
kBlock,
};
std::forward_list<std::pair<Kind, std::unordered_map<std::string, Value*>>> Scopes;
public:
struct ModuleScope {
SymbolTable& tables_ref;
ModuleScope(SymbolTable& tables) : tables_ref(tables) {
tables.enter(kModule);
}
~ModuleScope() { tables_ref.exit(); }
};
struct FunctionScope {
SymbolTable& tables_ref;
FunctionScope(SymbolTable& tables) : tables_ref(tables) {
tables.enter(kFunction);
}
~FunctionScope() { tables_ref.exit(); }
};
struct BlockScope {
SymbolTable& tables_ref;
BlockScope(SymbolTable& tables) : tables_ref(tables) {
tables.enter(kBlock);
}
~BlockScope() { tables_ref.exit(); }
};
SymbolTable() = default;
bool isModuleScope() const { return Scopes.front().first == kModule; }
bool isFunctionScope() const { return Scopes.front().first == kFunction; }
bool isBlockScope() const { return Scopes.front().first == kBlock; }
Value *lookup(const std::string &name) const {
for (auto &scope : Scopes) {
auto iter = scope.second.find(name);
if (iter != scope.second.end())
return iter->second;
}
return nullptr;
}
auto insert(const std::string &name, Value *value) {
assert(not Scopes.empty());
return Scopes.front().second.emplace(name, value);
}
private:
void enter(Kind kind) {
Scopes.emplace_front();
Scopes.front().first = kind;
}
void exit() {
Scopes.pop_front();
}
};