aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc6
-rw-r--r--boot/materialization.cc14
-rw-r--r--boot/name_analysis.cc6
-rw-r--r--boot/parser.yy29
4 files changed, 37 insertions, 18 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index 456797a..b681695 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -597,8 +597,10 @@ namespace elna::boot
}
identifier_definition::identifier_definition(const std::string& name,
- const source_position& position, const bool exported, std::vector<attribute>&& attributes)
- : attributes(std::move(attributes)), m_identifier(name, position), m_exported(exported)
+ const source_position& position, const bool exported,
+ std::vector<identifier>&& parameters, std::vector<attribute>&& attributes)
+ : parameters(std::move(parameters)), attributes(std::move(attributes)),
+ m_identifier(name, position), m_exported(exported)
{
}
diff --git a/boot/materialization.cc b/boot/materialization.cc
index 6eea0d1..9e9d3ae 100644
--- a/boot/materialization.cc
+++ b/boot/materialization.cc
@@ -39,6 +39,10 @@ namespace elna::boot
return "Local symbols cannot be extern";
case field_export:
return "Record fields cannot be exported";
+ case variable_generic:
+ return "Variables cannot have generic parameters";
+ case field_generic:
+ return "Record fields cannot have generic parameters";
}
__builtin_unreachable();
}
@@ -78,6 +82,11 @@ namespace elna::boot
add_error<materialization_error>(variable_identifier.id().position(),
materialization_error::kind::local_export);
}
+ if (!variable_identifier.parameters.empty())
+ {
+ add_error<materialization_error>(variable_identifier.id().position(),
+ materialization_error::kind::variable_generic);
+ }
}
if (!this->in_global_scope && declaration->is_extern)
{
@@ -99,6 +108,11 @@ namespace elna::boot
add_error<materialization_error>(field_identifier.id().position(),
materialization_error::kind::field_export);
}
+ if (!field_identifier.parameters.empty())
+ {
+ add_error<materialization_error>(field_identifier.id().position(),
+ materialization_error::kind::field_generic);
+ }
}
}
}
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index c58b586..17e15f6 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -1409,13 +1409,13 @@ namespace elna::boot
void declaration_visitor::visit(type_declaration *declaration)
{
- const bool is_generic = !declaration->parameters.empty();
+ const bool is_generic = !declaration->identifier.parameters.empty();
std::vector<type> parameters;
if (is_generic)
{
this->bag.enter();
- parameters = enter_parameters(declaration->parameters);
+ parameters = enter_parameters(declaration->identifier.parameters);
}
type underlying = resolve_type(declaration->underlying_type());
@@ -1514,7 +1514,7 @@ namespace elna::boot
// parameters are visible in it, and it becomes the body's scope, which
// is why the body sees them too.
const std::shared_ptr<symbol_table> scope = this->bag.enter();
- const std::vector<type> type_parameters = enter_parameters(declaration->parameters);
+ const std::vector<type> type_parameters = enter_parameters(declaration->identifier.parameters);
auto [heading, parameter_names, noreturn] = !declaration->body.has_value()
? build_procedure<attribute_kind::varargs, attribute_kind::noreturn>(declaration->heading())
: build_procedure<attribute_kind::noreturn>(declaration->heading());
diff --git a/boot/parser.yy b/boot/parser.yy
index 65d3dba..855cc76 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -161,6 +161,7 @@ along with GCC; see the file COPYING3. If not see
%type <std::unique_ptr<elna::boot::attribute>> attribute;
%type <std::vector<elna::boot::attribute>> attributes;
%type <std::pair<std::vector<std::string>, bool>> import_declaration;
+%type <bool> export_marker;
%type <std::vector<std::string>> import_path;
%type <std::vector<elna::boot::identifier>> required_identifiers optional_identifiers generic_parameters;
%type <std::unique_ptr<elna::boot::enumeration_type_expression::member_declaration>> enumeration_member;
@@ -244,9 +245,15 @@ optional_begin_statements:
| statements { $$ = $1; }
identifier:
IDENTIFIER { $$ = std::make_unique<boot::identifier>($1, boot::make_position(@1)); }
+export_marker:
+ "*" { $$ = true; }
+ | %empty { $$ = false; }
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); }
+ IDENTIFIER generic_parameters export_marker
+ {
+ $$ = std::make_unique<boot::identifier_definition>($1, boot::make_position(@1),
+ $3, std::move($2));
+ }
attribute:
"#{" IDENTIFIER optional_expressions "}"
{
@@ -282,16 +289,14 @@ procedure_heading:
$$->attributes = $4;
}
procedure_declaration:
- "proc" identifier_definition generic_parameters procedure_heading procedure_body
+ "proc" identifier_definition procedure_heading procedure_body
{
$$ = new boot::procedure_declaration(boot::make_position(@$),
- std::move(*$2), $4, std::move(*$5));
- $$->parameters = $3;
+ std::move(*$2), $3, std::move(*$4));
}
- | "proc" identifier_definition generic_parameters procedure_heading "extern"
+ | "proc" identifier_definition procedure_heading "extern"
{
- $$ = new boot::procedure_declaration(boot::make_position(@$), std::move(*$2), $4);
- $$->parameters = $3;
+ $$ = new boot::procedure_declaration(boot::make_position(@$), std::move(*$2), $3);
}
call_expression:
designator_expression actual_parameter_list
@@ -764,16 +769,14 @@ import_declarations:
new boot::import_declaration(boot::make_position(@$), std::move(segments), exported));
}
type_declaration:
- identifier_definition generic_parameters "=" type_expression
+ identifier_definition "=" type_expression
{
- $$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1), $4);
- $$->parameters = $2;
+ $$ = new boot::type_declaration(boot::make_position(@$), std::move(*$1), $3);
}
- | identifier_definition generic_parameters "=" "extern"
+ | identifier_definition "=" "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