aboutsummaryrefslogtreecommitdiff
path: root/boot/parser.yy
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-11 09:11:47 +0200
committerEugen Wissner <belka@caraus.de>2026-09-11 09:11:47 +0200
commitbd2b80d6ac582b9f0bcd96c86d4b79bfdb64eca1 (patch)
treea835a5cfe5a9cf48720b9255261e065fd7978849 /boot/parser.yy
parentb27872d5c5bfecae74195771f5c1f4e73385b6d6 (diff)
downloadelna-bd2b80d6ac582b9f0bcd96c86d4b79bfdb64eca1.tar.gz
Implement aligned attribute
Diffstat (limited to 'boot/parser.yy')
-rw-r--r--boot/parser.yy76
1 files changed, 59 insertions, 17 deletions
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 <std::string> STRING
%token <bool> 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 <std::vector<elna::boot::type_declaration *>> type_declarations type_part;
%type <std::unique_ptr<elna::boot::procedure_body>> procedure_body;
%type <elna::boot::field_declaration> field_declaration;
-%type <std::vector<elna::boot::field_declaration>> optional_fields required_fields;
+%type <std::vector<elna::boot::field_declaration>> field_declarations;
%type <std::unique_ptr<elna::boot::field_initializer>> field_initializer;
%type <std::vector<elna::boot::field_initializer>> field_initializers;
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
%type <std::vector<elna::boot::statement *> *> else_statements;
%type <std::unique_ptr<elna::boot::identifier>> identifier with_counter;
-%type <std::unique_ptr<elna::boot::identifier_definition>> identifier_definition;
+%type <std::unique_ptr<elna::boot::identifier_definition>> identifier_definition attributed_identifier;
%type <std::vector<elna::boot::identifier_definition>> identifier_definitions;
+%type <std::unique_ptr<elna::boot::attribute>> attribute;
+%type <std::vector<elna::boot::attribute>> attributes;
%type <std::vector<std::string>> import_declaration;
%type <std::vector<elna::boot::identifier>> required_identifiers optional_identifiers generic_parameters;
%type <elna::boot::named_expression *> name_reference;
@@ -188,18 +189,43 @@ identifier:
identifier_definition:
IDENTIFIER "*" { $$ = std::make_unique<boot::identifier_definition>($1, boot::make_position(@1), true); }
| IDENTIFIER { $$ = std::make_unique<boot::identifier_definition>($1, boot::make_position(@1), false); }
+attribute:
+ TRAIT "(" required_expressions ")"
+ {
+ $$ = std::make_unique<boot::attribute>(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::procedure_type_expression>(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<boot::type_expression>($3)); }
-required_fields:
- field_declaration ";" required_fields
+ identifier_definitions ":" type_expression
+ { $$ = std::make_pair($1, std::shared_ptr<boot::type_expression>($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<boot::field_initializer>(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<boot::attribute> 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<boot::attribute> 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
{