Unify the build_type function
This commit is contained in:
@ -464,7 +464,8 @@ namespace boot
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
record_type_expression::record_type_expression(const struct position position, fields_t&& fields)
|
||||
record_type_expression::record_type_expression(const struct position position,
|
||||
std::vector<field_declaration>&& fields)
|
||||
: type_expression(position), fields(std::move(fields))
|
||||
{
|
||||
}
|
||||
@ -479,7 +480,8 @@ namespace boot
|
||||
return std::static_pointer_cast<record_type_expression>(shared_from_this());
|
||||
}
|
||||
|
||||
union_type_expression::union_type_expression(const struct position position, fields_t&& fields)
|
||||
union_type_expression::union_type_expression(const struct position position,
|
||||
std::vector<field_declaration>&& fields)
|
||||
: type_expression(position), fields(std::move(fields))
|
||||
{
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <elna::boot::type_definition *> type_definition;
|
||||
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
|
||||
%type <elna::boot::block *> block;
|
||||
%type <elna::boot::field_t> field_declaration;
|
||||
%type <elna::boot::field_declaration> field_declaration;
|
||||
%type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::type_expression>>>>
|
||||
optional_fields required_fields;
|
||||
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
|
||||
|
177
boot/semantic.cc
177
boot/semantic.cc
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user