Add second GENERIC visitor
This commit is contained in:
@ -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)
|
||||
|
||||
|
@ -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(¶meter_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());
|
||||
|
@ -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());
|
||||
|
Reference in New Issue
Block a user