aboutsummaryrefslogtreecommitdiff
path: root/boot/parser.yy
diff options
context:
space:
mode:
Diffstat (limited to 'boot/parser.yy')
-rw-r--r--boot/parser.yy54
1 files changed, 37 insertions, 17 deletions
diff --git a/boot/parser.yy b/boot/parser.yy
index ba611b5..00bdae8 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -88,6 +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 "}"
%token ASSIGNMENT ":="
EXCLAMATION "!" ARROW "->"
@@ -157,7 +158,8 @@ along with GCC; see the file COPYING3. If not see
%type <std::unique_ptr<elna::boot::identifier_definition>> identifier_definition;
%type <std::vector<elna::boot::identifier_definition>> identifier_definitions;
%type <std::vector<std::string>> import_declaration;
-%type <std::vector<elna::boot::identifier>> required_identifiers optional_identifiers;
+%type <std::vector<elna::boot::identifier>> required_identifiers optional_identifiers generic_parameters;
+%type <elna::boot::named_expression *> name_reference;
%type <std::vector<elna::boot::import_declaration *>> import_declarations import_part;
%type <std::unique_ptr<elna::boot::array_type_expression>> array_type_expression;
%%
@@ -200,14 +202,16 @@ return_declaration:
procedure_heading: "(" optional_fields ")" return_declaration
{ $$ = std::make_unique<boot::procedure_type_expression>(boot::make_position(@$), $2, $4); }
procedure_declaration:
- "proc" identifier_definition procedure_heading procedure_body
+ "proc" identifier_definition generic_parameters procedure_heading procedure_body
{
$$ = new boot::procedure_declaration(boot::make_position(@$),
- std::move(*$2), $3.release(), std::move(*$4));
+ std::move(*$2), $4.release(), std::move(*$5));
+ $$->parameters = $3;
}
- | "proc" identifier_definition procedure_heading "extern"
+ | "proc" identifier_definition generic_parameters procedure_heading "extern"
{
- $$ = new boot::procedure_declaration(boot::make_position(@$), std::move(*$2), $3.release());
+ $$ = new boot::procedure_declaration(boot::make_position(@$), std::move(*$2), $4.release());
+ $$->parameters = $3;
}
procedure_part:
%empty {}
@@ -349,9 +353,14 @@ simple_expression:
}
| call_expression { $$ = $1.release(); }
| "(" expression ")" { $$ = $2; }
- | identifier "{" field_initializers "}"
+ | name_reference "{" field_initializers "}"
{
- $$ = new boot::record_constructor_expression(boot::make_position(@$), std::move(*$1), $3);
+ boot::named_expression *reference = $1;
+
+ $$ = new boot::record_constructor_expression(boot::make_position(@$),
+ boot::identifier(reference->name, reference->position()),
+ std::move(reference->arguments), $3);
+ delete reference;
}
| "[" required_expressions "]"
{
@@ -489,8 +498,12 @@ designator_expression:
{ $$ = new boot::field_access_expression(boot::make_position(@$), $1, std::move(*$3)); }
| simple_expression "^"
{ $$ = new boot::dereference_expression(boot::make_position(@$), $1); }
- | IDENTIFIER
+ | name_reference { $$ = $1; }
+name_reference:
+ IDENTIFIER
{ $$ = new boot::named_expression(boot::make_position(@$), $1); }
+ | IDENTIFIER "#[" type_expressions "]"
+ { $$ = new boot::named_expression(boot::make_position(@$), $1, $3); }
statement:
designator_expression ":=" expression
{ $$ = new boot::assign_statement(boot::make_position(@$), $1, $3); }
@@ -582,9 +595,14 @@ type_expression:
{
$$ = new boot::record_type_expression(boot::make_position(@$), $2);
}
- | "record" "(" identifier ")" optional_fields "end"
+ | "record" "(" name_reference ")" optional_fields "end"
{
- $$ = new boot::record_type_expression(boot::make_position(@$), $5, std::move(*$3));
+ boot::named_expression *reference = $3;
+
+ $$ = new boot::record_type_expression(boot::make_position(@$), $5,
+ boot::identifier(reference->name, reference->position()),
+ std::move(reference->arguments));
+ delete reference;
}
| "proc" procedure_heading
{
@@ -594,10 +612,10 @@ type_expression:
{
$$ = new boot::enumeration_type_expression(boot::make_position(@$), $2);
}
- | IDENTIFIER
- {
- $$ = new boot::named_expression(boot::make_position(@$), $1);
- }
+ | name_reference { $$ = $1; }
+generic_parameters:
+ %empty {}
+ | "#[" required_identifiers "]" { $$ = $2; }
required_identifiers:
identifier "," required_identifiers
{
@@ -654,14 +672,16 @@ import_declarations:
import_part:
%empty {}
| "import" import_declarations { $$ = $2; }
-type_declaration: identifier_definition "=" type_expression
+type_declaration: identifier_definition generic_parameters "=" type_expression
{
- $$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1), $3);
+ $$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1), $4);
+ $$->parameters = $2;
}
- | identifier_definition "=" "extern"
+ | identifier_definition generic_parameters "=" "extern"
{
$$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1),
new boot::extern_type_expression(boot::make_position(@$)));
+ $$->parameters = $2;
}
type_declarations:
type_declaration type_declarations