diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-08 11:04:34 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-08 11:04:34 +0200 |
| commit | ffe6097c534c82b9402bb6f0a57abeebd075e61d (patch) | |
| tree | 9079255db89007046fe1446d27009df8585a154e /boot | |
| parent | 79521d91b2bb85652fd29f5c44279338d55c757f (diff) | |
| download | elna-ffe6097c534c82b9402bb6f0a57abeebd075e61d.tar.gz | |
Allow multiple fields with the same type
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 19 | ||||
| -rw-r--r-- | boot/parser.yy | 31 | ||||
| -rw-r--r-- | boot/semantic.cc | 19 |
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; |
