Document symbol bag class and methods

This commit is contained in:
2025-08-23 00:48:58 +02:00
parent 809e41bcc3
commit 8fc60202ff
9 changed files with 168 additions and 52 deletions

View File

@@ -205,18 +205,16 @@ namespace elna::boot
void name_analysis_visitor::visit(type_declaration *definition)
{
definition->body().accept(this);
auto unresolved_declaration = this->bag.unresolved.at(definition->identifier.identifier);
unresolved_declaration->reference = this->current_type;
this->bag.resolve(definition->identifier.identifier, this->current_type);
}
void name_analysis_visitor::visit(named_type_expression *type_expression)
{
auto unresolved_alias = this->bag.unresolved.find(type_expression->name);
auto unresolved_alias = this->bag.declared(type_expression->name);
if (unresolved_alias != this->bag.unresolved.end())
if (unresolved_alias != nullptr)
{
this->current_type = type(unresolved_alias->second);
this->current_type = type(unresolved_alias);
}
else if (auto from_symbol_table = this->bag.lookup(type_expression->name))
{
@@ -301,7 +299,11 @@ namespace elna::boot
for (const auto& variable_identifier : declaration->identifiers)
{
this->bag.enter(variable_identifier.identifier, std::make_shared<variable_info>(this->current_type));
if (!this->bag.enter(variable_identifier.identifier, std::make_shared<variable_info>(this->current_type)))
{
add_error<already_declared_error>(variable_identifier.identifier, this->input_file,
declaration->position());
}
}
}
@@ -441,17 +443,17 @@ namespace elna::boot
}
bool name_analysis_visitor::check_unresolved_symbol(std::shared_ptr<alias_type> alias,
std::vector<std::string>& path)
std::vector<std::string>& alias_path)
{
if (std::find(std::cbegin(path), std::cend(path), alias->name) != std::cend(path))
if (std::find(std::cbegin(alias_path), std::cend(alias_path), alias->name) != std::cend(alias_path))
{
return false;
}
path.push_back(alias->name);
alias_path.push_back(alias->name);
if (auto another_alias = alias->reference.get<alias_type>())
{
return check_unresolved_symbol(another_alias, path);
return check_unresolved_symbol(another_alias, alias_path);
}
return true;
}
@@ -462,18 +464,18 @@ namespace elna::boot
{
type->accept(this);
}
for (auto& unresolved : this->bag.unresolved)
for (auto& unresolved : this->bag)
{
std::vector<std::string> path;
std::vector<std::string> alias_path;
if (check_unresolved_symbol(unresolved.second, path))
if (check_unresolved_symbol(unresolved.second, alias_path))
{
auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
this->bag.enter(unresolved.first, info);
}
else
{
add_error<cyclic_declaration_error>(path, this->input_file, position{ 0, 0 });
add_error<cyclic_declaration_error>(alias_path, this->input_file, position{ 0, 0 });
}
}
for (variable_declaration *const variable : unit->variables)

View File

@@ -358,14 +358,20 @@ namespace elna::boot
return result;
}
symbol_bag::symbol_bag()
symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> global_table)
: unresolved(unresolved)
{
this->symbols = std::make_shared<symbol_table>();
this->symbols = std::make_shared<symbol_table>(global_table);
}
symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> symbols)
: symbols(symbols), unresolved(unresolved)
forward_table::const_iterator symbol_bag::begin()
{
return unresolved.cbegin();
}
forward_table::const_iterator symbol_bag::end()
{
return unresolved.cend();
}
std::shared_ptr<info> symbol_bag::lookup(const std::string& name)
@@ -396,18 +402,31 @@ namespace elna::boot
this->symbols = child;
}
void symbol_bag::leave()
std::shared_ptr<symbol_table> symbol_bag::leave()
{
this->symbols = this->symbols->scope();
std::shared_ptr<symbol_table> result = this->symbols;
this->symbols = result->scope();
return result;
}
void symbol_bag::add_import(std::shared_ptr<symbol_table> table)
std::shared_ptr<alias_type> symbol_bag::declared(const std::string& symbol_name)
{
this->imports.push_front(table);
auto unresolved_alias = this->unresolved.find(symbol_name);
return unresolved_alias == this->unresolved.end() ? std::shared_ptr<alias_type>() : unresolved_alias->second;
}
std::shared_ptr<alias_type> symbol_bag::resolve(const std::string& symbol_name, type& resolution)
{
auto unresolved_declaration = this->unresolved.at(symbol_name);
unresolved_declaration->reference = resolution;
return unresolved_declaration;
}
void symbol_bag::add_import(const symbol_bag& bag)
{
add_import(bag.symbols);
this->imports.push_front(bag.symbols);
}
}