aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-13 16:07:11 +0200
committerEugen Wissner <belka@caraus.de>2026-09-13 16:07:11 +0200
commita5d033df465ca8de8457926cc64aacf38c6ae848 (patch)
treee459e27e808046ea42448768394574f3343f7015
parente72e20e025ab14320c79c2dca75721a0a5e002bd (diff)
downloadelna-a5d033df465ca8de8457926cc64aacf38c6ae848.tar.gz
Visit nested statements in validation visitor
-rw-r--r--boot/ast.cc45
-rw-r--r--boot/name_analysis.cc128
-rw-r--r--boot/parser.yy29
-rw-r--r--boot/validation.cc117
-rw-r--r--gcc/gcc/elna-generic.cc130
-rw-r--r--include/elna/boot/ast.h30
-rw-r--r--include/elna/boot/name_analysis.h8
-rw-r--r--include/elna/boot/validation.h16
-rw-r--r--include/elna/gcc/elna-generic.h5
9 files changed, 275 insertions, 233 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index 08d3a78..04e9230 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -354,17 +354,9 @@ namespace elna::boot
{
_import->accept(this);
}
- for (type_declaration *type : unit->types)
+ for (declaration *const unit_declaration : unit->declarations)
{
- type->accept(this);
- }
- for (variable_declaration *variable : unit->variables)
- {
- variable->accept(this);
- }
- for (procedure_declaration *procedure : unit->procedures)
- {
- procedure->accept(this);
+ unit_declaration->accept(this);
}
if (unit->entry_point.has_value())
{
@@ -991,11 +983,6 @@ namespace elna::boot
return *m_variable_type;
}
- declaration::declaration(const source_position position, identifier_definition identifier)
- : node(position), identifier(std::move(identifier))
- {
- }
-
procedure_type_expression::procedure_type_expression(const source_position position,
std::vector<field_declaration>&& parameters, return_t return_type)
: node(position), return_type(return_type), parameters(std::move(parameters))
@@ -1035,14 +1022,14 @@ namespace elna::boot
procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier,
procedure_type_expression *heading, procedure_body&& body)
- : declaration(position, std::move(identifier)), m_heading(heading),
+ : node(position), m_heading(heading), identifier(std::move(identifier)),
body(std::make_optional<procedure_body>(std::move(body)))
{
}
procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier,
procedure_type_expression *heading)
- : declaration(position, std::move(identifier)), m_heading(heading)
+ : node(position), m_heading(heading), identifier(std::move(identifier))
{
}
@@ -1063,7 +1050,7 @@ namespace elna::boot
type_declaration::type_declaration(const source_position position, identifier_definition identifier,
type_expression *underlying_type)
- : declaration(position, std::move(identifier)), m_underlying_type(underlying_type)
+ : node(position), m_underlying_type(underlying_type), identifier(std::move(identifier))
{
}
@@ -1126,26 +1113,20 @@ namespace elna::boot
unit::unit(const source_position position,
std::vector<import_declaration *>&& imports,
- std::vector<type_declaration *>&& types,
- std::vector<variable_declaration *>&& variables,
- std::vector<procedure_declaration *>&& procedures)
+ std::vector<declaration *>&& declarations)
: node(position),
- imports(std::move(imports)), types(std::move(types)), procedures(std::move(procedures)),
- variables(std::move(variables))
+ imports(std::move(imports)), declarations(std::move(declarations))
{
}
unit::unit(const source_position position,
std::vector<import_declaration *>&& imports,
- std::vector<type_declaration *>&& types,
- std::vector<variable_declaration *>&& variables,
- std::vector<procedure_declaration *>&& procedures,
+ std::vector<declaration *>&& declarations,
std::vector<identifier>&& parameters,
const source_position entry_position,
std::optional<procedure_body>&& body)
: node(position),
- imports(std::move(imports)), types(std::move(types)), procedures(std::move(procedures)),
- variables(std::move(variables)), entry_point(std::move(body)),
+ imports(std::move(imports)), declarations(std::move(declarations)), entry_point(std::move(body)),
parameters(std::move(parameters)), entry_position(entry_position)
{
}
@@ -1157,13 +1138,9 @@ namespace elna::boot
unit::~unit()
{
- for (const procedure_declaration *procedure : this->procedures)
- {
- delete procedure;
- }
- for (const type_declaration *type : this->types)
+ for (const declaration *unit_declaration : this->declarations)
{
- delete type;
+ delete unit_declaration;
}
for (const import_declaration *declaration : this->imports)
{
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 4a1a0ca..d5b2e91 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -278,9 +278,9 @@ namespace elna::boot
void forward_declaration_visitor::visit(unit *unit)
{
- for (type_declaration *const type : unit->types)
+ for (auto *const unit_declaration: unit->declarations)
{
- type->accept(this);
+ unit_declaration->accept(this);
}
}
@@ -296,6 +296,14 @@ namespace elna::boot
}
}
+ void forward_declaration_visitor::visit(variable_declaration *)
+ {
+ }
+
+ void forward_declaration_visitor::visit(procedure_declaration *)
+ {
+ }
+
resolving_visitor::resolving_visitor(symbol_bag& bag, const target_info& target,
const std::filesystem::path& module_path)
: bag(bag), constant_evaluator(this->bag, target), module_file(module_path)
@@ -502,41 +510,6 @@ namespace elna::boot
return type();
}
- void resolving_visitor::visit(variable_declaration *declaration)
- {
- const type variable_type = resolve_type(declaration->variable_type());
- std::optional<constant_value> computed;
-
- if (declaration->initializer != nullptr)
- {
- declaration->initializer->accept(this);
- computed = this->constant_evaluator.evaluate(*declaration->initializer);
-
- if (this->bag.is_global() && !computed.has_value())
- {
- add_error<non_constant_expression_error>(declaration->initializer->position(),
- non_constant_expression_error::initializer{ extract_identifiers(declaration->identifiers) });
- }
- }
- else if (!declaration->is_extern && resolve_aliases(variable_type).get<constant_type>() != nullptr)
- {
- auto position_span = source_position(
- declaration->identifiers.front().id().position().start(),
- declaration->identifiers.back().id().position().end());
- add_error<declaration_format_error>(position_span,
- declaration_format_error::not_initialized{ extract_identifiers(declaration->identifiers) });
- }
- for (const auto& variable_identifier : declaration->identifiers)
- {
- auto variable_symbol = register_variable(variable_identifier.name(),
- variable_type, declaration->position(), declaration->is_extern);
- variable_symbol->exported = variable_identifier.exported();
- variable_symbol->alignment =
- evaluate_attributes<attribute_kind::aligned>(variable_identifier.attributes).alignment;
- variable_symbol->value = computed;
- }
- }
-
std::vector<type> resolving_visitor::enter_parameters(const std::vector<identifier>& parameters)
{
std::vector<type> result;
@@ -1324,17 +1297,9 @@ namespace elna::boot
void declaration_visitor::visit(unit *unit)
{
- for (type_declaration *const type : unit->types)
+ for (declaration *const unit_declaration : unit->declarations)
{
- type->accept(this);
- }
- for (variable_declaration *const variable : unit->variables)
- {
- variable->accept(this);
- }
- for (procedure_declaration *const procedure : unit->procedures)
- {
- procedure->accept(this);
+ unit_declaration->accept(this);
}
if (unit->entry_point.has_value())
{
@@ -1422,6 +1387,41 @@ namespace elna::boot
}
}
+ void declaration_visitor::visit(variable_declaration *declaration)
+ {
+ const type variable_type = resolve_type(declaration->variable_type());
+ std::optional<constant_value> computed;
+
+ if (declaration->initializer != nullptr)
+ {
+ declaration->initializer->accept(this);
+ computed = this->constant_evaluator.evaluate(*declaration->initializer);
+
+ if (!computed.has_value())
+ {
+ add_error<non_constant_expression_error>(declaration->initializer->position(),
+ non_constant_expression_error::initializer{ extract_identifiers(declaration->identifiers) });
+ }
+ }
+ else if (!declaration->is_extern && resolve_aliases(variable_type).get<constant_type>() != nullptr)
+ {
+ auto position_span = source_position(
+ declaration->identifiers.front().id().position().start(),
+ declaration->identifiers.back().id().position().end());
+ add_error<declaration_format_error>(position_span,
+ declaration_format_error::not_initialized{ extract_identifiers(declaration->identifiers) });
+ }
+ for (const auto& variable_identifier : declaration->identifiers)
+ {
+ auto variable_symbol = register_variable(variable_identifier.name(),
+ variable_type, declaration->position(), declaration->is_extern);
+ variable_symbol->exported = variable_identifier.exported();
+ variable_symbol->alignment =
+ evaluate_attributes<attribute_kind::aligned>(variable_identifier.attributes).alignment;
+ variable_symbol->value = computed;
+ }
+ }
+
void declaration_visitor::visit(procedure_declaration *declaration)
{
// The scope is opened before the heading is built so that the type
@@ -1482,9 +1482,9 @@ namespace elna::boot
void name_analysis_visitor::visit(unit *unit)
{
- for (procedure_declaration *const procedure : unit->procedures)
+ for (declaration *const unit_declaration : unit->declarations)
{
- procedure->accept(this);
+ unit_declaration->accept(this);
}
if (unit->entry_point.has_value())
{
@@ -1498,7 +1498,35 @@ namespace elna::boot
void name_analysis_visitor::visit(type_declaration *)
{
- __builtin_unreachable();
+ }
+
+ void name_analysis_visitor::visit(variable_declaration *declaration)
+ {
+ if (!this->bag.is_global())
+ {
+ const type variable_type = resolve_type(declaration->variable_type());
+
+ if (declaration->initializer != nullptr)
+ {
+ declaration->initializer->accept(this);
+ }
+ else if (resolve_aliases(variable_type).get<constant_type>() != nullptr)
+ {
+ auto position_span = source_position(
+ declaration->identifiers.front().id().position().start(),
+ declaration->identifiers.back().id().position().end());
+ add_error<declaration_format_error>(position_span,
+ declaration_format_error::not_initialized{ extract_identifiers(declaration->identifiers) });
+ }
+ for (const auto& variable_identifier : declaration->identifiers)
+ {
+ auto variable_symbol = register_variable(variable_identifier.name(),
+ variable_type, declaration->position(), declaration->is_extern);
+ variable_symbol->exported = variable_identifier.exported();
+ variable_symbol->alignment =
+ evaluate_attributes<attribute_kind::aligned>(variable_identifier.attributes).alignment;
+ }
+ }
}
void name_analysis_visitor::visit(procedure_declaration *declaration)
diff --git a/boot/parser.yy b/boot/parser.yy
index f97d545..9c9e728 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -146,8 +146,8 @@ along with GCC; see the file COPYING3. If not see
%type <std::unique_ptr<elna::boot::procedure_type_expression>> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
%type <std::vector<elna::boot::procedure_declaration *>> procedure_part;
-%type <elna::boot::type_declaration *> type_declaration;
-%type <std::vector<elna::boot::type_declaration *>> type_declarations type_part;
+%type <std::unique_ptr<elna::boot::type_declaration>> type_declaration;
+%type <std::vector<elna::boot::declaration *>> type_declarations type_part;
%type <std::unique_ptr<elna::boot::procedure_body>> procedure_body;
%type <elna::boot::field_declaration> field_declaration;
%type <std::vector<elna::boot::field_declaration>> field_declarations;
@@ -171,15 +171,30 @@ program:
{
driver.finished = true;
- boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2, $3, $4);
+ std::vector<boot::declaration *> declarations = $2;
+ std::vector<boot::variable_declaration *> variables = $3;
+ declarations.insert(declarations.end(),
+ std::make_move_iterator(variables.begin()), std::make_move_iterator(variables.end()));
+ std::vector<boot::procedure_declaration *> appendix = $4;
+ declarations.insert(declarations.end(),
+ std::make_move_iterator(appendix.begin()), std::make_move_iterator(appendix.end()));
+
+ boot::unit *tree = new boot::unit(boot::make_position(@$), $1, std::move(declarations));
driver.tree.reset(tree);
}
| import_part type_part variable_part procedure_part
"program" "(" optional_identifiers ")" procedure_body "end" "."
{
driver.finished = true;
+ std::vector<boot::declaration *> declarations = $2;
+ std::vector<boot::variable_declaration *> variables = $3;
+ declarations.insert(declarations.end(),
+ std::make_move_iterator(variables.begin()), std::make_move_iterator(variables.end()));
+ std::vector<boot::procedure_declaration *> appendix = $4;
+ declarations.insert(declarations.end(),
+ std::make_move_iterator(appendix.begin()), std::make_move_iterator(appendix.end()));
- boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2, $3, $4,
+ boot::unit *tree = new boot::unit(boot::make_position(@$), $1, std::move(declarations),
std::move($7), boot::make_position(@5), std::move(*$9));
driver.tree.reset(tree);
}
@@ -706,12 +721,12 @@ import_part:
| "import" import_declarations { $$ = $2; }
type_declaration: identifier_definition generic_parameters "=" type_expression
{
- $$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1), $4);
+ $$ = std::make_unique<boot::type_declaration>(boot::make_position(@$), std::move(*$1), $4);
$$->parameters = $2;
}
| identifier_definition generic_parameters "=" "extern"
{
- $$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1),
+ $$ = std::make_unique<boot::type_declaration>(boot::make_position(@$), std::move(*$1),
new boot::extern_type_expression(boot::make_position(@$)));
$$->parameters = $2;
}
@@ -719,7 +734,7 @@ type_declarations:
type_declaration type_declarations
{
$$ = $2;
- $$.insert($$.cbegin(), $1);
+ $$.insert($$.cbegin(), $1.release());
}
| %empty {}
type_part:
diff --git a/boot/validation.cc b/boot/validation.cc
index 91dc064..2125a99 100644
--- a/boot/validation.cc
+++ b/boot/validation.cc
@@ -41,51 +41,36 @@ namespace elna::boot
{
}
- void validation_visitor::visit(assign_statement *)
- {
- }
-
- void validation_visitor::visit(if_statement *)
- {
- }
-
- void validation_visitor::visit(while_statement *)
- {
- }
-
- void validation_visitor::visit(repeat_statement *)
- {
- }
-
- void validation_visitor::visit(for_statement *)
+ void validation_visitor::visit_statements(const std::vector<statement *>& statements)
{
+ for (statement *const body_statement : statements)
+ {
+ body_statement->accept(this);
+ }
}
- void validation_visitor::visit(defer_statement *)
+ void validation_visitor::visit(unit *unit)
{
- }
+ for (declaration *unit_declaration : unit->declarations)
+ {
+ unit_declaration->accept(this);
+ }
+ if (unit->entry_point.has_value())
+ {
+ auto entry_point = this->bag.lookup("")->is_procedure();
- void validation_visitor::visit(empty_statement *)
- {
+ this->bag.enter(entry_point->scope);
+ visit_statements(unit->entry_point->statements);
+ this->bag.leave();
+ }
}
- void validation_visitor::visit(procedure_call *)
+ void validation_visitor::visit(type_declaration *)
{
}
- void validation_visitor::visit(unit *unit)
+ void validation_visitor::visit(variable_declaration *)
{
- for (procedure_declaration *procedure : unit->procedures)
- {
- procedure->accept(this);
- }
- if (unit->entry_point.has_value())
- {
- for (auto *entry_statement : unit->entry_point->statements)
- {
- entry_statement->accept(this);
- }
- }
}
void validation_visitor::visit(procedure_declaration *declaration)
@@ -94,10 +79,7 @@ namespace elna::boot
{
auto procedure = this->bag.lookup(declaration->identifier.name())->is_procedure();
this->bag.enter(procedure->scope);
- for (auto *statement : declaration->body.value().statements)
- {
- statement->accept(this);
- }
+ visit_statements(declaration->body.value().statements);
this->bag.leave();
}
}
@@ -106,17 +88,11 @@ namespace elna::boot
{
for (const switch_case& case_block : statement->cases)
{
- for (auto *block_statement : case_block.statements)
- {
- block_statement->accept(this);
- }
+ visit_statements(case_block.statements);
}
if (statement->alternative != nullptr)
{
- for (auto *block_statement : *statement->alternative)
- {
- block_statement->accept(this);
- }
+ visit_statements(*statement->alternative);
}
std::unordered_map<constant_value, source_position, constant_value_hash> seen;
@@ -139,4 +115,53 @@ namespace elna::boot
}
}
}
+
+ void validation_visitor::visit(assign_statement *)
+ {
+ }
+
+ void validation_visitor::visit(if_statement *statement)
+ {
+ visit_statements(statement->branch().statements);
+ for (const conditional_statements *branch : statement->branches)
+ {
+ visit_statements(branch->statements);
+ }
+ if (statement->alternative != nullptr)
+ {
+ visit_statements(*statement->alternative);
+ }
+ }
+
+ void validation_visitor::visit(while_statement *statement)
+ {
+ visit_statements(statement->branch().statements);
+ for (const conditional_statements *branch : statement->branches)
+ {
+ visit_statements(branch->statements);
+ }
+ }
+
+ void validation_visitor::visit(repeat_statement *statement)
+ {
+ visit_statements(statement->body);
+ }
+
+ void validation_visitor::visit(for_statement *statement)
+ {
+ visit_statements(statement->body);
+ }
+
+ void validation_visitor::visit(defer_statement *statement)
+ {
+ visit_statements(statement->statements);
+ }
+
+ void validation_visitor::visit(empty_statement *)
+ {
+ }
+
+ void validation_visitor::visit(procedure_call *)
+ {
+ }
}
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index 94a70df..ed75fa4 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -286,13 +286,9 @@ namespace elna::gcc
void generic_visitor::visit(boot::unit *unit)
{
- for (boot::variable_declaration *const variable : unit->variables)
+ for (boot::declaration *const unit_declaration : unit->declarations)
{
- variable->accept(this);
- }
- for (boot::procedure_declaration *const procedure : unit->procedures)
- {
- procedure->accept(this);
+ unit_declaration->accept(this);
}
if (unit->entry_point.has_value())
{
@@ -365,6 +361,69 @@ namespace elna::gcc
}
}
+ void generic_visitor::visit(boot::type_declaration *)
+ {
+ }
+
+ void generic_visitor::visit(boot::variable_declaration *declaration)
+ {
+ for (const auto& variable_identifier : declaration->identifiers)
+ {
+ const location_t declaration_location = get_location(&declaration->position());
+ const std::string& variable_name = variable_identifier.name();
+ tree declaration_tree = this->symbols->lookup(variable_name);
+
+ auto variable_symbol = this->bag.lookup(variable_name)->is_variable();
+
+ if (declaration_tree == NULL_TREE)
+ {
+ declaration_tree = declare_variable(variable_name, *variable_symbol, this->symbols);
+ }
+ if (variable_symbol->alignment.has_value())
+ {
+ SET_DECL_ALIGN(declaration_tree,
+ variable_symbol->alignment.value() * BITS_PER_UNIT);
+ DECL_USER_ALIGN(declaration_tree) = 1;
+ }
+ if (variable_symbol->value.has_value())
+ {
+ tree type = get_inner_alias(variable_symbol->symbol, this->symbols);
+ DECL_INITIAL(declaration_tree) = constant_to_tree(
+ variable_symbol->value.value(), this->symbols, type);
+ }
+ else if (declaration->initializer != nullptr)
+ {
+ declaration->initializer->accept(this);
+ DECL_INITIAL(declaration_tree) = this->current_expression;
+ }
+ else if (!declaration->is_extern && POINTER_TYPE_P(TREE_TYPE(declaration_tree)))
+ {
+ DECL_INITIAL(declaration_tree) = null_pointer_node;
+ }
+ if (variable_symbol->symbol.get<boot::constant_type>() != nullptr)
+ {
+ TREE_READONLY(declaration_tree) = 1;
+ }
+ this->current_expression = NULL_TREE;
+
+ if (lang_hooks.decls.global_bindings_p())
+ {
+ TREE_STATIC(declaration_tree) = static_cast<unsigned>(!declaration->is_extern);
+ varpool_node::get_create(declaration_tree);
+ varpool_node::finalize_decl(declaration_tree);
+ }
+ else
+ {
+ DECL_CONTEXT(declaration_tree) = current_function_decl;
+ f_binding_level->names = chainon(f_binding_level->names, declaration_tree);
+
+ tree declaration_statement = build1_loc(declaration_location, DECL_EXPR,
+ void_type_node, declaration_tree);
+ append_statement(declaration_statement);
+ }
+ }
+ }
+
void generic_visitor::visit(boot::procedure_declaration *declaration)
{
tree fndecl = this->symbols->lookup(declaration->identifier.name());
@@ -751,65 +810,6 @@ namespace elna::gcc
}
}
- void generic_visitor::visit(boot::variable_declaration *declaration)
- {
- for (const auto& variable_identifier : declaration->identifiers)
- {
- const location_t declaration_location = get_location(&declaration->position());
- const std::string& variable_name = variable_identifier.name();
- tree declaration_tree = this->symbols->lookup(variable_name);
-
- auto variable_symbol = this->bag.lookup(variable_name)->is_variable();
-
- if (declaration_tree == NULL_TREE)
- {
- declaration_tree = declare_variable(variable_name, *variable_symbol, this->symbols);
- }
- if (variable_symbol->alignment.has_value())
- {
- SET_DECL_ALIGN(declaration_tree,
- variable_symbol->alignment.value() * BITS_PER_UNIT);
- DECL_USER_ALIGN(declaration_tree) = 1;
- }
- if (variable_symbol->value.has_value())
- {
- tree type = get_inner_alias(variable_symbol->symbol, this->symbols);
- DECL_INITIAL(declaration_tree) = constant_to_tree(
- variable_symbol->value.value(), this->symbols, type);
- }
- else if (declaration->initializer != nullptr)
- {
- declaration->initializer->accept(this);
- DECL_INITIAL(declaration_tree) = this->current_expression;
- }
- else if (!declaration->is_extern && POINTER_TYPE_P(TREE_TYPE(declaration_tree)))
- {
- DECL_INITIAL(declaration_tree) = null_pointer_node;
- }
- if (variable_symbol->symbol.get<boot::constant_type>() != nullptr)
- {
- TREE_READONLY(declaration_tree) = 1;
- }
- this->current_expression = NULL_TREE;
-
- if (lang_hooks.decls.global_bindings_p())
- {
- TREE_STATIC(declaration_tree) = static_cast<unsigned>(!declaration->is_extern);
- varpool_node::get_create(declaration_tree);
- varpool_node::finalize_decl(declaration_tree);
- }
- else
- {
- DECL_CONTEXT(declaration_tree) = current_function_decl;
- f_binding_level->names = chainon(f_binding_level->names, declaration_tree);
-
- tree declaration_statement = build1_loc(declaration_location, DECL_EXPR,
- void_type_node, declaration_tree);
- append_statement(declaration_statement);
- }
- }
- }
-
void generic_visitor::visit(boot::named_expression *expression)
{
tree symbol = this->symbols->lookup(expression->name);
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h
index 0fc5e32..5d5bdce 100644
--- a/include/elna/boot/ast.h
+++ b/include/elna/boot/ast.h
@@ -395,13 +395,8 @@ namespace elna::boot
/**
* Symbol definition.
*/
- class declaration : public node
+ class declaration : public virtual node
{
- protected:
- declaration(const source_position position, identifier_definition identifier);
-
- public:
- const identifier_definition identifier;
};
/**
@@ -591,7 +586,7 @@ namespace elna::boot
/**
* Variable declaration.
*/
- class variable_declaration : public node
+ class variable_declaration : public declaration
{
std::shared_ptr<type_expression> m_variable_type;
@@ -680,7 +675,8 @@ namespace elna::boot
procedure_type_expression *m_heading;
public:
- std::optional<procedure_body> body;
+ const identifier_definition identifier;
+ const std::optional<procedure_body> body;
/**
* Type parameters bound by this declaration. Empty for a plain
@@ -707,9 +703,9 @@ namespace elna::boot
type_expression *m_underlying_type;
public:
- /**
- * Type parameters bound by this declaration. Empty for a plain type.
- */
+ const identifier_definition identifier;
+
+ /// Type parameters bound by this declaration. Empty for a plain type.
std::vector<elna::boot::identifier> parameters;
type_declaration(const source_position position, identifier_definition identifier,
@@ -1049,23 +1045,17 @@ namespace elna::boot
{
public:
const std::vector<import_declaration *> imports;
- const std::vector<type_declaration *> types;
- const std::vector<procedure_declaration *> procedures;
- const std::vector<variable_declaration *> variables;
+ const std::vector<declaration *> declarations;
const std::optional<procedure_body> entry_point;
const std::vector<identifier> parameters;
const std::optional<source_position> entry_position;
unit(const source_position position,
std::vector<import_declaration *>&& imports,
- std::vector<type_declaration *>&& types,
- std::vector<variable_declaration *>&& variables,
- std::vector<procedure_declaration *>&& procedures);
+ std::vector<declaration *>&& declarations);
unit(const source_position position,
std::vector<import_declaration *>&& imports,
- std::vector<type_declaration *>&& types,
- std::vector<variable_declaration *>&& variables,
- std::vector<procedure_declaration *>&& procedures,
+ std::vector<declaration *>&& declarations,
std::vector<identifier>&& parameters,
const source_position entry_position,
std::optional<procedure_body>&& body);
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
index 73f0a66..eff122b 100644
--- a/include/elna/boot/name_analysis.h
+++ b/include/elna/boot/name_analysis.h
@@ -191,6 +191,8 @@ namespace elna::boot
void visit(unit *unit) override;
void visit(type_declaration *declaration) override;
+ void visit(variable_declaration *) override;
+ void visit(procedure_declaration *) override;
};
/**
@@ -293,8 +295,6 @@ namespace elna::boot
type lookup_field(const type& composite_type, const std::string& field_name);
public:
- void visit(variable_declaration *declaration) override;
-
void visit(array_type_expression *expression) override;
void visit(slice_type_expression *expression) override;
void visit(pointer_type_expression *expression) override;
@@ -367,6 +367,7 @@ namespace elna::boot
void visit(unit *unit) override;
void visit(type_declaration *declaration) override;
+ void visit(variable_declaration *declaration) override;
void visit(procedure_declaration *declaration) override;
[[noreturn]] void visit(for_statement *) override;
@@ -385,7 +386,8 @@ namespace elna::boot
const std::filesystem::path& module_path);
void visit(unit *unit) override;
- [[noreturn]] void visit(type_declaration *) override;
+ void visit(type_declaration *) override;
+ void visit(variable_declaration *declaration) override;
void visit(procedure_declaration *declaration) override;
void visit(for_statement *statement) override;
diff --git a/include/elna/boot/validation.h b/include/elna/boot/validation.h
index c99ce07..8598ada 100644
--- a/include/elna/boot/validation.h
+++ b/include/elna/boot/validation.h
@@ -48,19 +48,23 @@ namespace elna::boot
symbol_bag& bag;
evaluator constant_evaluator;
+ void visit_statements(const std::vector<statement *>& statements);
+
public:
validation_visitor(symbol_bag& bag, const target_info& target);
void visit(unit *unit) override;
+ void visit(type_declaration *declaration) override;
+ void visit(variable_declaration *) override;
void visit(procedure_declaration *declaration) override;
- void visit(case_statement *statement) override;
+ void visit(case_statement *statement) override;
void visit(assign_statement *) override;
- void visit(if_statement *) override;
- void visit(while_statement *) override;
- void visit(repeat_statement *) override;
- void visit(for_statement *) override;
- void visit(defer_statement *) override;
+ void visit(if_statement *statement) override;
+ void visit(while_statement *statement) override;
+ void visit(repeat_statement *statement) override;
+ void visit(for_statement *statement) override;
+ void visit(defer_statement *statement) override;
void visit(empty_statement *) override;
void visit(procedure_call *) override;
};
diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h
index d67f3c9..fbd68d8 100644
--- a/include/elna/gcc/elna-generic.h
+++ b/include/elna/gcc/elna-generic.h
@@ -71,7 +71,9 @@ namespace elna::gcc
generic_visitor(const std::shared_ptr<symbol_table>& symbol_table,
elna::boot::symbol_bag bag, const elna::boot::target_info& target);
- void visit(boot::procedure_declaration *declaration) override;
+ void visit(boot::type_declaration *) override;
+ void visit(boot::variable_declaration *declaration) override;
+ void visit(boot::procedure_declaration *) override;
void visit(boot::procedure_call *call) override;
void visit(boot::cast_expression *expression) override;
void visit(boot::literal<boot::integer_literal> *literal) override;
@@ -83,7 +85,6 @@ namespace elna::gcc
void visit(boot::traits_expression *trait) override;
void visit(boot::binary_expression *expression) override;
void visit(boot::unary_expression *expression) override;
- void visit(boot::variable_declaration *declaration) override;
void visit(boot::named_expression *expression) override;
void visit(boot::array_access_expression *expression) override;
void visit(boot::field_access_expression *expression) override;