diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-08 19:45:19 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-08 19:45:19 +0200 |
| commit | 7d07bef760a8807fe49fbe5c90799a1822f95973 (patch) | |
| tree | 8b8d8ed0003dc61c4bd7313df86f6cbaea3d4b82 /boot | |
| parent | d392f0c54a7748b816ab327758ae835f73cd1c0a (diff) | |
| download | elna-7d07bef760a8807fe49fbe5c90799a1822f95973.tar.gz | |
Make modules re-exportable
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 5 | ||||
| -rw-r--r-- | boot/dependency.cc | 2 | ||||
| -rw-r--r-- | boot/parser.yy | 20 | ||||
| -rw-r--r-- | boot/symbol.cc | 17 |
4 files changed, 34 insertions, 10 deletions
diff --git a/boot/ast.cc b/boot/ast.cc index 69b15d3..456797a 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -1681,8 +1681,9 @@ namespace elna::boot delete this->alternative; } - import_declaration::import_declaration(const source_position position, std::vector<std::string>&& segments) - : node(position), segments(std::move(segments)) + import_declaration::import_declaration(const source_position position, std::vector<std::string>&& segments, + const bool exported) + : node(position), segments(std::move(segments)), exported(exported) { } diff --git a/boot/dependency.cc b/boot/dependency.cc index 5053a36..31eccc9 100644 --- a/boot/dependency.cc +++ b/boot/dependency.cc @@ -90,7 +90,7 @@ namespace elna::boot } for (const auto& import : imports) { - const std::vector<import_collision> collisions = result.value.add_import(import.symbols); + const std::vector<import_collision> collisions = result.value.add_import(import.symbols, import.reexport); for (const import_collision& collision : collisions) { diff --git a/boot/parser.yy b/boot/parser.yy index cfa63d5..65d3dba 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -160,7 +160,8 @@ along with GCC; see the file COPYING3. If not see %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::pair<std::vector<std::string>, bool>> import_declaration; +%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; %type <std::vector<elna::boot::enumeration_type_expression::member_declaration>> enumeration_members; @@ -736,22 +737,31 @@ variable_declarations: $$ = $2; $$.insert(std::cbegin($$), $1); } -import_declaration: - IDENTIFIER "." import_declaration +import_path: + IDENTIFIER "." import_path { $$ = $3; $$.emplace($$.cbegin(), $1); } | IDENTIFIER { $$.emplace_back($1); } +import_declaration: + import_path "*" { $$ = { $1, true }; } + | import_path { $$ = { $1, false }; } import_declarations: import_declaration "," import_declarations { + auto [segments, exported] = $1; + $$ = $3; - $$.emplace($$.cbegin(), new boot::import_declaration(boot::make_position(@$), $1)); + $$.emplace($$.cbegin(), + new boot::import_declaration(boot::make_position(@$), std::move(segments), exported)); } | import_declaration { - $$.emplace_back(new boot::import_declaration(boot::make_position(@$), $1)); + auto [segments, exported] = $1; + + $$.emplace_back( + new boot::import_declaration(boot::make_position(@$), std::move(segments), exported)); } type_declaration: identifier_definition generic_parameters "=" type_expression diff --git a/boot/symbol.cc b/boot/symbol.cc index 375cbfd..2805839 100644 --- a/boot/symbol.cc +++ b/boot/symbol.cc @@ -522,7 +522,8 @@ namespace elna::boot return this->unresolved.insert({ symbol_name, std::move(forward_declaration) }).second; } - std::vector<import_collision> symbol_bag::add_import(const std::shared_ptr<symbol_table>& symbols) + std::vector<import_collision> symbol_bag::add_import(const std::shared_ptr<symbol_table>& symbols, + const bool reexport) { std::vector<import_collision> collisions; @@ -538,7 +539,10 @@ namespace elna::boot } } this->imports.push_back(symbols); - + if (reexport) + { + this->reexports.push_back(symbols); + } return collisions; } @@ -553,6 +557,15 @@ namespace elna::boot if (!m_exported) { m_exported = std::make_shared<symbol_table>(symbols->scope()); + // The same symbol can reach a module along several re-export + // paths; it is the same info then, so entering it twice is a no-op. + for (const auto& reexported : this->reexports) + { + for (const auto& [name, info] : *reexported) + { + m_exported->enter(name, info); + } + } for (const auto& [name, info] : *symbols) { if (info->exported) |
