From 7d07bef760a8807fe49fbe5c90799a1822f95973 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 8 Oct 2026 19:45:19 +0200 Subject: Make modules re-exportable --- boot/ast.cc | 5 +++-- boot/dependency.cc | 2 +- boot/parser.yy | 20 +++++++++++++++----- boot/symbol.cc | 17 +++++++++++++++-- 4 files changed, 34 insertions(+), 10 deletions(-) (limited to 'boot') 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&& segments) - : node(position), segments(std::move(segments)) + import_declaration::import_declaration(const source_position position, std::vector&& 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 collisions = result.value.add_import(import.symbols); + const std::vector 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 > identifier_definitions; %type > attribute; %type > attributes; -%type > import_declaration; +%type , bool>> import_declaration; +%type > import_path; %type > required_identifiers optional_identifiers generic_parameters; %type > enumeration_member; %type > 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 symbol_bag::add_import(const std::shared_ptr& symbols) + std::vector symbol_bag::add_import(const std::shared_ptr& symbols, + const bool reexport) { std::vector 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(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) -- cgit v1.2.3