diff options
author | John Hodge <tpg@mutabah.net> | 2016-04-30 12:10:35 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-04-30 12:10:35 +0800 |
commit | f5c9ee756d97fb8c02fd74faeab7a50907de6690 (patch) | |
tree | 854f70f73fdfb23fccca203f0136febdec57e50d /src/resolve | |
parent | bce9d5618eb54201cef08b1ba158d267cdef0b4f (diff) | |
download | mrust-f5c9ee756d97fb8c02fd74faeab7a50907de6690.tar.gz |
Resolve - Further work on use/index.
- Use recurses into (some) code blocks
- Index does three passes to reduce the chance of wildcard import troubles. (HACK)
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/index.cpp | 56 | ||||
-rw-r--r-- | src/resolve/use.cpp | 94 |
2 files changed, 128 insertions, 22 deletions
diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 697e98f1..cb4ffc6b 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -31,7 +31,7 @@ void _add_item_value(AST::Module& mod, const ::std::string& name, bool is_pub, : _add_item(mod, false, name, is_pub, mv$(ir), error_on_collision); } -void Resolve_Index_Module(AST::Module& mod) +void Resolve_Index_Module_Base(AST::Module& mod) { TRACE_FUNCTION_F("mod = " << mod.path()); for( const auto& i : mod.items() ) @@ -73,6 +73,7 @@ void Resolve_Index_Module(AST::Module& mod) ) } + bool has_pub_wildcard = false; // Named imports for( const auto& i : mod.imports() ) { @@ -82,7 +83,7 @@ void Resolve_Index_Module(AST::Module& mod) const auto& b = i.data.path.binding(); TU_MATCH(::AST::PathBinding, (b), (e), (Unbound, - BUG(sp, "Import left unbound"); + BUG(sp, "Import left unbound ("<<i.data.path<<")"); ), (Variable, BUG(sp, "Import was bound to variable"); @@ -111,13 +112,41 @@ void Resolve_Index_Module(AST::Module& mod) (EnumVar , _add_item_value(mod, i.name, i.is_pub, b.clone()); ) ) } + else + { + if( i.is_pub ) + { + has_pub_wildcard = true; + } + } } - mod.m_index_populated = 1; + mod.m_index_populated = (has_pub_wildcard ? 1 : 2); + + // Handle child modules + for( auto& i : mod.items() ) + { + TU_MATCH_DEF(AST::Item, (i.data), (e), + ( + ), + (Module, + Resolve_Index_Module_Base(e); + ) + ) + } + for(auto& mp : mod.anon_mods()) + { + Resolve_Index_Module_Base(*mp); + } +} + +void Resolve_Index_Module_Wildcard(AST::Module& mod, bool handle_pub) +{ + TRACE_FUNCTION_F("mod = " << mod.path()); // Glob/wildcard imports for( const auto& i : mod.imports() ) { - if( i.name == "" ) + if( i.name == "" && i.is_pub == handle_pub ) { const auto& sp = i.data.sp; const auto& b = i.data.path.binding(); @@ -126,7 +155,7 @@ void Resolve_Index_Module(AST::Module& mod) BUG(sp, "Glob import of invalid type encountered"); ), (Unbound, - BUG(sp, "Import left unbound"); + BUG(sp, "Import left unbound ("<<i.data.path<<")"); ), (Variable, BUG(sp, "Import was bound to variable"); @@ -146,9 +175,10 @@ void Resolve_Index_Module(AST::Module& mod) ERROR(sp, E0000, "Glob import of self"); } // 1. Begin indexing of this module if it is not already indexed - if( !e.module_->m_index_populated ) + if( e.module_->m_index_populated == 1 ) { - TODO(sp, "Handle glob import of module not yet indexed"); + // TODO: Handle wildcard import of a module with a public wildcard import + TODO(sp, "Handle wildcard import of module with a wildcard (" << e.module_->path() << " by " << mod.path() << ")"); //Resolve_Index_Module( *e.module_ ); } for(const auto& vi : e.module_->m_type_items) { @@ -178,6 +208,8 @@ void Resolve_Index_Module(AST::Module& mod) ) } } + + // handle_pub == true first, leading to full resoltion no matter what mod.m_index_populated = 2; // Handle child modules @@ -187,13 +219,19 @@ void Resolve_Index_Module(AST::Module& mod) ( ), (Module, - Resolve_Index_Module(e); + Resolve_Index_Module_Wildcard(e, handle_pub); ) ) } + for(auto& mp : mod.anon_mods()) + { + Resolve_Index_Module_Wildcard(*mp, handle_pub); + } } void Resolve_Index(AST::Crate& crate) { - Resolve_Index_Module(crate.m_root_module); + Resolve_Index_Module_Base(crate.m_root_module); + Resolve_Index_Module_Wildcard(crate.m_root_module, true); + Resolve_Index_Module_Wildcard(crate.m_root_module, false); } diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 6eb837e6..5d794b66 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -4,10 +4,12 @@ #include <main_bindings.hpp> #include <ast/crate.hpp> #include <ast/ast.hpp> +#include <ast/expr.hpp> -void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path); ::AST::Path Resolve_Use_AbsolutisePath(const ::AST::Path& base_path, ::AST::Path path); -::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path); +void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path, slice< const ::AST::Module* > parent_modules={}); +::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, slice< const ::AST::Module* > parent_modules); + void Resolve_Use(::AST::Crate& crate) { @@ -54,7 +56,7 @@ void Resolve_Use(::AST::Crate& crate) throw "BUG: Reached end of Resolve_Use_AbsolutisePath"; } -void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path) +void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path path, slice< const ::AST::Module* > parent_modules) { TRACE_FUNCTION_F("path = " << path << ", mod.path() = " << mod.path()); for(auto& use_stmt : mod.imports()) @@ -68,7 +70,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( use_stmt.data.path.crate() != "" ) BUG(span, "Use path crate was set before resolve"); - use_stmt.data.path.bind( Resolve_Use_GetBinding(span, crate, use_stmt.data.path) ); + use_stmt.data.path.bind( Resolve_Use_GetBinding(span, crate, use_stmt.data.path, parent_modules) ); // - If doing a glob, ensure the item type is valid if( use_stmt.name == "" ) @@ -92,11 +94,60 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path Resolve_Use_Mod(crate, i.data.as_Module(), path + i.name); } } + /* + unsigned int idx = 0; + for(auto& mp : mod.anon_mods()) + { + Resolve_Use_Mod(crate, *mp, path + FMT("#" << idx)); + idx ++; + } + */ + // TODO: Handle anon modules by iterating code (allowing correct item mappings) + + struct NV: + public AST::NodeVisitorDef + { + const AST::Crate& crate; + ::std::vector< const AST::Module* > parent_modules; + + NV(const AST::Crate& crate, const AST::Module& cur_module): + crate(crate), + parent_modules() + { + parent_modules.push_back( &cur_module ); + } + + void visit(AST::ExprNode_Block& node) override { + // TODO: Recurse into module, with a stack of immediate-scope modules for resolution. + if( node.m_local_mod ) { + Resolve_Use_Mod(this->crate, *node.m_local_mod, node.m_local_mod->path(), this->parent_modules); + + parent_modules.push_back(&*node.m_local_mod); + } + AST::NodeVisitorDef::visit(node); + if( node.m_local_mod ) { + parent_modules.pop_back(); + } + } + } expr_iter(crate, mod); + + for(auto& i : mod.items()) + { + TU_MATCH_DEF( AST::Item, (i.data), (e), + ( + ), + (Function, + if( e.code().is_valid() ) { + e.code().node().visit( expr_iter ); + } + ) + ) + } } -::AST::PathBinding Resolve_Use_GetBinding_Mod(const Span& span, const ::AST::Crate& crate, const ::AST::Module& mod, const ::std::string& des_item_name) +::AST::PathBinding Resolve_Use_GetBinding_Mod(const Span& span, const ::AST::Crate& crate, const ::AST::Module& mod, const ::std::string& des_item_name, slice< const ::AST::Module* > parent_modules) { - // HACK - Catch the possibiliy of a name clash (not sure if this is really an erro) + // HACK - Catch the possibiliy of a name clash (not sure if this is really an error) { bool found = false; for( const auto& item : mod.items() ) @@ -112,6 +163,17 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } } + if( des_item_name[0] == '#' ) { + unsigned int idx = 0; + if( ::std::sscanf(des_item_name.c_str(), "#%u", &idx) != 1 ) { + BUG(span, "Invalid anon path segment '" << des_item_name << "'"); + } + if( idx >= mod.anon_mods().size() ) { + BUG(span, "Invalid anon path segment '" << des_item_name << "'"); + } + return ::AST::PathBinding::make_Module({mod.anon_mods()[idx]}); + } + for( const auto& item : mod.items() ) { if( item.data.is_None() ) @@ -120,7 +182,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( item.name == des_item_name ) { TU_MATCH(::AST::Item, (item.data), (e), (None, - // IMPOSSIBLe - Handled above + // IMPOSSIBLE - Handled above ), (Crate, //return ::AST::PathBinding::make_Crate({&e}); @@ -162,7 +224,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( imp.data.path.binding().is_Unbound() ) { DEBUG(" > Needs resolve"); // TODO: Handle possibility of recursion - return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path)); + return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path), parent_modules); } else { return imp.data.path.binding().clone(); @@ -175,7 +237,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path if( binding->is_Unbound() ) { DEBUG("Temp resolving wildcard " << imp.data); // TODO: Handle possibility of recursion - binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path)); + binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path), parent_modules); binding = &binding_; } @@ -193,16 +255,22 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } } - ERROR(span, E0000, "Could not find node '" << des_item_name << "' in module " << mod.path()); + if( mod.path().nodes().back().name()[0] == '#' ) { + assert( parent_modules.size() > 0 ); + return Resolve_Use_GetBinding_Mod(span, crate, *parent_modules.back(), des_item_name, parent_modules.subslice(0, parent_modules.size()-1)); + } + else { + ERROR(span, E0000, "Could not find node '" << des_item_name << "' in module " << mod.path()); + } } -::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path) +::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, slice< const ::AST::Module* > parent_modules) { const AST::Module* mod = &crate.m_root_module; const auto& nodes = path.nodes(); for( unsigned int i = 0; i < nodes.size()-1; i ++ ) { - auto b = Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes[i].name()); + auto b = Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes[i].name(), parent_modules); TU_MATCH_DEF(::AST::PathBinding, (b), (e), ( ERROR(span, E0000, "Unexpected item type in import"); @@ -235,6 +303,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path ) } - return Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.back().name()); + return Resolve_Use_GetBinding_Mod(span, crate, *mod, nodes.back().name(), parent_modules); } |