Add lexer and parser sources

This commit is contained in:
2025-06-14 23:57:48 +02:00
parent d5e2d53e9b
commit f524311f06
25 changed files with 3475 additions and 427 deletions

View File

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

View File

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