Unify the build_type function

This commit is contained in:
2025-03-06 22:59:41 +01:00
parent dbeaca7cbf
commit dc5760394b
8 changed files with 261 additions and 175 deletions

View File

@ -21,33 +21,104 @@ namespace elna
{
namespace boot
{
alias_type *type::is_alias()
{
return nullptr;
}
primitive_type *type::is_primitive()
{
return nullptr;
}
record_type *type::is_record()
{
return nullptr;
}
union_type *type::is_union()
{
return nullptr;
}
type::~type()
type::type(alias_type *alias)
: payload({ .alias = alias }), tag(type_tag::alias)
{
}
alias_type *alias_type::is_alias()
type::type(primitive_type *primitive)
: payload({ .primitive = primitive }), tag(type_tag::primitive)
{
}
type::type(record_type *record)
: payload({ .record = record }), tag(type_tag::record)
{
}
type::type(union_type *_union)
: payload({ ._union = _union }), tag(type_tag::_union)
{
}
type::type(pointer_type *pointer)
: payload({ .pointer = pointer }), tag(type_tag::pointer)
{
}
template<>
alias_type *const type::get<alias_type>() const
{
if (tag == type_tag::alias)
{
return payload.alias;
}
else
{
return nullptr;
}
}
template<>
primitive_type *const type::get<primitive_type>() const
{
if (tag == type_tag::primitive)
{
return payload.primitive;
}
else
{
return nullptr;
}
}
template<>
record_type *const type::get<record_type>() const
{
if (tag == type_tag::record)
{
return payload.record;
}
else
{
return nullptr;
}
}
template<>
union_type *const type::get<union_type>() const
{
if (tag == type_tag::_union)
{
return payload._union;
}
else
{
return nullptr;
}
}
template<>
pointer_type *const type::get<pointer_type>() const
{
if (tag == type_tag::pointer)
{
return payload.pointer;
}
else
{
return nullptr;
}
}
bool type::empty() const
{
return tag == type_tag::empty;
}
pointer_type::pointer_type(type base)
: base(base)
{
return this;
}
primitive_type::primitive_type(const std::string& identifier)
@ -55,19 +126,67 @@ namespace boot
{
}
primitive_type *primitive_type::is_primitive()
void declaration_visitor::visit(program *program)
{
return this;
for (type_definition *const type : program->types)
{
this->unresolved.insert({ type->identifier, new alias_type() });
}
for (type_definition *const type : program->types)
{
type->accept(this);
}
}
record_type *record_type::is_record()
void declaration_visitor::visit(type_definition *definition)
{
return this;
auto unresolved_declaration = this->unresolved.at(definition->identifier);
definition->body().accept(this);
unresolved_declaration->reference = this->current_type;
}
union_type *union_type::is_union()
void declaration_visitor::visit(primitive_type_expression *type_expression)
{
auto unresolved_alias = this->unresolved.find(type_expression->name);
if (unresolved_alias != this->unresolved.end())
{
this->current_type = type(unresolved_alias->second);
}
else
{
this->current_type = type(new 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(new pointer_type(this->current_type));
}
void declaration_visitor::visit(record_type_expression *type_expression)
{
auto type_definition = new record_type();
this->current_type = type(type_definition);
}
void declaration_visitor::visit(union_type_expression *type_expression)
{
auto type_definition = new union_type();
this->current_type = type(type_definition);
}
void declaration_visitor::visit(procedure_type_expression *type_expression)
{
return this;
}
}
}