#include "sem/SymbolTable.h"

SymbolTable::SymbolTable() {
  // Push global scope
  PushScope();
}

void SymbolTable::PushScope() {
  scopes_.emplace_back();
}

void SymbolTable::PopScope() {
  if (scopes_.size() > 1) {
    scopes_.pop_back();
  }
}

bool SymbolTable::Add(const std::string& name, const Symbol& symbol) {
  auto& current_scope = scopes_.back();
  if (current_scope.find(name) != current_scope.end()) {
    return false;
  }
  current_scope[name] = symbol;
  return true;
}

Symbol* SymbolTable::Lookup(const std::string& name) {
  for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
    auto search = it->find(name);
    if (search != it->end()) {
      return &search->second;
    }
  }
  return nullptr;
}

bool SymbolTable::IsInCurrentScope(const std::string& name) const {
  const auto& current_scope = scopes_.back();
  return current_scope.find(name) != current_scope.end();
}
