Randomize type declaration order

This commit is contained in:
2025-03-12 23:56:54 +01:00
parent c9a8ecdc0a
commit ac084be7f5
5 changed files with 48 additions and 28 deletions

View File

@ -21,16 +21,28 @@ namespace elna
{
namespace boot
{
declaration_error::declaration_error(const std::string& identifier, const char *path, const struct position position)
undeclared_error::undeclared_error(const std::string& identifier, const char *path, const struct position position)
: error(path, position), identifier(identifier)
{
}
std::string declaration_error::what() const
std::string undeclared_error::what() const
{
return "Type '" + identifier + "' not declared";
}
already_declared_error::already_declared_error(const std::string& identifier,
const char *path, const struct position position)
: error(path, position), identifier(identifier)
{
}
std::string already_declared_error::what() const
{
return "Symbol '" + identifier + "' has been already declared";
}
declaration_visitor::declaration_visitor(const char *path, std::shared_ptr<symbol_table> symbols)
: error_container(path), symbols(symbols)
{
@ -40,7 +52,10 @@ namespace boot
{
for (type_definition *const type : program->types)
{
this->unresolved.insert({ type->identifier, std::make_shared<alias_type>() });
if (!this->unresolved.insert({ type->identifier, std::make_shared<alias_type>() }).second)
{
add_error<already_declared_error>(type->identifier, this->input_file, type->position());
}
}
for (type_definition *const type : program->types)
{
@ -64,11 +79,14 @@ namespace boot
{
this->current_type = type(unresolved_alias->second);
}
else if (auto from_symbol_table = this->symbols.lookup(type_expression->name))
{
this->current_type = from_symbol_table->is_type()->symbol;
}
else
{
// TODO:
// add_error<declaration_error>(type_expression->name, this->input_file, type_expression->position());
this->current_type = type(std::make_shared<primitive_type>(type_expression->name));
add_error<undeclared_error>(type_expression->name, this->input_file, type_expression->position());
this->current_type = type();
}
}
@ -91,8 +109,10 @@ namespace boot
for (auto& field : type_expression->fields)
{
field.second->accept(this);
type_definition->fields.push_back({ field.first, type(this->current_type) });
if (!this->current_type.empty())
{
type_definition->fields.push_back({ field.first, type(this->current_type) });
}
}
this->current_type = type(type_definition);
}

View File

@ -15,8 +15,6 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#pragma once
#include "elna/boot/symbol.h"
namespace elna
@ -68,7 +66,7 @@ namespace boot
new (&alias) std::weak_ptr<alias_type>(other.alias);
break;
case type_tag::primitive:
new (&primitive) std::weak_ptr<primitive_type>(other.primitive);
new (&primitive) std::shared_ptr<primitive_type>(other.primitive);
break;
case type_tag::record:
new (&record) std::shared_ptr<record_type>(other.record);
@ -101,7 +99,7 @@ namespace boot
new (&alias) std::weak_ptr<alias_type>(std::move(other.alias));
break;
case type_tag::primitive:
new (&primitive) std::weak_ptr<primitive_type>(std::move(other.primitive));
new (&primitive) std::shared_ptr<primitive_type>(std::move(other.primitive));
break;
case type_tag::record:
new (&record) std::shared_ptr<record_type>(std::move(other.record));
@ -149,6 +147,7 @@ namespace boot
case type_tag::alias:
break;
case type_tag::primitive:
this->primitive.~shared_ptr<primitive_type>();
break;
case type_tag::record:
this->record.~shared_ptr<record_type>();
@ -183,7 +182,7 @@ namespace boot
{
if (tag == type_tag::primitive)
{
return this->primitive.lock();
return this->primitive;
}
else
{