Add second GENERIC visitor

This commit is contained in:
2025-03-04 22:56:32 +01:00
parent c5930285bf
commit 8dc02047df
12 changed files with 572 additions and 341 deletions

View File

@ -46,8 +46,6 @@ elna_OBJS = \
elna/driver.o \
elna/lexer.o \
elna/parser.o \
elna/semantic.o \
elna/symbol.o \
elna/result.o \
$(END)

View File

@ -38,9 +38,73 @@ namespace elna
{
namespace gcc
{
declaration_visitor::declaration_visitor(std::shared_ptr<symbol_table> symbol_table)
: symbols(symbol_table)
{
this->unresolved.insert({ "Int", std::make_shared<type>(elna_int_type_node) });
this->unresolved.insert({ "Word", std::make_shared<type>(elna_word_type_node) });
this->unresolved.insert({ "Char", std::make_shared<type>(elna_char_type_node) });
this->unresolved.insert({ "Bool", std::make_shared<type>(elna_bool_type_node) });
this->unresolved.insert({ "Byte", std::make_shared<type>(elna_byte_type_node) });
this->unresolved.insert({ "Float", std::make_shared<type>(elna_float_type_node) });
this->unresolved.insert({ "String", std::make_shared<type>(elna_string_type_node) });
}
tree get_inner_alias(const type& t)
{
if (t.reference == nullptr)
{
return t.resolved;
}
else
{
return get_inner_alias(*t.reference);
}
}
void declaration_visitor::visit(boot::program *program)
{
for (boot::type_definition *const type : program->types)
{
type->accept(this);
}
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 if (auto alias_node = type->body().is_record())
{
unresolved_declaration->resolved = make_node(RECORD_TYPE);
}
else if (auto alias_node = type->body().is_union())
{
unresolved_declaration->resolved = make_node(UNION_TYPE);
}
}
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, std::make_shared<type>() });
}
generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table)
{
this->symbol_map = symbol_table;
this->symbols = symbol_table;
}
void generic_visitor::build_procedure_call(location_t call_location,
@ -180,23 +244,6 @@ namespace gcc
constant->accept(this);
}
for (boot::type_definition *const type : program->types)
{
tree type_node = NULL_TREE;
if (type->body().is_record())
{
type_node = make_node(RECORD_TYPE);
}
else if (type->body().is_union())
{
type_node = make_node(UNION_TYPE);
}
if (type_node != NULL_TREE)
{
this->symbol_map->enter(type->identifier, type_node);
}
}
for (boot::type_definition *const type : program->types)
{
type->accept(this);
}
@ -229,7 +276,7 @@ namespace gcc
DECL_CONTEXT(declaration_tree) = fndecl;
DECL_ARG_TYPE(declaration_tree) = TREE_VALUE(parameter_type);
this->symbol_map->enter(argument_name, declaration_tree);
this->symbols->enter(argument_name, declaration_tree);
DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree);
parameter_type = TREE_CHAIN(parameter_type);
}
@ -269,7 +316,7 @@ namespace gcc
{
tree declaration_type = build_procedure_type(definition->heading());
tree fndecl = build_fn_decl(definition->identifier.c_str(), declaration_type);
this->symbol_map->enter(definition->identifier, fndecl);
this->symbols->enter(definition->identifier, fndecl);
if (definition->heading().no_return)
{
@ -299,7 +346,7 @@ namespace gcc
if (definition->body != nullptr)
{
this->symbol_map->enter(parameter->identifier, declaration_tree);
this->symbols->enter(parameter->identifier, declaration_tree);
}
argument_chain = chainon(argument_chain, declaration_tree);
function_args_iter_next(&parameter_type);
@ -332,7 +379,7 @@ namespace gcc
void generic_visitor::enter_scope()
{
this->symbol_map = std::make_shared<symbol_table>(this->symbol_map);
this->symbols = std::make_shared<symbol_table>(this->symbols);
// Chain the binding levels.
struct binding_level *new_level = ggc_cleared_alloc<binding_level>();
@ -352,7 +399,7 @@ namespace gcc
BLOCK_SUPERCONTEXT(it) = new_block;
}
tree bind_expr = build3(BIND_EXPR, void_type_node, variables, chain_defer(), new_block);
this->symbol_map = this->symbol_map->scope();
this->symbols = this->symbols->scope();
f_binding_level = f_binding_level->level_chain;
@ -365,35 +412,7 @@ namespace gcc
tree generic_visitor::lookup(const std::string& name)
{
if (name == "Int")
{
return elna_int_type_node;
}
if (name == "Word")
{
return elna_word_type_node;
}
if (name == "Char")
{
return elna_char_type_node;
}
if (name == "Bool")
{
return elna_bool_type_node;
}
if (name == "Byte")
{
return elna_byte_type_node;
}
if (name == "Float")
{
return elna_float_type_node;
}
if (name == "String")
{
return elna_string_type_node;
}
return this->symbol_map->lookup(name);
return this->symbols->lookup(name);
}
void generic_visitor::visit(boot::number_literal<std::int32_t> *literal)
@ -720,7 +739,7 @@ namespace gcc
tree definition_tree = build_decl(definition_location, CONST_DECL,
get_identifier(definition->identifier.c_str()), TREE_TYPE(this->current_expression));
auto result = this->symbol_map->enter(definition->identifier, definition_tree);
auto result = this->symbols->enter(definition->identifier, definition_tree);
if (result)
{
@ -748,12 +767,12 @@ namespace gcc
void generic_visitor::visit(boot::type_definition *definition)
{
location_t definition_location = get_location(&definition->position());
this->current_expression = this->symbol_map->lookup(definition->identifier);
this->current_expression = lookup(definition->identifier);
definition->body().accept(this);
tree definition_tree = build_decl(definition_location, TYPE_DECL,
get_identifier(definition->identifier.c_str()), this->current_expression);
auto result = this->symbol_map->enter(definition->identifier, this->current_expression);
auto result = this->symbols->enter(definition->identifier, this->current_expression);
/* if (result)
{ */
@ -798,7 +817,7 @@ namespace gcc
location_t declaration_location = get_location(&declaration->position());
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
get_identifier(declaration->identifier.c_str()), this->current_expression);
bool result = this->symbol_map->enter(declaration->identifier, declaration_tree);
bool result = this->symbols->enter(declaration->identifier, declaration_tree);
if (is_pointer_type(this->current_expression))
{
@ -829,7 +848,7 @@ namespace gcc
void generic_visitor::visit(boot::variable_expression *expression)
{
auto symbol = this->lookup(expression->name);
auto symbol = lookup(expression->name);
if (symbol == NULL_TREE)
{
@ -1122,9 +1141,9 @@ namespace gcc
void generic_visitor::visit(boot::primitive_type_expression *type)
{
tree symbol = this->lookup(type->name);
tree symbol = lookup(type->name);
if (symbol == NULL_TREE && TYPE_P(symbol))
if (symbol == NULL_TREE || !TYPE_P(symbol))
{
error_at(get_location(&type->position()),
"type '%s' not declared", type->name.c_str());

View File

@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see
#include <fstream>
#include "elna/boot/driver.h"
#include "elna/boot/semantic.h"
#include "elna/gcc/elna-tree.h"
#include "elna/gcc/elna-generic.h"
#include "elna/gcc/elna-diagnostic.h"
@ -89,8 +88,10 @@ static void elna_parse_file(const char *filename)
}
else
{
elna::boot::declaration_visitor declaration_visitor{ std::make_shared<elna::boot::symbol_table>() };
elna::gcc::generic_visitor generic_visitor{ std::make_shared<elna::gcc::symbol_table>() };
std::shared_ptr<elna::gcc::symbol_table> symbol_table = std::make_shared<elna::gcc::symbol_table>();
elna::gcc::declaration_visitor declaration_visitor{ symbol_table };
elna::gcc::generic_visitor generic_visitor{ symbol_table };
declaration_visitor.visit(driver.tree.get());
generic_visitor.visit(driver.tree.get());