Add lexer and parser sources
This commit is contained in:
@ -99,23 +99,25 @@ namespace elna::gcc
|
||||
|
||||
}
|
||||
|
||||
std::deque<std::unique_ptr<boot::error>> do_semantic_analysis(const char *path,
|
||||
const std::unique_ptr<boot::program>& ast, std::shared_ptr<boot::symbol_table> info_table,
|
||||
std::shared_ptr<symbol_table> symbols, std::unordered_map<std::string, tree>& unresolved)
|
||||
std::unordered_map<std::string, tree> do_semantic_analysis(std::shared_ptr<boot::symbol_table> info_table,
|
||||
std::shared_ptr<symbol_table> symbols)
|
||||
{
|
||||
boot::declaration_visitor declaration_visitor(path, info_table);
|
||||
std::unordered_map<std::string, tree> unresolved;
|
||||
|
||||
declaration_visitor.visit(ast.get());
|
||||
|
||||
if (declaration_visitor.errors().empty())
|
||||
for (auto& [symbol_name, symbol_info] : *info_table)
|
||||
{
|
||||
for (auto& [symbol_name, symbol_info] : declaration_visitor.unresolved)
|
||||
std::vector<std::string> type_path;
|
||||
|
||||
// The top level symbol table has basic (builtin) types in it which are not aliases.
|
||||
if (auto type_info = symbol_info->is_type())
|
||||
{
|
||||
std::vector<std::string> type_path;
|
||||
handle_symbol(symbol_name, symbol_info, symbols, unresolved, type_path);
|
||||
if (auto alias_type = type_info->symbol.get<boot::alias_type>())
|
||||
{
|
||||
handle_symbol(symbol_name, alias_type, symbols, unresolved, type_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::move(declaration_visitor.errors());
|
||||
return unresolved;
|
||||
}
|
||||
|
||||
generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table,
|
||||
@ -318,7 +320,7 @@ namespace elna::gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::declare_procedure(boot::procedure_definition *const definition)
|
||||
void generic_visitor::declare_procedure(boot::procedure_declaration *const definition)
|
||||
{
|
||||
tree declaration_type = build_procedure_type(definition->heading());
|
||||
tree fndecl = build_fn_decl(definition->identifier.identifier.c_str(), declaration_type);
|
||||
@ -409,11 +411,11 @@ namespace elna::gcc
|
||||
{
|
||||
declaration->accept(this);
|
||||
}
|
||||
for (boot::constant_definition *const constant : unit->constants)
|
||||
for (boot::constant_declaration *const constant : unit->constants)
|
||||
{
|
||||
constant->accept(this);
|
||||
}
|
||||
for (boot::type_definition *const type : unit->types)
|
||||
for (boot::type_declaration *const type : unit->types)
|
||||
{
|
||||
type->accept(this);
|
||||
}
|
||||
@ -421,17 +423,17 @@ namespace elna::gcc
|
||||
{
|
||||
variable->accept(this);
|
||||
}
|
||||
for (boot::procedure_definition *const procedure : unit->procedures)
|
||||
for (boot::procedure_declaration *const procedure : unit->procedures)
|
||||
{
|
||||
declare_procedure(procedure);
|
||||
}
|
||||
for (boot::procedure_definition *const procedure : unit->procedures)
|
||||
for (boot::procedure_declaration *const procedure : unit->procedures)
|
||||
{
|
||||
procedure->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::procedure_definition *definition)
|
||||
void generic_visitor::visit(boot::procedure_declaration *definition)
|
||||
{
|
||||
if (!definition->body.has_value())
|
||||
{
|
||||
@ -449,7 +451,7 @@ namespace elna::gcc
|
||||
{
|
||||
this->symbols->enter(IDENTIFIER_POINTER(DECL_NAME(argument_chain)), argument_chain);
|
||||
}
|
||||
for (boot::constant_definition *const constant : definition->body.value().constants())
|
||||
for (boot::constant_declaration *const constant : definition->body.value().constants())
|
||||
{
|
||||
constant->accept(this);
|
||||
}
|
||||
@ -818,7 +820,7 @@ namespace elna::gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::constant_definition *definition)
|
||||
void generic_visitor::visit(boot::constant_declaration *definition)
|
||||
{
|
||||
location_t definition_location = get_location(&definition->position());
|
||||
definition->body().accept(this);
|
||||
@ -858,7 +860,7 @@ namespace elna::gcc
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::type_definition *definition)
|
||||
void generic_visitor::visit(boot::type_declaration *definition)
|
||||
{
|
||||
location_t definition_location = get_location(&definition->position());
|
||||
this->current_expression = this->unresolved.at(definition->identifier.identifier);
|
||||
|
12
gcc/elna1.cc
12
gcc/elna1.cc
@ -84,19 +84,21 @@ static void elna_parse_file(const char *filename)
|
||||
{
|
||||
for (const std::unique_ptr<elna::boot::program>& module_tree : outcome.modules)
|
||||
{
|
||||
std::unordered_map<std::string, tree> unresolved;
|
||||
elna::boot::declaration_visitor declaration_visitor(filename, info_table);
|
||||
|
||||
auto semantic_errors = elna::gcc::do_semantic_analysis(filename, module_tree,
|
||||
info_table, symbol_table, unresolved);
|
||||
declaration_visitor.visit(module_tree.get());
|
||||
|
||||
if (semantic_errors.empty())
|
||||
if (declaration_visitor.errors().empty())
|
||||
{
|
||||
std::unordered_map<std::string, tree> unresolved = elna::gcc::do_semantic_analysis(
|
||||
info_table, symbol_table);
|
||||
|
||||
elna::gcc::generic_visitor generic_visitor{ symbol_table, std::move(unresolved) };
|
||||
generic_visitor.visit(module_tree.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
elna::gcc::report_errors(semantic_errors);
|
||||
elna::gcc::report_errors(declaration_visitor.errors());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user