Add second GENERIC visitor

This commit is contained in:
2025-03-04 22:56:32 +01:00
parent c5930285bf
commit 30a218cefb
8 changed files with 518 additions and 136 deletions

View File

@ -46,7 +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,35 @@ namespace elna
{
namespace gcc
{
declaration_visitor::declaration_visitor(std::shared_ptr<symbol_table> symbol_table)
: symbols(symbol_table)
{
}
void declaration_visitor::visit(boot::program *program)
{
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->symbols->enter(type->identifier, type_node);
}
}
}
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 +206,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 +238,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 +278,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 +308,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 +341,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 +361,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;
@ -393,7 +402,7 @@ namespace gcc
{
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 +729,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 +757,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 = this->symbols->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 +807,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))
{

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());