#include "scope.hpp"
unsigned Scope::num = 0;
Scope::Scope(): parent(NULL) {
}
Scope::Scope(const Scope* p): parent(p) {
}
Scope::~Scope() {
for (std::vector<var_t>::iterator it = vars.begin(); it != vars.end(); ++it) {
free(it->name);
}
}
unsigned Scope::push() {
return ++num;
}
unsigned Scope::push(const char* v) {
return push(v, strlen(v));
}
unsigned Scope::push(const char* v, size_t l) {
if (find(v, l)) return 0;
unsigned id = ++num;
vars.push_back((var_t){strndup(v, l), id});
return id;
}
void Scope::pop(unsigned id) {
for (std::vector<var_t>::iterator it = vars.begin(); it != vars.end(); ++it) {
if (it->id == id) {
free(it->name);
vars.erase(it);
return;
}
}
assert(false);
}
unsigned Scope::pop() {
if (!vars.size()) return 0;
unsigned rv = vars.back().id;
assert(rv);
free(vars.back().name);
vars.pop_back();
return rv;
}
unsigned Scope::find(const char* v, bool* this_lvl) const {
return find(v, strlen(v), this_lvl);
}
unsigned Scope::find(const char* v, size_t l, bool* this_lvl) const {
if (this_lvl) *this_lvl = false;
for (std::vector<var_t>::const_iterator it = vars.begin(); it != vars.end(); ++it) {
if (l == strlen(it->name) && !strncmp(it->name, v, l)) {
if (this_lvl) *this_lvl = true;
return it->id;
}
}
return parent? parent->find(v, l): 0;
}