aboutsummaryrefslogtreecommitdiff
path: root/boot/semantic.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-07 21:39:57 +0200
committerEugen Wissner <belka@caraus.de>2026-07-07 21:39:57 +0200
commit79521d91b2bb85652fd29f5c44279338d55c757f (patch)
treed3b5b73177f63fd5ff684a8aba6f7b9af84dab27 /boot/semantic.cc
parent470bfba45661d19558c0bf43b7819696a925ecb4 (diff)
downloadelna-79521d91b2bb85652fd29f5c44279338d55c757f.tar.gz
Allow multiple parameters with same type
Diffstat (limited to 'boot/semantic.cc')
-rw-r--r--boot/semantic.cc54
1 files changed, 25 insertions, 29 deletions
diff --git a/boot/semantic.cc b/boot/semantic.cc
index 29ef3c1..cd50742 100644
--- a/boot/semantic.cc
+++ b/boot/semantic.cc
@@ -81,16 +81,6 @@ namespace elna::boot
return "Procedure '" + identifier + "' is expected to return, but does not have a return statement";
}
- variable_initializer_error::variable_initializer_error(const struct position position)
- : error(position)
- {
- }
-
- std::string variable_initializer_error::what() const
- {
- return "Only one variable can be initialized";
- }
-
type_analysis_visitor::type_analysis_visitor(symbol_bag bag)
: error_container(), bag(bag)
{
@@ -194,7 +184,8 @@ namespace elna::boot
{
}
- procedure_type name_analysis_visitor::build_procedure(procedure_type_expression& type_expression)
+ std::pair<procedure_type, std::vector<std::string>> name_analysis_visitor::build_procedure(
+ procedure_type_expression& type_expression)
{
procedure_type::return_t result_return;
@@ -211,12 +202,17 @@ namespace elna::boot
{
result_return = procedure_type::return_t();
}
- procedure_type result_type = procedure_type(result_return);
-
- for (struct type_expression *parameter : type_expression.parameters)
+ std::pair<procedure_type, std::vector<std::string>> result_type{
+ procedure_type(result_return), std::vector<std::string>()
+ };
+ for (auto& [parameter_names, parameters_type] : type_expression.parameters)
{
- parameter->accept(this);
- result_type.parameters.push_back(this->current_type);
+ parameters_type->accept(this);
+ for (auto& parameter_name : parameter_names)
+ {
+ result_type.first.parameters.push_back(this->current_type);
+ result_type.second.push_back(parameter_name);
+ }
}
return result_type;
}
@@ -311,7 +307,7 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_type_expression *type_expression)
{
std::shared_ptr<procedure_type> result_type =
- std::make_shared<procedure_type>(std::move(build_procedure(*type_expression)));
+ std::make_shared<procedure_type>(std::move(build_procedure(*type_expression).first));
this->current_type = type(result_type);
}
@@ -359,16 +355,15 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_declaration *definition)
{
std::shared_ptr<procedure_info> info;
- auto heading = build_procedure(definition->heading());
+ auto [heading, parameter_names] = build_procedure(definition->heading());
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);
+ info = std::make_shared<procedure_info>(heading, std::move(parameter_names), this->bag.enter());
+ auto name_iterator = std::cbegin(info->names);
auto type_iterator = std::cbegin(heading.parameters);
- while (name_iterator != std::cend(definition->parameter_names)
- && type_iterator != std::cend(heading.parameters))
+ while (name_iterator != std::cend(info->names) && type_iterator != std::cend(heading.parameters))
{
this->current_type = *type_iterator;
auto variable_symbol = register_variable(*name_iterator, false, definition->heading().position());
@@ -393,7 +388,7 @@ namespace elna::boot
}
else
{
- info = std::make_shared<procedure_info>(heading, definition->parameter_names);
+ info = std::make_shared<procedure_info>(heading, std::move(parameter_names));
}
info->exported = definition->identifier.exported;
this->bag.enter(definition->identifier.name, info);
@@ -494,7 +489,12 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_call *call)
{
- call->callable().accept(this);
+ auto name_expression = call->callable().is_named();
+
+ if (name_expression == nullptr || name_expression->name != "assert")
+ {
+ call->callable().accept(this);
+ }
for (expression *const argument: call->arguments)
{
argument->accept(this);
@@ -665,12 +665,8 @@ namespace elna::boot
}
}
- void declaration_visitor::visit(variable_declaration *declaration)
+ void declaration_visitor::visit(variable_declaration *)
{
- if (declaration->has_initializer() && declaration->identifiers.size() > 1)
- {
- add_error<variable_initializer_error>(declaration->position());
- }
}
void declaration_visitor::visit(procedure_declaration *definition)