summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/crate.cpp2
-rw-r--r--src/expand/mod.cpp2
-rw-r--r--src/include/rustic.hpp21
-rw-r--r--src/resolve/index.cpp56
-rw-r--r--src/resolve/use.cpp94
5 files changed, 152 insertions, 23 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp
index 38bf92c3..43279c90 100644
--- a/src/ast/crate.cpp
+++ b/src/ast/crate.cpp
@@ -26,7 +26,7 @@ namespace {
namespace AST {
Crate::Crate():
- m_root_module(::AST::Path()),
+ m_root_module(::AST::Path("",{})),
m_load_std(LOAD_STD)
{
}
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index 416db81e..bbe4db85 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -629,6 +629,8 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo
i.data.attrs = mv$(attrs);
}
+ // IGNORE m_anon_modules, handled as part of expressions
+
DEBUG("Impls");
for( auto& impl : mod.impls() )
{
diff --git a/src/include/rustic.hpp b/src/include/rustic.hpp
index 15588565..3b4a0386 100644
--- a/src/include/rustic.hpp
+++ b/src/include/rustic.hpp
@@ -8,10 +8,22 @@ class slice
T* m_first;
unsigned int m_len;
public:
+ slice():
+ m_first(nullptr),
+ m_len(0)
+ {}
+ slice(const ::std::vector<T>& v):
+ m_first(&v[0]),
+ m_len(v.size())
+ {}
slice(::std::vector<T>& v):
m_first(&v[0]),
m_len(v.size())
{}
+ slice(T* ptr, unsigned int len):
+ m_first(ptr),
+ m_len(len)
+ {}
::std::vector<T> to_vec() const {
return ::std::vector<T>(begin(), end());
@@ -24,9 +36,18 @@ public:
assert(i < m_len);
return m_first[i];
}
+ slice<T> subslice(unsigned int ofs, unsigned int len) const {
+ assert(ofs < m_len);
+ assert(len <= m_len);
+ assert(ofs + len <= m_len);
+ return slice { m_first + ofs, len };
+ }
T* begin() const { return m_first; }
T* end() const { return m_first + m_len; }
+
+ T& front() const { return m_first[0]; }
+ T& back() const { return m_first[m_len-1]; }
};
template<typename T>
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);
}