Unify the build_type function
This commit is contained in:
@ -38,112 +38,41 @@ namespace elna
|
||||
{
|
||||
namespace gcc
|
||||
{
|
||||
declaration_visitor::declaration_visitor(std::shared_ptr<symbol_table> symbol_table)
|
||||
: symbols(symbol_table)
|
||||
static tree get_inner_alias(std::shared_ptr<symbol_table> symbol_table, const boot::type& type)
|
||||
{
|
||||
this->symbols->enter("Int", elna_int_type_node);
|
||||
this->symbols->enter("Word", elna_word_type_node);
|
||||
this->symbols->enter("Char", elna_char_type_node);
|
||||
this->symbols->enter("Bool", elna_bool_type_node);
|
||||
this->symbols->enter("Byte", elna_byte_type_node);
|
||||
this->symbols->enter("Float", elna_float_type_node);
|
||||
this->symbols->enter("String", elna_string_type_node);
|
||||
}
|
||||
|
||||
tree declaration_visitor::get_inner_alias(const boot::alias_type& t)
|
||||
{
|
||||
if (t.reference == nullptr)
|
||||
if (auto reference = type.get<boot::primitive_type>())
|
||||
{
|
||||
return NULL_TREE;
|
||||
return symbol_table->lookup(reference->identifier);
|
||||
}
|
||||
else if (auto reference = t.reference->is_primitive())
|
||||
{
|
||||
return this->symbols->lookup(reference->identifier);
|
||||
}
|
||||
else if (auto reference = t.reference->is_alias())
|
||||
{
|
||||
return get_inner_alias(*reference);
|
||||
}
|
||||
else if (auto reference = t.reference->is_record())
|
||||
else if (auto reference = type.get<boot::record_type>())
|
||||
{
|
||||
return make_node(RECORD_TYPE);
|
||||
}
|
||||
else if (auto reference = t.reference->is_union())
|
||||
else if (auto reference = type.get<boot::union_type>())
|
||||
{
|
||||
return make_node(UNION_TYPE);
|
||||
}
|
||||
return NULL_TREE;
|
||||
else if (auto reference = type.get<boot::pointer_type>())
|
||||
{
|
||||
return build_pointer_type_for_mode(get_inner_alias(symbol_table, reference->base), VOIDmode, true);
|
||||
}
|
||||
else if (auto reference = type.get<boot::alias_type>())
|
||||
{
|
||||
return get_inner_alias(symbol_table, reference->reference);
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
boot::type *declaration_visitor::build_type(boot::type_expression *type_expression)
|
||||
void do_semantic_analysis(std::shared_ptr<symbol_table> symbols, std::unique_ptr<boot::program>& ast)
|
||||
{
|
||||
if (auto alias_node = type_expression->is_primitive())
|
||||
{
|
||||
return this->unresolved.at(alias_node->name);
|
||||
}
|
||||
else if (auto alias_node = type_expression->is_record())
|
||||
{
|
||||
return build_record(alias_node.get());
|
||||
}
|
||||
else if (auto alias_node = type_expression->is_union())
|
||||
{
|
||||
return build_union(alias_node.get());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
boot::declaration_visitor declaration_visitor;
|
||||
|
||||
boot::record_type *declaration_visitor::build_record(boot::record_type_expression *type_expression)
|
||||
{
|
||||
return new boot::record_type();
|
||||
}
|
||||
|
||||
boot::union_type *declaration_visitor::build_union(boot::union_type_expression *type_expression)
|
||||
{
|
||||
return new boot::union_type();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(boot::program *program)
|
||||
{
|
||||
for (boot::type_definition *const type : program->types)
|
||||
declaration_visitor.visit(ast.get());
|
||||
for (auto unresolved : declaration_visitor.unresolved)
|
||||
{
|
||||
type->accept(this);
|
||||
auto inner_alias = elna::gcc::get_inner_alias(symbols, boot::type(unresolved.second));
|
||||
symbols->enter(unresolved.first, inner_alias);
|
||||
}
|
||||
for (boot::type_definition *const type : program->types)
|
||||
{
|
||||
auto unresolved_declaration = this->unresolved.at(type->identifier);
|
||||
|
||||
if (auto alias_node = type->body().is_primitive())
|
||||
{
|
||||
auto unresolved_alias = this->unresolved.find(alias_node->name);
|
||||
|
||||
if (unresolved_alias != this->unresolved.end())
|
||||
{
|
||||
unresolved_declaration->reference = unresolved_alias->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
unresolved_declaration->reference = new boot::primitive_type(alias_node->name);
|
||||
}
|
||||
}
|
||||
else if (auto alias_node = type->body().is_record())
|
||||
{
|
||||
unresolved_declaration->reference = build_record(alias_node.get());
|
||||
}
|
||||
else if (auto alias_node = type->body().is_union())
|
||||
{
|
||||
unresolved_declaration->reference = build_union(alias_node.get());
|
||||
}
|
||||
}
|
||||
for (auto unresolved : this->unresolved)
|
||||
{
|
||||
auto inner_alias = get_inner_alias(*unresolved.second);
|
||||
this->symbols->enter(unresolved.first, inner_alias);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(boot::type_definition *definition)
|
||||
{
|
||||
this->unresolved.insert({ definition->identifier, new boot::alias_type() });
|
||||
}
|
||||
|
||||
generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table)
|
||||
|
11
gcc/elna1.cc
11
gcc/elna1.cc
@ -90,10 +90,17 @@ static void elna_parse_file(const char *filename)
|
||||
{
|
||||
std::shared_ptr<elna::gcc::symbol_table> symbol_table = std::make_shared<elna::gcc::symbol_table>();
|
||||
|
||||
elna::gcc::declaration_visitor declaration_visitor{ symbol_table };
|
||||
symbol_table->enter("Int", elna_int_type_node);
|
||||
symbol_table->enter("Word", elna_word_type_node);
|
||||
symbol_table->enter("Char", elna_char_type_node);
|
||||
symbol_table->enter("Bool", elna_bool_type_node);
|
||||
symbol_table->enter("Byte", elna_byte_type_node);
|
||||
symbol_table->enter("Float", elna_float_type_node);
|
||||
symbol_table->enter("String", elna_string_type_node);
|
||||
|
||||
elna::gcc::do_semantic_analysis(symbol_table, driver.tree);
|
||||
elna::gcc::generic_visitor generic_visitor{ symbol_table };
|
||||
|
||||
declaration_visitor.visit(driver.tree.get());
|
||||
generic_visitor.visit(driver.tree.get());
|
||||
}
|
||||
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
||||
|
Reference in New Issue
Block a user