diff options
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 6 | ||||
| -rw-r--r-- | boot/materialization.cc | 14 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 6 | ||||
| -rw-r--r-- | boot/parser.yy | 29 |
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 |
