aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-10-08 19:45:19 +0200
committerEugen Wissner <belka@caraus.de>2026-10-08 19:45:19 +0200
commit7d07bef760a8807fe49fbe5c90799a1822f95973 (patch)
tree8b8d8ed0003dc61c4bd7313df86f6cbaea3d4b82 /boot
parentd392f0c54a7748b816ab327758ae835f73cd1c0a (diff)
downloadelna-7d07bef760a8807fe49fbe5c90799a1822f95973.tar.gz
Make modules re-exportable
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc5
-rw-r--r--boot/dependency.cc2
-rw-r--r--boot/parser.yy20
-rw-r--r--boot/symbol.cc17
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)