aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc19
-rw-r--r--boot/parser.yy31
-rw-r--r--boot/semantic.cc19
3 files changed, 18 insertions, 51 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index b7604e5..5885cff 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -388,14 +388,6 @@ namespace elna::boot
{
}
- record_type_expression::~record_type_expression()
- {
- for (const field_declaration& field : this->fields)
- {
- delete field.second;
- }
- }
-
void record_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
@@ -412,14 +404,6 @@ namespace elna::boot
{
}
- union_type_expression::~union_type_expression()
- {
- for (const field_declaration& field : this->fields)
- {
- delete field.second;
- }
- }
-
void union_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
@@ -486,8 +470,7 @@ namespace elna::boot
}
procedure_type_expression::procedure_type_expression(const struct position position,
- std::vector<std::pair<std::vector<std::string>, std::shared_ptr<type_expression>>>&& parameters,
- return_t return_type)
+ std::vector<field_declaration>&& parameters, return_t return_type)
: node(position), return_type(return_type), parameters(std::move(parameters))
{
}
diff --git a/boot/parser.yy b/boot/parser.yy
index 3b8e69e..b05b544 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -150,11 +150,7 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<elna::boot::type_declaration *>> type_declarations type_part;
%type <std::unique_ptr<elna::boot::block>> block;
%type <elna::boot::field_declaration> field_declaration;
-%type <std::pair<std::vector<std::string>, std::shared_ptr<elna::boot::type_expression>>> formal_parameter;
-%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
- optional_fields required_fields;
-%type <std::vector<std::pair<std::vector<std::string>, std::shared_ptr<elna::boot::type_expression>>>>
- formal_parameters formal_parameter_list;
+%type <std::vector<elna::boot::field_declaration>> optional_fields required_fields;
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
%type <std::vector<elna::boot::statement *> *> else_statements;
%type <elna::boot::cast_expression *> cast_expression;
@@ -220,9 +216,9 @@ return_declaration:
/* proper procedure */ {}
| ":" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); }
| ":" type_expression { $$ = boot::procedure_type_expression::return_t($2); }
-procedure_heading: formal_parameter_list return_declaration
+procedure_heading: "(" optional_fields ")" return_declaration
{
- $$ = new boot::procedure_type_expression(boot::make_position(@1), std::move($1), std::move($2));
+ $$ = new boot::procedure_type_expression(boot::make_position(@1), std::move($2), std::move($4));
}
procedure_declaration:
"proc" identifier_definition procedure_heading block
@@ -442,7 +438,7 @@ statements:
}
| statement { $$.push_back($1); }
field_declaration:
- IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
+ identifiers ":" type_expression { $$ = std::make_pair(std::move($1), std::shared_ptr<boot::type_expression>($3)); }
required_fields:
field_declaration ";" required_fields
{
@@ -470,9 +466,9 @@ type_expression:
{
$$ = new boot::union_type_expression(boot::make_position(@1), std::move($2));
}
- | "proc" formal_parameter_list return_declaration
+ | "proc" procedure_heading
{
- $$ = new boot::procedure_type_expression(boot::make_position(@1), std::move($2), std::move($3));
+ $$ = $2;
}
| "(" identifiers ")"
{
@@ -564,21 +560,6 @@ type_declarations:
type_part:
/* no type definitions */ {}
| "type" type_declarations { std::swap($$, $2); }
-formal_parameter:
- identifiers ":" type_expression { $$ = std::make_pair(std::move($1), std::shared_ptr<boot::type_expression>($3)); }
-formal_parameter_list:
- "(" ")" {}
- | "(" formal_parameters ")" { std::swap($$, $2); }
-formal_parameters:
- formal_parameter ";" formal_parameters
- {
- std::swap($$, $3);
- $$.emplace($$.cbegin(), std::move($1.first), $1.second);
- }
- | formal_parameter
- {
- $$.emplace_back(std::move($1.first), $1.second);
- }
actual_parameter_list:
"(" ")" {}
| "(" expressions ")" { std::swap($$, $2); }
diff --git a/boot/semantic.cc b/boot/semantic.cc
index cd50742..bc7c2d2 100644
--- a/boot/semantic.cc
+++ b/boot/semantic.cc
@@ -272,15 +272,18 @@ namespace elna::boot
for (auto& field : fields)
{
- if (field_names.find(field.first) != field_names.cend())
+ field.second->accept(this);
+ for (auto& field_name : field.first)
{
- add_error<field_duplication_error>(field.first, field.second->position());
- }
- else
- {
- field_names.insert(field.first);
- field.second->accept(this);
- result.push_back(std::make_pair(field.first, this->current_type));
+ if (field_names.find(field_name) != field_names.cend())
+ {
+ add_error<field_duplication_error>(field_name, field.second->position());
+ }
+ else
+ {
+ field_names.insert(field_name);
+ result.push_back(std::make_pair(field_name, this->current_type));
+ }
}
}
return result;