roza/lib/SymTable.cpp

141 lines
2.3 KiB
C++
Raw Normal View History

#include "SymTable.hpp"
namespace roza
{
/*static*/ int SymTable::addr = 0;
/*explicit*/ SymTable::SymTable()
{
}
/*explicit*/ SymTable::SymTable(SymTable const& sym_table)
{
m_scope = sym_table.m_scope;
2023-08-31 23:22:51 +00:00
m_entries = sym_table.m_entries;
}
/*virtual*/ SymTable::~SymTable()
{
}
2023-08-31 23:22:51 +00:00
void SymTable::enter_scope()
{
m_scope++;
}
void SymTable::leave_scope()
{
auto iter = std::begin(m_entries);
while (iter != std::end(m_entries))
{
if (iter->scope >= m_scope)
{
iter = m_entries.erase(iter);
}
else
{
iter++;
}
}
m_scope--;
}
int SymTable::declare(std::string const& name, std::shared_ptr<Node> node)
{
2023-08-31 23:22:51 +00:00
assert(!exists_in_scope(name));
2023-08-31 23:22:51 +00:00
m_entries.push_back(SymEntry {
name,
SymTable::addr++,
m_scope,
node,
false
});
return SymTable::addr - 1;
}
int SymTable::declare_mut(std::string const& name, std::shared_ptr<Node> node)
{
2023-08-31 23:22:51 +00:00
int addr = declare(name, node);
m_entries.back().is_mut = true;
2023-08-31 23:22:51 +00:00
return addr;
}
SymEntry& SymTable::find(std::string const& name)
{
assert(exists(name));
2023-08-31 23:22:51 +00:00
size_t idx = 0;
int scope = -1;
size_t i = 0;
for (auto const& entry: m_entries)
{
if (entry.name == name && entry.scope > scope)
{
idx = i;
scope = entry.scope;
}
i++;
}
assert(scope >= 0);
return m_entries[idx];
}
SymEntry const& SymTable::find(std::string const& name) const
{
assert(exists(name));
2023-08-31 23:22:51 +00:00
size_t idx = 0;
int scope = -1;
size_t i = 0;
for (auto const& entry: m_entries)
{
if (entry.name == name && entry.scope > scope)
{
idx = i;
scope = entry.scope;
}
i++;
}
assert(scope >= 0);
return m_entries[idx];
}
bool SymTable::exists(std::string const& name) const
{
2023-08-31 23:22:51 +00:00
for (auto const& entry: m_entries)
{
if (entry.name == name) { return true; }
}
return false;
}
bool SymTable::exists_in_scope(std::string const& name) const
{
for (auto const& entry: m_entries)
{
if (entry.name == name && entry.scope >= m_scope)
{
return true;
}
}
return false;
}
}