Add a symbol table with type info

This commit is contained in:
2025-03-09 00:53:13 +01:00
parent 868db6e0bf
commit f739194e06
9 changed files with 471 additions and 342 deletions

View File

@ -21,243 +21,18 @@ namespace elna
{
namespace boot
{
type::type()
: tag(type_tag::alias)
declaration_error::declaration_error(const std::string& identifier, const char *path, const struct position position)
: error(path, position), identifier(identifier)
{
}
type::type(std::shared_ptr<alias_type> alias)
: tag(type_tag::alias), alias(alias)
std::string declaration_error::what() const
{
return "Type '" + identifier + "' not declared";
}
type::type(std::shared_ptr<primitive_type> primitive)
: tag(type_tag::primitive), primitive(primitive)
{
}
type::type(std::shared_ptr<record_type> record)
: tag(type_tag::record), record(record)
{
}
type::type(std::shared_ptr<union_type> _union)
: tag(type_tag::_union), _union(_union)
{
}
type::type(std::shared_ptr<pointer_type> pointer)
: tag(type_tag::pointer), pointer(pointer)
{
}
type::type(std::shared_ptr<array_type> array)
: tag(type_tag::array), array(array)
{
}
void type::copy(const type& other)
{
switch (other.tag)
{
case type_tag::empty:
break;
case type_tag::alias:
new (&alias) std::weak_ptr<alias_type>(other.alias);
break;
case type_tag::primitive:
new (&primitive) std::weak_ptr<primitive_type>(other.primitive);
break;
case type_tag::record:
new (&record) std::shared_ptr<record_type>(other.record);
break;
case type_tag::_union:
new (&_union) std::shared_ptr<union_type>(other._union);
break;
case type_tag::pointer:
new (&pointer) std::shared_ptr<pointer_type>(other.pointer);
break;
case type_tag::array:
new (&array) std::shared_ptr<array_type>(other.array);
break;
}
}
type::type(const type& other)
: tag(other.tag)
{
copy(other);
}
void type::move(type&& other)
{
switch (other.tag)
{
case type_tag::empty:
break;
case type_tag::alias:
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));
break;
case type_tag::record:
new (&record) std::shared_ptr<record_type>(std::move(other.record));
break;
case type_tag::_union:
new (&_union) std::shared_ptr<union_type>(std::move(other._union));
break;
case type_tag::pointer:
new (&pointer) std::shared_ptr<pointer_type>(std::move(other.pointer));
break;
case type_tag::array:
new (&array) std::shared_ptr<array_type>(std::move(other.array));
break;
}
}
type& type::operator=(const type& other)
{
this->~type();
this->tag = other.tag;
copy(other);
return *this;
}
type::type(type&& other)
: tag(other.tag)
{
move(std::move(other));
}
type& type::operator=(type&& other)
{
this->~type();
this->tag = other.tag;
move(std::move(other));
return *this;
}
type::~type()
{
switch (tag)
{
case type_tag::empty:
break;
case type_tag::alias:
break;
case type_tag::primitive:
break;
case type_tag::record:
this->record.~shared_ptr<record_type>();
break;
case type_tag::_union:
this->_union.~shared_ptr<union_type>();
break;
case type_tag::pointer:
this->pointer.~shared_ptr<pointer_type>();
break;
case type_tag::array:
this->array.~shared_ptr<array_type>();
break;
}
}
template<>
std::shared_ptr<alias_type> type::get<alias_type>() const
{
if (tag == type_tag::alias)
{
return this->alias.lock();
}
else
{
return nullptr;
}
}
template<>
std::shared_ptr<primitive_type> type::get<primitive_type>() const
{
if (tag == type_tag::primitive)
{
return this->primitive.lock();
}
else
{
return nullptr;
}
}
template<>
std::shared_ptr<record_type> type::get<record_type>() const
{
if (tag == type_tag::record)
{
return this->record;
}
else
{
return nullptr;
}
}
template<>
std::shared_ptr<union_type> type::get<union_type>() const
{
if (tag == type_tag::_union)
{
return this->_union;
}
else
{
return nullptr;
}
}
template<>
std::shared_ptr<pointer_type> type::get<pointer_type>() const
{
if (tag == type_tag::pointer)
{
return this->pointer;
}
else
{
return nullptr;
}
}
template<>
std::shared_ptr<array_type> type::get<array_type>() const
{
if (tag == type_tag::array)
{
return this->array;
}
else
{
return nullptr;
}
}
bool type::empty() const
{
return tag == type_tag::empty;
}
pointer_type::pointer_type(type base)
: base(base)
{
}
array_type::array_type(type base, std::uint64_t size)
: base(base), size(size)
{
}
primitive_type::primitive_type(const std::string& identifier)
: identifier(identifier)
declaration_visitor::declaration_visitor(const char *path, std::shared_ptr<symbol_table> symbols)
: path(path), symbols(symbols)
{
}
@ -275,9 +50,8 @@ namespace boot
void declaration_visitor::visit(type_definition *definition)
{
auto unresolved_declaration = this->unresolved.at(definition->identifier);
definition->body().accept(this);
auto unresolved_declaration = this->unresolved.at(definition->identifier);
unresolved_declaration->reference = this->current_type;
}
@ -292,24 +66,36 @@ namespace boot
}
else
{
auto new_error = std::make_unique<declaration_error>(type_expression->name,
path, type_expression->position());
this->errors.emplace_back(std::move(new_error));
// TODO: Delete the next line.
this->current_type = type(std::make_shared<primitive_type>(type_expression->name));
}
}
void declaration_visitor::visit(array_type_expression *type_expression)
{
}
void declaration_visitor::visit(pointer_type_expression *type_expression)
{
type_expression->base().accept(this);
this->current_type = type(std::make_shared<pointer_type>(this->current_type));
}
void declaration_visitor::visit(array_type_expression *type_expression)
{
type_expression->base().accept(this);
this->current_type = type(std::make_shared<array_type>(this->current_type, type_expression->size));
}
void declaration_visitor::visit(record_type_expression *type_expression)
{
auto type_definition = std::make_shared<record_type>();
for (auto& field : type_expression->fields)
{
field.second->accept(this);
type_definition->fields.push_back({ field.first, type(this->current_type) });
}
this->current_type = type(type_definition);
}
@ -317,6 +103,12 @@ namespace boot
{
auto type_definition = std::make_shared<union_type>();
for (auto& field : type_expression->fields)
{
field.second->accept(this);
type_definition->fields.push_back({ field.first, type(this->current_type) });
}
this->current_type = type(type_definition);
}