2023-08-31 19:25:00 +00:00
|
|
|
#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;
|
2023-08-31 19:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*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--;
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:25:00 +00:00
|
|
|
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 19:25:00 +00:00
|
|
|
|
2023-08-31 23:22:51 +00:00
|
|
|
m_entries.push_back(SymEntry {
|
|
|
|
name,
|
|
|
|
SymTable::addr++,
|
|
|
|
m_scope,
|
|
|
|
node,
|
|
|
|
false
|
|
|
|
});
|
2023-08-31 19:25:00 +00:00
|
|
|
|
|
|
|
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 19:25:00 +00:00
|
|
|
|
2023-08-31 23:22:51 +00:00
|
|
|
return addr;
|
2023-08-31 19:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2023-08-31 19:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2023-08-31 19:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2023-08-31 19:25:00 +00:00
|
|
|
}
|
|
|
|
}
|