aboutsummaryrefslogtreecommitdiff
path: root/frontend/semantic.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-03 08:53:03 +0200
committerEugen Wissner <belka@caraus.de>2026-07-03 08:53:03 +0200
commit4ad6052aa2816f8296e62569272e99fc0d2fd3c1 (patch)
treee1002f3fc1d51929b6f7b77f4769eb84be4e9e82 /frontend/semantic.cc
parent453332311ac2d569093f9ef62d41d13b0ce024c8 (diff)
downloadelna-4ad6052aa2816f8296e62569272e99fc0d2fd3c1.tar.gz
Merge variable_expression and named_type_expression
Diffstat (limited to 'frontend/semantic.cc')
-rw-r--r--frontend/semantic.cc88
1 files changed, 63 insertions, 25 deletions
diff --git a/frontend/semantic.cc b/frontend/semantic.cc
index 36c75b8..ee18492 100644
--- a/frontend/semantic.cc
+++ b/frontend/semantic.cc
@@ -223,10 +223,20 @@ namespace elna::frontend
{
visit(static_cast<unit *>(program));
+ this->bag.enter();
+ auto variable_type = this->bag.lookup("Int")->is_type()->symbol;
+ this->bag.enter("count", std::make_shared<variable_info>(variable_type, false));
+
+ variable_type = this->bag.lookup("Char")->is_type()->symbol;
+ variable_type = type(std::make_shared<pointer_type>(variable_type));
+ variable_type = type(std::make_shared<pointer_type>(variable_type));
+ this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false));
+
for (statement *const statement : program->body)
{
statement->accept(this);
}
+ this->bag.leave();
}
void name_analysis_visitor::visit(type_declaration *definition)
@@ -239,23 +249,8 @@ namespace elna::frontend
this->bag.enter(definition->identifier.name, info);
}
- void name_analysis_visitor::visit(named_type_expression *type_expression)
+ void name_analysis_visitor::visit(type_expression *)
{
- auto unresolved_alias = this->bag.declared(type_expression->name);
-
- if (unresolved_alias != nullptr)
- {
- this->current_type = type(unresolved_alias);
- }
- else if (auto from_symbol_table = this->bag.lookup(type_expression->name))
- {
- this->current_type = from_symbol_table->is_type()->symbol;
- }
- else
- {
- add_error<undeclared_error>(type_expression->name, this->input_file, type_expression->position());
- this->current_type = type();
- }
}
void name_analysis_visitor::visit(pointer_type_expression *type_expression)
@@ -267,7 +262,9 @@ namespace elna::frontend
void name_analysis_visitor::visit(array_type_expression *type_expression)
{
type_expression->base().accept(this);
- this->current_type = type(std::make_shared<array_type>(this->current_type, type_expression->size));
+ auto result_type{ std::make_shared<array_type>(this->current_type, type_expression->size) };
+
+ this->current_type = type(result_type);
}
std::vector<type_field> name_analysis_visitor::build_composite_type(const std::vector<field_declaration>& fields)
@@ -324,20 +321,27 @@ namespace elna::frontend
this->current_type = type(result_type);
}
+ std::shared_ptr<variable_info> name_analysis_visitor::register_variable(const std::string& name,
+ const bool is_extern, const struct position position)
+ {
+ auto variable_symbol = std::make_shared<variable_info>(this->current_type, is_extern);
+
+ if (!this->bag.enter(name, variable_symbol))
+ {
+ add_error<already_declared_error>(name, this->input_file, position);
+ }
+ return variable_symbol;
+ }
+
void name_analysis_visitor::visit(variable_declaration *declaration)
{
declaration->variable_type().accept(this);
for (const auto& variable_identifier : declaration->identifiers)
{
- auto variable_symbol = std::make_shared<variable_info>(this->current_type, declaration->is_extern);
-
+ auto variable_symbol = register_variable(variable_identifier.name, declaration->is_extern,
+ declaration->position());
variable_symbol->exported = variable_identifier.exported;
- if (!this->bag.enter(variable_identifier.name, variable_symbol))
- {
- add_error<already_declared_error>(variable_identifier.name, this->input_file,
- declaration->position());
- }
}
}
@@ -358,7 +362,19 @@ namespace elna::frontend
if (definition->body.has_value())
{
info = std::make_shared<procedure_info>(heading, definition->parameter_names, this->bag.enter());
+ auto name_iterator = std::cbegin(definition->parameter_names);
+ auto type_iterator = std::cbegin(heading.parameters);
+ while (name_iterator != std::cend(definition->parameter_names)
+ && type_iterator != std::cend(heading.parameters))
+ {
+ this->current_type = *type_iterator;
+ auto variable_symbol = register_variable(*name_iterator, false, definition->heading().position());
+ variable_symbol->exported = false;
+
+ ++name_iterator;
+ ++type_iterator;
+ }
for (constant_declaration *const constant : definition->body.value().constants())
{
constant->accept(this);
@@ -489,6 +505,10 @@ namespace elna::frontend
{
variable->accept(this);
}
+ for (constant_declaration *const constant : unit->constants)
+ {
+ constant->accept(this);
+ }
for (procedure_declaration *const procedure : unit->procedures)
{
procedure->accept(this);
@@ -522,8 +542,26 @@ namespace elna::frontend
expression->operand().accept(this);
}
- void name_analysis_visitor::visit(variable_expression *)
+ void name_analysis_visitor::visit(named_expression *type_expression)
{
+ auto unresolved_alias = this->bag.declared(type_expression->name);
+
+ if (unresolved_alias != nullptr)
+ {
+ this->current_type = type(unresolved_alias);
+ }
+ else if (auto from_symbol_table = this->bag.lookup(type_expression->name))
+ {
+ if (auto type_symbol = from_symbol_table->is_type())
+ {
+ this->current_type = type_symbol->symbol;
+ }
+ }
+ else
+ {
+ add_error<undeclared_error>(type_expression->name, this->input_file, type_expression->position());
+ this->current_type = type();
+ }
}
void name_analysis_visitor::visit(array_access_expression *expression)