summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-06 15:12:00 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-06 15:12:00 +0800
commit1ac071bb74b47a0904e080f1343b31142da9da90 (patch)
tree0fc3b75aba1187b4c45c79153de2f3cf853a0ff1
parent3081e4762069a8ba401f77bee4951061b1e9589a (diff)
downloadmrust-1ac071bb74b47a0904e080f1343b31142da9da90.tar.gz
Resolve - Separate modules and types for slightly different lookup requirements
-rw-r--r--src/ast/ast.hpp10
-rw-r--r--src/main.cpp4
-rw-r--r--src/resolve/absolute.cpp78
-rw-r--r--src/resolve/index.cpp115
4 files changed, 146 insertions, 61 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 4ca16210..fc1a2f73 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -552,8 +552,14 @@ private:
public:
char m_index_populated = 0; // 0 = no, 1 = partial, 2 = complete
- ::std::unordered_map< ::std::string, ::std::pair<bool, PathBinding> > m_type_items;
- ::std::unordered_map< ::std::string, ::std::pair<bool, PathBinding> > m_value_items;
+ // TODO: Add "namespace" list (separate to types)
+ struct IndexEnt {
+ bool is_pub;
+ ::AST::Path path;
+ };
+ ::std::unordered_map< ::std::string, IndexEnt > m_namespace_items;
+ ::std::unordered_map< ::std::string, IndexEnt > m_type_items;
+ ::std::unordered_map< ::std::string, IndexEnt > m_value_items;
public:
Module() {}
diff --git a/src/main.cpp b/src/main.cpp
index 2030a663..74e5e7f1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -129,6 +129,10 @@ int main(int argc, char *argv[])
CompilePhaseV("Temp output - Resolved", [&]() {
Dump_Rust( FMT(params.outfile << "_1_res.rs").c_str(), crate );
});
+
+ CompilePhaseV("HIR Lower", [&]() {
+ //hir_crate = LowerHIR_FromAST(mv$( crate ));
+ });
// Replace type aliases (`type`) into the actual type
CompilePhaseV("Resolve Type Aliases", [&]() {
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index b3722f29..2985419a 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -165,12 +165,15 @@ struct Context
enum class LookupMode {
- //Namespace,
+ Namespace,
Type,
Constant,
Pattern,
Variable,
};
+ AST::Path lookup_mod(const Span& sp, const ::std::string& name) const {
+ return this->lookup(sp, name, LookupMode::Namespace);
+ }
AST::Path lookup_type(const Span& sp, const ::std::string& name) const {
return this->lookup(sp, name, LookupMode::Type);
}
@@ -185,6 +188,7 @@ struct Context
if( !rv.is_valid() ) {
switch(mode)
{
+ case LookupMode::Namespace: ERROR(sp, E0000, "Couldn't find path component '" << name << "'");
case LookupMode::Type: ERROR(sp, E0000, "Couldn't find type name '" << name << "'");
case LookupMode::Pattern: ERROR(sp, E0000, "Couldn't find pattern name '" << name << "'");
case LookupMode::Constant: ERROR(sp, E0000, "Couldn't find constant name '" << name << "'");
@@ -194,29 +198,49 @@ struct Context
return rv;
}
bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, LookupMode mode, ::AST::Path& path) const {
- // TODO: m_type_items/m_value_items should store the path
- if( mode == LookupMode::Type ) {
+ switch(mode)
+ {
+ case LookupMode::Namespace:
+ {
+ auto v = mod.m_namespace_items.find(name);
+ if( v != mod.m_namespace_items.end() ) {
+ path = ::AST::Path( v->second.path );
+ return true;
+ }
+ }
+ {
+ auto v = mod.m_type_items.find(name);
+ if( v != mod.m_type_items.end() ) {
+ path = ::AST::Path( v->second.path );
+ return true;
+ }
+ }
+ break;
+
+ case LookupMode::Type:
//if( name == "SizeHint" ) {
// DEBUG("lookup_in_mod(mod="<<mod.path()<<")");
// for(const auto& v : mod.m_type_items) {
- // DEBUG("- " << v.first << " = " << (v.second.first ? "pub " : "") << v.second.second);
+ // DEBUG("- " << v.first << " = " << (v.second.is_pub ? "pub " : "") << v.second.path);
// }
//}
- auto v = mod.m_type_items.find(name);
- if( v != mod.m_type_items.end() ) {
- path = mod.path() + name;
- return true;
+ {
+ auto v = mod.m_type_items.find(name);
+ if( v != mod.m_type_items.end() ) {
+ path = ::AST::Path( v->second.path );
+ return true;
+ }
}
- }
- else if( mode == LookupMode::Pattern ) {
+ break;
+ case LookupMode::Pattern:
{
auto v = mod.m_type_items.find(name);
if( v != mod.m_type_items.end() ) {
- const auto& b = v->second.second;
+ const auto& b = v->second.path.binding();
switch( b.tag() )
{
case ::AST::PathBinding::TAG_Struct:
- path = mod.path() + name;
+ path = ::AST::Path( v->second.path );
return true;
default:
break;
@@ -226,25 +250,29 @@ struct Context
{
auto v = mod.m_value_items.find(name);
if( v != mod.m_value_items.end() ) {
- const auto& b = v->second.second;
+ const auto& b = v->second.path.binding();
switch( b.tag() )
{
case ::AST::PathBinding::TAG_EnumVar:
case ::AST::PathBinding::TAG_Static:
- path = mod.path() + name;
+ path = ::AST::Path( v->second.path );
return true;
default:
break;
}
}
}
- }
- else {
- auto v = mod.m_value_items.find(name);
- if( v != mod.m_value_items.end() ) {
- path = mod.path() + name;
- return true;
+ break;
+ case LookupMode::Constant:
+ case LookupMode::Variable:
+ {
+ auto v = mod.m_value_items.find(name);
+ if( v != mod.m_value_items.end() ) {
+ path = ::AST::Path( v->second.path );
+ return true;
+ }
}
+ break;
}
return false;
}
@@ -259,7 +287,7 @@ struct Context
}
),
(ConcreteSelf,
- if( mode == LookupMode::Type && name == "Self" ) {
+ if( ( mode == LookupMode::Type || mode == LookupMode::Namespace ) && name == "Self" ) {
return ::AST::Path( ::AST::Path::TagUfcs(), *e, ::std::vector< ::AST::PathNode>() );
}
),
@@ -279,7 +307,7 @@ struct Context
}
),
(Generic,
- if( mode == LookupMode::Type ) {
+ if( mode == LookupMode::Type || mode == LookupMode::Namespace ) {
for( auto it2 = e.types.rbegin(); it2 != e.types.rend(); ++ it2 )
{
if( it2->name == name ) {
@@ -328,6 +356,7 @@ struct Context
::std::ostream& operator<<(::std::ostream& os, const Context::LookupMode& v) {
switch(v)
{
+ case Context::LookupMode::Namespace:os << "Namespace"; break;
case Context::LookupMode::Type: os << "Type"; break;
case Context::LookupMode::Pattern: os << "Pattern"; break;
case Context::LookupMode::Constant: os << "Constant"; break;
@@ -372,9 +401,10 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context::
DEBUG("- Relative");
if(e.nodes.size() == 0)
BUG(sp, "Resolve_Absolute_Path - Relative path with no nodes");
- if(e.nodes.size() > 1 || mode == Context::LookupMode::Type) {
+ if(e.nodes.size() > 1)
+ {
// Look up type
- auto p = context.lookup_type(sp, e.nodes[0].name());
+ auto p = context.lookup(sp, e.nodes[0].name(), Context::LookupMode::Namespace);
DEBUG("Found type/mod - " << p);
if( e.nodes.size() > 1 )
diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp
index e905de26..b98c3b8e 100644
--- a/src/resolve/index.cpp
+++ b/src/resolve/index.cpp
@@ -5,16 +5,48 @@
#include <ast/crate.hpp>
#include <main_bindings.hpp>
-void _add_item(AST::Module& mod, bool is_type, const ::std::string& name, bool is_pub, ::AST::PathBinding ir, bool error_on_collision)
+enum class IndexName
{
- DEBUG("Add " << (is_type ? "type" : "value") << " item '" << name << "': " << ir);
- auto& list = (is_type ? mod.m_type_items : mod.m_value_items);
+ Namespace,
+ Type,
+ Value,
+};
+::std::ostream& operator<<(::std::ostream& os, const IndexName& loc)
+{
+ switch(loc)
+ {
+ case IndexName::Namespace:
+ return os << "namespace";
+ case IndexName::Type:
+ return os << "type";
+ case IndexName::Value:
+ return os << "value";
+ }
+ throw "";
+}
+::std::unordered_map< ::std::string, ::AST::Module::IndexEnt >& get_mod_index(::AST::Module& mod, IndexName location) {
+ switch(location)
+ {
+ case IndexName::Namespace:
+ return mod.m_namespace_items;
+ case IndexName::Type:
+ return mod.m_type_items;
+ case IndexName::Value:
+ return mod.m_value_items;
+ }
+ throw "";
+}
+
+void _add_item(AST::Module& mod, IndexName location, const ::std::string& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true)
+{
+ DEBUG("Add " << location << " item '" << name << "': " << ir);
+ auto& list = get_mod_index(mod, location);
- if( false == list.insert( ::std::make_pair(name, ::std::make_pair(is_pub, mv$(ir))) ).second )
+ if( false == list.insert(::std::make_pair(name, ::AST::Module::IndexEnt { is_pub, mv$(ir) } )).second )
{
if( error_on_collision )
{
- ERROR(Span(), E0000, "Duplicate definition of name '" << name << "' in " << (is_type ? "type" : "value") << " scope (" << mod.path() << ")");
+ ERROR(Span(), E0000, "Duplicate definition of name '" << name << "' in " << location << " scope (" << mod.path() << ")");
}
else
{
@@ -22,13 +54,14 @@ void _add_item(AST::Module& mod, bool is_type, const ::std::string& name, bool i
}
}
}
-void _add_item_type(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir, bool error_on_collision=true)
+void _add_item_type(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true)
{
- _add_item(mod, true, name, is_pub, mv$(ir), error_on_collision);
+ _add_item(mod, IndexName::Namespace, name, is_pub, ::AST::Path(ir), error_on_collision);
+ _add_item(mod, IndexName::Type, name, is_pub, mv$(ir), error_on_collision);
}
-void _add_item_value(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir, bool error_on_collision=true)
+void _add_item_value(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::Path ir, bool error_on_collision=true)
{
- _add_item(mod, false, name, is_pub, mv$(ir), error_on_collision);
+ _add_item(mod, IndexName::Value, name, is_pub, mv$(ir), error_on_collision);
}
void Resolve_Index_Module_Base(AST::Module& mod)
@@ -36,40 +69,50 @@ void Resolve_Index_Module_Base(AST::Module& mod)
TRACE_FUNCTION_F("mod = " << mod.path());
for( const auto& i : mod.items() )
{
+ ::AST::Path p = mod.path() + i.name;
+
TU_MATCH(AST::Item, (i.data), (e),
(None,
),
// - Types/modules only
(Module,
- _add_item_type(mod, i.name, i.is_pub, ::AST::PathBinding::make_Module({&e}));
+ p.bind( ::AST::PathBinding::make_Module({&e}) );
+ _add_item(mod, IndexName::Namespace, i.name, i.is_pub, mv$(p));
),
(Crate,
TODO(Span(), "Crate in Resolve_Index_Module");
- //_add_item_type(mod, i.name, i.is_pub, ::AST::PathBinding::make_Crate(e));
+ //p.bind( ::AST::PathBinding::make_Crate(e) );
+ //_add_item(mod, IndexName::Namespace, i.name, i.is_pub, mv$(p));
),
(Enum,
- _add_item_type(mod, i.name, i.is_pub, ::AST::PathBinding::make_Enum({&e}));
+ p.bind( ::AST::PathBinding::make_Enum({&e}) );
+ _add_item_type(mod, i.name, i.is_pub, mv$(p));
),
(Trait,
- _add_item_type(mod, i.name, i.is_pub, ::AST::PathBinding::make_Trait({&e}));
+ p.bind( ::AST::PathBinding::make_Trait({&e}) );
+ _add_item_type(mod, i.name, i.is_pub, mv$(p));
),
(Type,
- _add_item_type(mod, i.name, i.is_pub, ::AST::PathBinding::make_TypeAlias({&e}));
+ p.bind( ::AST::PathBinding::make_TypeAlias({&e}) );
+ _add_item_type(mod, i.name, i.is_pub, mv$(p));
),
// - Mixed
(Struct,
- _add_item_type(mod, i.name, i.is_pub, ::AST::PathBinding::make_Struct({&e}));
- // - If the struct is a tuple-like struct, it presents in the value namespace
+ p.bind( ::AST::PathBinding::make_Struct({&e}) );
+ // - If the struct is a tuple-like struct (or unit-like), it presents in the value namespace
if( e.m_data.is_Tuple() ) {
- _add_item_value(mod, i.name, i.is_pub, ::AST::PathBinding::make_Struct({&e}));
+ _add_item_value(mod, i.name, i.is_pub, p);
}
+ _add_item_type(mod, i.name, i.is_pub, mv$(p));
),
// - Values only
(Function,
- _add_item_value(mod, i.name, i.is_pub, ::AST::PathBinding::make_Function({&e}));
+ p.bind( ::AST::PathBinding::make_Function({&e}) );
+ _add_item_value(mod, i.name, i.is_pub, mv$(p));
),
(Static,
- _add_item_value(mod, i.name, i.is_pub, ::AST::PathBinding::make_Static({&e}));
+ p.bind( ::AST::PathBinding::make_Static({&e}) );
+ _add_item_value(mod, i.name, i.is_pub, mv$(p));
)
)
}
@@ -99,22 +142,22 @@ void Resolve_Index_Module_Base(AST::Module& mod)
BUG(sp, "Import was bound to struct method");
),
- (Module, _add_item_type(mod, i.name, i.is_pub, b.clone()); ),
- //(Crate, _add_item_type(mod, i.name, i.is_pub, b.clone()); ),
- (Enum, _add_item_type(mod, i.name, i.is_pub, b.clone()); ),
- (Trait, _add_item_type(mod, i.name, i.is_pub, b.clone()); ),
- (TypeAlias, _add_item_type(mod, i.name, i.is_pub, b.clone()); ),
+ (Module, _add_item(mod, IndexName::Namespace, i.name, i.is_pub, i.data.path); ),
+ //(Crate, _add_item_type(mod, IndexName::Namespace, i.name, i.is_pub, i.data.path); ),
+ (Enum, _add_item_type(mod, i.name, i.is_pub, i.data.path); ),
+ (Trait, _add_item_type(mod, i.name, i.is_pub, i.data.path); ),
+ (TypeAlias, _add_item_type(mod, i.name, i.is_pub, i.data.path); ),
(Struct,
- _add_item_type(mod, i.name, i.is_pub, b.clone());
+ _add_item_type(mod, i.name, i.is_pub, i.data.path);
// - If the struct is a tuple-like struct, it presents in the value namespace
if( e.struct_->m_data.is_Tuple() ) {
- _add_item_value(mod, i.name, i.is_pub, b.clone());
+ _add_item_value(mod, i.name, i.is_pub, i.data.path);
}
),
- (Static , _add_item_value(mod, i.name, i.is_pub, b.clone()); ),
- (Function, _add_item_value(mod, i.name, i.is_pub, b.clone()); ),
- (EnumVar , _add_item_value(mod, i.name, i.is_pub, b.clone()); )
+ (Static , _add_item_value(mod, i.name, i.is_pub, i.data.path); ),
+ (Function, _add_item_value(mod, i.name, i.is_pub, i.data.path); ),
+ (EnumVar , _add_item_value(mod, i.name, i.is_pub, i.data.path); )
)
}
else
@@ -187,24 +230,26 @@ void Resolve_Index_Module_Wildcard(AST::Module& mod, bool handle_pub)
//Resolve_Index_Module( *e.module_ );
}
for(const auto& vi : e.module_->m_type_items) {
- if( vi.second.first ) {
- _add_item_type( mod, vi.first, i.is_pub, vi.second.second.clone(), false );
+ if( vi.second.is_pub ) {
+ _add_item_type( mod, vi.first, i.is_pub, vi.second.path, false );
}
}
for(const auto& vi : e.module_->m_value_items) {
- if( vi.second.first ) {
- _add_item_value( mod, vi.first, i.is_pub, vi.second.second.clone(), false );
+ if( vi.second.is_pub ) {
+ _add_item_value( mod, vi.first, i.is_pub, vi.second.path, false );
}
}
),
(Enum,
unsigned int idx = 0;
for( const auto& ev : e.enum_->variants() ) {
+ ::AST::Path p = mod.path() + ev.m_name;
+ p.bind( ::AST::PathBinding::make_EnumVar({e.enum_, idx}) );
if( ev.m_data.is_Struct() ) {
- _add_item_type ( mod, ev.m_name, i.is_pub, ::AST::PathBinding::make_EnumVar({e.enum_, idx}), false );
+ _add_item_type ( mod, ev.m_name, i.is_pub, mv$(p), false );
}
else {
- _add_item_value( mod, ev.m_name, i.is_pub, ::AST::PathBinding::make_EnumVar({e.enum_, idx}), false );
+ _add_item_value( mod, ev.m_name, i.is_pub, mv$(p), false );
}
idx += 1;