CompilerSysY/include/scopetable.h
2023-05-02 17:20:35 +08:00

56 lines
1.3 KiB
C++

#pragma once
#include "common.h"
namespace antlrSysY {
template <typename T_V> class ScopeTable {
typedef std::map<std::string, T_V> ScopeTableEntry_t;
private:
std::vector<ScopeTableEntry_t> _scope_list;
public:
// On init, there is already an empty scope
ScopeTable() {
_scope_list.push_back(ScopeTableEntry_t());
}
~ScopeTable() {}
void enter_scope() {
_scope_list.push_back(ScopeTableEntry_t());
};
void leave_scope() {
if (_scope_list.size() <= 1)
throw GrammarException("Unable to leave global scope");
_scope_list.pop_back();
};
void push_name(const std::string &name, const T_V &value) {
auto &current_scope = _scope_list.back();
if (current_scope.count(name))
throw GrammarException("Duplicate name in current scope");
current_scope[name] = value;
};
std::optional<T_V> get_name(const std::string &name) {
for (auto i = _scope_list.size() - 1; i >= 0; --i) {
if (_scope_list[i].count(name)) {
return {_scope_list[i][name]};
}
}
return {};
};
std::optional<T_V> get_name(const std::string &name, int level) {
if (_scope_list[level].count(name)) {
return {_scope_list[level][name]};
}
return {};
};
int get_level() const {
return _scope_list.size() - 1;
}
};
}