From bd2b80d6ac582b9f0bcd96c86d4b79bfdb64eca1 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 11 Sep 2026 09:11:47 +0200 Subject: Implement aligned attribute --- boot/parser.yy | 76 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 17 deletions(-) (limited to 'boot/parser.yy') diff --git a/boot/parser.yy b/boot/parser.yy index 00bdae8..21ff827 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -88,8 +88,7 @@ along with GCC; see the file COPYING3. If not see %token STRING %token BOOLEAN %token LEFT_PAREN "(" RIGHT_PAREN ")" LEFT_SQUARE "[" RIGHT_SQUARE "]" -%token GENERIC_OPEN "#[" -%token LEFT_BRACE "{" RIGHT_BRACE "}" + LEFT_BRACE "{" RIGHT_BRACE "}" GENERIC_OPEN "#[" %token ASSIGNMENT ":=" EXCLAMATION "!" ARROW "->" AT "@" HAT "^" @@ -149,14 +148,16 @@ along with GCC; see the file COPYING3. If not see %type > type_declarations type_part; %type > procedure_body; %type field_declaration; -%type > optional_fields required_fields; +%type > field_declarations; %type > field_initializer; %type > field_initializers; %type > elsif_then_statements elsif_do_statements; %type *> else_statements; %type > identifier with_counter; -%type > identifier_definition; +%type > identifier_definition attributed_identifier; %type > identifier_definitions; +%type > attribute; +%type > attributes; %type > import_declaration; %type > required_identifiers optional_identifiers generic_parameters; %type name_reference; @@ -188,18 +189,43 @@ identifier: identifier_definition: IDENTIFIER "*" { $$ = std::make_unique($1, boot::make_position(@1), true); } | IDENTIFIER { $$ = std::make_unique($1, boot::make_position(@1), false); } +attribute: + TRAIT "(" required_expressions ")" + { + $$ = std::make_unique(boot::identifier($1, boot::make_position(@1)), $3); + } +attributes: + %empty {} + | attribute attributes + { + $$ = $2; + $$.emplace($$.cbegin(), std::move(*$1)); + } +attributed_identifier: + attributes identifier_definition + { + $$ = $2; + $$->attributes = $1; + + // An empty rule is located where the previous token ended, which + // would push the declaration's position back over it. + if ($$->attributes.empty()) + { + @$ = @2; + } + } identifier_definitions: - identifier_definition "," identifier_definitions + attributed_identifier "," identifier_definitions { $$ = $3; $$.emplace($$.cbegin(), std::move(*$1)); } - | identifier_definition { $$.emplace_back(std::move(*$1)); } + | attributed_identifier { $$.emplace_back(std::move(*$1)); } return_declaration: %empty {} | "->" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); } | "->" type_expression { $$ = boot::procedure_type_expression::return_t($2); } -procedure_heading: "(" optional_fields ")" return_declaration +procedure_heading: "(" field_declarations ")" return_declaration { $$ = std::make_unique(boot::make_position(@$), $2, $4); } procedure_declaration: "proc" identifier_definition generic_parameters procedure_heading procedure_body @@ -555,16 +581,15 @@ statements: } | statement { $$.push_back($1); } field_declaration: - required_identifiers ":" type_expression { $$ = std::make_pair($1, std::shared_ptr($3)); } -required_fields: - field_declaration ";" required_fields + identifier_definitions ":" type_expression + { $$ = std::make_pair($1, std::shared_ptr($3)); } +field_declarations: + field_declaration ";" field_declarations { $$ = $3; $$.emplace($$.cbegin(), $1); } | field_declaration { $$.emplace_back($1); } -optional_fields: - required_fields { $$ = $1; } | %empty {} field_initializer: identifier ":" expression { $$ = std::make_unique(std::move(*$1), $3); } @@ -591,18 +616,35 @@ type_expression: { $$ = new boot::pointer_type_expression(boot::make_position(@$), $2); } - | "record" optional_fields "end" + | attributes "record" field_declarations "end" { - $$ = new boot::record_type_expression(boot::make_position(@$), $2); + std::vector written = $1; + + if (written.empty()) + { + @$ = @2 + @4; + } + auto *record = new boot::record_type_expression(boot::make_position(@$), $3); + + record->attributes = std::move(written); + $$ = record; } - | "record" "(" name_reference ")" optional_fields "end" + | attributes "record" "(" name_reference ")" field_declarations "end" { - boot::named_expression *reference = $3; + std::vector written = $1; - $$ = new boot::record_type_expression(boot::make_position(@$), $5, + if (written.empty()) + { + @$ = @2 + @7; + } + boot::named_expression *reference = $4; + auto *record = new boot::record_type_expression(boot::make_position(@$), $6, boot::identifier(reference->name, reference->position()), std::move(reference->arguments)); + + record->attributes = std::move(written); delete reference; + $$ = record; } | "proc" procedure_heading { -- cgit v1.2.3