diff options
author | John Hodge <tpg@mutabah.net> | 2017-07-06 22:46:08 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-07-06 22:46:08 +0800 |
commit | b9ae7fd9692e780958eca568514090ec44f2d0d5 (patch) | |
tree | 6b7fa5ffd3fe0e97808dc511546876536761aa05 /src/resolve/absolute.cpp | |
parent | bded1205ddf56332f5864f4a93d69b74a41fb38f (diff) | |
download | mrust-b9ae7fd9692e780958eca568514090ec44f2d0d5.tar.gz |
All - Some little tweaks for windows port
Diffstat (limited to 'src/resolve/absolute.cpp')
-rw-r--r-- | src/resolve/absolute.cpp | 805 |
1 files changed, 404 insertions, 401 deletions
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 1e197769..bbce7056 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -12,477 +12,480 @@ #include <main_bindings.hpp> #include <hir/hir.hpp> -struct GenericSlot +namespace { - enum class Level + struct GenericSlot { - Top, - Method, - } level; - unsigned short index; - - unsigned int to_binding() const { - if(level == Level::Method && index != 0xFFFF) { - return (unsigned int)index + 256; - } - else { - return (unsigned int)index; + enum class Level + { + Top, + Method, + } level; + unsigned short index; + + unsigned int to_binding() const { + if(level == Level::Method && index != 0xFFFF) { + return (unsigned int)index + 256; + } + else { + return (unsigned int)index; + } } - } -}; -template<typename Val> -struct Named -{ - ::std::string name; - Val value; -}; + }; + template<typename Val> + struct Named + { + ::std::string name; + Val value; + }; -struct Context -{ - TAGGED_UNION(Ent, Module, - (Module, struct { - const ::AST::Module* mod; - }), - (ConcreteSelf, const TypeRef* ), - (VarBlock, struct { - unsigned int level; - // "Map" of names to function-level variable slots - ::std::vector< ::std::pair<Ident, unsigned int> > variables; - }), - (Generic, struct { - // Map of names to slots - ::std::vector< Named< GenericSlot > > types; - ::std::vector< Named< GenericSlot > > constants; - ::std::vector< Named< GenericSlot > > lifetimes; - }) - ); - - const ::AST::Crate& m_crate; - const ::AST::Module& m_mod; - ::std::vector<Ent> m_name_context; - unsigned int m_var_count; - unsigned int m_block_level; - bool m_frozen_bind_set; - - Context(const ::AST::Crate& crate, const ::AST::Module& mod): - m_crate(crate), - m_mod(mod), - m_var_count(~0u), - m_block_level(0), - m_frozen_bind_set( false ) - {} - - void push(const ::AST::GenericParams& params, GenericSlot::Level level, bool has_self=false) { - auto e = Ent::make_Generic({}); - auto& data = e.as_Generic(); - - if( has_self ) { - //assert( level == GenericSlot::Level::Top ); - data.types.push_back( Named<GenericSlot> { "Self", GenericSlot { level, 0xFFFF } } ); - m_name_context.push_back( Ent::make_ConcreteSelf(nullptr) ); - } - if( params.ty_params().size() > 0 ) { - const auto& typs = params.ty_params(); - for(unsigned int i = 0; i < typs.size(); i ++ ) { - data.types.push_back( Named<GenericSlot> { typs[i].name(), GenericSlot { level, static_cast<unsigned short>(i) } } ); + struct Context + { + TAGGED_UNION(Ent, Module, + (Module, struct { + const ::AST::Module* mod; + }), + (ConcreteSelf, const TypeRef* ), + (VarBlock, struct { + unsigned int level; + // "Map" of names to function-level variable slots + ::std::vector< ::std::pair<Ident, unsigned int> > variables; + }), + (Generic, struct { + // Map of names to slots + ::std::vector< Named< GenericSlot > > types; + ::std::vector< Named< GenericSlot > > constants; + ::std::vector< Named< GenericSlot > > lifetimes; + }) + ); + + const ::AST::Crate& m_crate; + const ::AST::Module& m_mod; + ::std::vector<Ent> m_name_context; + unsigned int m_var_count; + unsigned int m_block_level; + bool m_frozen_bind_set; + + Context(const ::AST::Crate& crate, const ::AST::Module& mod): + m_crate(crate), + m_mod(mod), + m_var_count(~0u), + m_block_level(0), + m_frozen_bind_set( false ) + {} + + void push(const ::AST::GenericParams& params, GenericSlot::Level level, bool has_self=false) { + auto e = Ent::make_Generic({}); + auto& data = e.as_Generic(); + + if( has_self ) { + //assert( level == GenericSlot::Level::Top ); + data.types.push_back( Named<GenericSlot> { "Self", GenericSlot { level, 0xFFFF } } ); + m_name_context.push_back( Ent::make_ConcreteSelf(nullptr) ); } + if( params.ty_params().size() > 0 ) { + const auto& typs = params.ty_params(); + for(unsigned int i = 0; i < typs.size(); i ++ ) { + data.types.push_back( Named<GenericSlot> { typs[i].name(), GenericSlot { level, static_cast<unsigned short>(i) } } ); + } + } + if( params.lft_params().size() > 0 ) { + //TODO(Span(), "resolve/absolute.cpp - Context::push(GenericParams) - Lifetime params - " << params); + } + + m_name_context.push_back(mv$(e)); } - if( params.lft_params().size() > 0 ) { - //TODO(Span(), "resolve/absolute.cpp - Context::push(GenericParams) - Lifetime params - " << params); + void pop(const ::AST::GenericParams& , bool has_self=false) { + if( !m_name_context.back().is_Generic() ) + BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); + m_name_context.pop_back(); + if(has_self) { + if( !m_name_context.back().is_ConcreteSelf() ) + BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); + m_name_context.pop_back(); + } } - - m_name_context.push_back(mv$(e)); - } - void pop(const ::AST::GenericParams& , bool has_self=false) { - if( !m_name_context.back().is_Generic() ) - BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); - m_name_context.pop_back(); - if(has_self) { - if( !m_name_context.back().is_ConcreteSelf() ) + void push(const ::AST::Module& mod) { + m_name_context.push_back( Ent::make_Module({ &mod }) ); + } + void pop(const ::AST::Module& mod) { + if( !m_name_context.back().is_Module() ) BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); m_name_context.pop_back(); } - } - void push(const ::AST::Module& mod) { - m_name_context.push_back( Ent::make_Module({ &mod }) ); - } - void pop(const ::AST::Module& mod) { - if( !m_name_context.back().is_Module() ) - BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); - m_name_context.pop_back(); - } - class RootBlockScope { - friend struct Context; - Context& ctxt; - unsigned int old_varcount; - RootBlockScope(Context& ctxt, unsigned int val): - ctxt(ctxt), - old_varcount(ctxt.m_var_count) - { - ctxt.m_var_count = val; + class RootBlockScope { + friend struct Context; + Context& ctxt; + unsigned int old_varcount; + RootBlockScope(Context& ctxt, unsigned int val): + ctxt(ctxt), + old_varcount(ctxt.m_var_count) + { + ctxt.m_var_count = val; + } + public: + ~RootBlockScope() { + ctxt.m_var_count = old_varcount; + } + }; + RootBlockScope enter_rootblock() { + return RootBlockScope(*this, 0); } - public: - ~RootBlockScope() { - ctxt.m_var_count = old_varcount; + RootBlockScope clear_rootblock() { + return RootBlockScope(*this, ~0u); } - }; - RootBlockScope enter_rootblock() { - return RootBlockScope(*this, 0); - } - RootBlockScope clear_rootblock() { - return RootBlockScope(*this, ~0u); - } - void push_self(const TypeRef& tr) { - m_name_context.push_back( Ent::make_ConcreteSelf(&tr) ); - } - void pop_self(const TypeRef& tr) { - TU_IFLET(Ent, m_name_context.back(), ConcreteSelf, e, - m_name_context.pop_back(); - ) - else { - BUG(Span(), "resolve/absolute.cpp - Context::pop(TypeRef) - Mismatched pop"); + void push_self(const TypeRef& tr) { + m_name_context.push_back( Ent::make_ConcreteSelf(&tr) ); } - } - ::TypeRef get_self() const { - for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) - { - TU_MATCH_DEF(Ent, (*it), (e), - ( - ), - (ConcreteSelf, - if( e ) { - return e->clone(); - } - else { - return ::TypeRef(Span(), "Self", 0xFFFF); - } - ) + void pop_self(const TypeRef& tr) { + TU_IFLET(Ent, m_name_context.back(), ConcreteSelf, e, + m_name_context.pop_back(); ) + else { + BUG(Span(), "resolve/absolute.cpp - Context::pop(TypeRef) - Mismatched pop"); + } } + ::TypeRef get_self() const { + for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) + { + TU_MATCH_DEF(Ent, (*it), (e), + ( + ), + (ConcreteSelf, + if( e ) { + return e->clone(); + } + else { + return ::TypeRef(Span(), "Self", 0xFFFF); + } + ) + ) + } - TODO(Span(), "Error when get_self called with no self"); - } + TODO(Span(), "Error when get_self called with no self"); + } - void push_block() { - m_block_level += 1; - DEBUG("Push block to " << m_block_level); - } - unsigned int push_var(const Span& sp, const Ident& name) { - if( m_var_count == ~0u ) { - BUG(sp, "Assigning local when there's no variable context"); + void push_block() { + m_block_level += 1; + DEBUG("Push block to " << m_block_level); } - // TODO: Handle avoiding duplicate bindings in a pattern - if( m_frozen_bind_set ) - { - if( !m_name_context.back().is_VarBlock() ) { - BUG(sp, "resolve/absolute.cpp - Context::push_var - No block"); + unsigned int push_var(const Span& sp, const Ident& name) { + if( m_var_count == ~0u ) { + BUG(sp, "Assigning local when there's no variable context"); + } + // TODO: Handle avoiding duplicate bindings in a pattern + if( m_frozen_bind_set ) + { + if( !m_name_context.back().is_VarBlock() ) { + BUG(sp, "resolve/absolute.cpp - Context::push_var - No block"); + } + auto& vb = m_name_context.back().as_VarBlock(); + for( const auto& v : vb.variables ) + { + // TODO: Error when a binding is used twice or not at all + if( v.first == name ) { + return v.second; + } + } + ERROR(sp, E0000, "Mismatched bindings in pattern"); } - auto& vb = m_name_context.back().as_VarBlock(); - for( const auto& v : vb.variables ) + else { - // TODO: Error when a binding is used twice or not at all - if( v.first == name ) { - return v.second; + assert( m_block_level > 0 ); + if( !m_name_context.back().is_VarBlock() || m_name_context.back().as_VarBlock().level < m_block_level ) { + m_name_context.push_back( Ent::make_VarBlock({ m_block_level, {} }) ); } + DEBUG("New var @ " << m_block_level << ": #" << m_var_count << " " << name); + auto& vb = m_name_context.back().as_VarBlock(); + assert(vb.level == m_block_level); + vb.variables.push_back( ::std::make_pair(mv$(name), m_var_count) ); + m_var_count += 1; + assert( m_var_count >= vb.variables.size() ); + return m_var_count - 1; } - ERROR(sp, E0000, "Mismatched bindings in pattern"); } - else - { + void pop_block() { assert( m_block_level > 0 ); - if( !m_name_context.back().is_VarBlock() || m_name_context.back().as_VarBlock().level < m_block_level ) { - m_name_context.push_back( Ent::make_VarBlock({ m_block_level, {} }) ); + if( m_name_context.size() > 0 && m_name_context.back().is_VarBlock() && m_name_context.back().as_VarBlock().level == m_block_level ) { + DEBUG("Pop block from " << m_block_level << " with vars:" << FMT_CB(os, + for(const auto& v : m_name_context.back().as_VarBlock().variables) + os << " " << v.first << "#" << v.second; + )); + m_name_context.pop_back(); } - DEBUG("New var @ " << m_block_level << ": #" << m_var_count << " " << name); - auto& vb = m_name_context.back().as_VarBlock(); - assert(vb.level == m_block_level); - vb.variables.push_back( ::std::make_pair(mv$(name), m_var_count) ); - m_var_count += 1; - assert( m_var_count >= vb.variables.size() ); - return m_var_count - 1; - } - } - void pop_block() { - assert( m_block_level > 0 ); - if( m_name_context.size() > 0 && m_name_context.back().is_VarBlock() && m_name_context.back().as_VarBlock().level == m_block_level ) { - DEBUG("Pop block from " << m_block_level << " with vars:" << FMT_CB(os, - for(const auto& v : m_name_context.back().as_VarBlock().variables) - os << " " << v.first << "#" << v.second; - )); - m_name_context.pop_back(); - } - else { - DEBUG("Pop block from " << m_block_level << " - no vars"); - for(const auto& ent : ::reverse(m_name_context)) { - TU_IFLET(Ent, ent, VarBlock, e, - //DEBUG("Block @" << e.level << ": " << e.variables.size() << " vars"); - assert( e.level < m_block_level ); - ) + else { + DEBUG("Pop block from " << m_block_level << " - no vars"); + for(const auto& ent : ::reverse(m_name_context)) { + TU_IFLET(Ent, ent, VarBlock, e, + //DEBUG("Block @" << e.level << ": " << e.variables.size() << " vars"); + assert( e.level < m_block_level ); + ) + } } + m_block_level -= 1; } - m_block_level -= 1; - } - /// Indicate that a multiple-pattern binding is started - void start_patbind() { - assert( m_block_level > 0 ); - m_name_context.push_back( Ent::make_VarBlock({ m_block_level, {} }) ); - assert( m_frozen_bind_set == false ); - } - /// Freeze the set of pattern bindings - void freeze_patbind() { - m_frozen_bind_set = true; - } - /// End a multiple-pattern binding state (unfreeze really) - void end_patbind() { - m_frozen_bind_set = false; - } + /// Indicate that a multiple-pattern binding is started + void start_patbind() { + assert( m_block_level > 0 ); + m_name_context.push_back( Ent::make_VarBlock({ m_block_level, {} }) ); + assert( m_frozen_bind_set == false ); + } + /// Freeze the set of pattern bindings + void freeze_patbind() { + m_frozen_bind_set = true; + } + /// End a multiple-pattern binding state (unfreeze really) + void end_patbind() { + m_frozen_bind_set = false; + } - enum class LookupMode { - Namespace, - Type, - Constant, - Pattern, - Variable, - }; - static const char* lookup_mode_msg(LookupMode mode) { - switch(mode) - { - case LookupMode::Namespace: return "path component"; - case LookupMode::Type: return "type name"; - case LookupMode::Pattern: return "pattern name"; - case LookupMode::Constant: return "constant name"; - case LookupMode::Variable: return "variable name"; - } - return ""; - } - AST::Path lookup(const Span& sp, const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { - auto rv = this->lookup_opt(name, src_context, mode); - if( !rv.is_valid() ) { + enum class LookupMode { + Namespace, + Type, + Constant, + Pattern, + Variable, + }; + static const char* lookup_mode_msg(LookupMode mode) { 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 << "'"); - case LookupMode::Variable: ERROR(sp, E0000, "Couldn't find variable name '" << name << "'"); + case LookupMode::Namespace: return "path component"; + case LookupMode::Type: return "type name"; + case LookupMode::Pattern: return "pattern name"; + case LookupMode::Constant: return "constant name"; + case LookupMode::Variable: return "variable name"; } + return ""; } - return rv; - } - static bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, LookupMode mode, ::AST::Path& path) { - 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 == "IntoIterator" ) { - // DEBUG("lookup_in_mod(mod="<<mod.path()<<")"); - // for(const auto& v : mod.m_type_items) { - // 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 = ::AST::Path( v->second.path ); - return true; + AST::Path lookup(const Span& sp, const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { + auto rv = this->lookup_opt(name, src_context, mode); + 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 << "'"); + case LookupMode::Variable: ERROR(sp, E0000, "Couldn't find variable name '" << name << "'"); } } - break; - case LookupMode::Pattern: + return rv; + } + static bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, LookupMode mode, ::AST::Path& path) { + switch(mode) { - auto v = mod.m_type_items.find(name); - if( v != mod.m_type_items.end() ) { - const auto& b = v->second.path.binding(); - switch( b.tag() ) - { - case ::AST::PathBinding::TAG_Struct: + 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; - default: - break; } } - } - { - auto v = mod.m_value_items.find(name); - if( v != mod.m_value_items.end() ) { - const auto& b = v->second.path.binding(); - switch( b.tag() ) - { - case ::AST::PathBinding::TAG_EnumVar: - case ::AST::PathBinding::TAG_Static: + { + auto v = mod.m_type_items.find(name); + if( v != mod.m_type_items.end() ) { path = ::AST::Path( v->second.path ); return true; - default: - break; } } - } - 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; - } - AST::Path lookup_opt(const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { - DEBUG("name=" << name <<", src_context=" << src_context); - for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) - { - TU_MATCH(Ent, (*it), (e), - (Module, - DEBUG("- Module"); - ::AST::Path rv; - if( this->lookup_in_mod(*e.mod, name, mode, rv) ) { - return rv; - } - ), - (ConcreteSelf, - DEBUG("- ConcreteSelf"); - if( ( mode == LookupMode::Type || mode == LookupMode::Namespace ) && name == "Self" ) { - return ::AST::Path( ::AST::Path::TagUfcs(), e->clone(), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); - } - ), - (VarBlock, - DEBUG("- VarBlock"); - assert(e.level <= m_block_level); - if( mode != LookupMode::Variable ) { - // ignore + break; + + case LookupMode::Type: + //if( name == "IntoIterator" ) { + // DEBUG("lookup_in_mod(mod="<<mod.path()<<")"); + // for(const auto& v : mod.m_type_items) { + // 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 = ::AST::Path( v->second.path ); + return true; + } } - else { - for( auto it2 = e.variables.rbegin(); it2 != e.variables.rend(); ++ it2 ) - { - if( it2->first.name == name && it2->first.hygiene.is_visible(src_context) ) { - ::AST::Path rv(name); - rv.bind_variable( it2->second ); - return rv; + break; + case LookupMode::Pattern: + { + auto v = mod.m_type_items.find(name); + if( v != mod.m_type_items.end() ) { + const auto& b = v->second.path.binding(); + switch( b.tag() ) + { + case ::AST::PathBinding::TAG_Struct: + path = ::AST::Path( v->second.path ); + return true; + default: + break; } } } - ), - (Generic, - DEBUG("- Generic"); - if( mode == LookupMode::Type || mode == LookupMode::Namespace ) { - for( auto it2 = e.types.rbegin(); it2 != e.types.rend(); ++ it2 ) - { - if( it2->name == name ) { - ::AST::Path rv(name); - rv.bind_variable( it2->value.to_binding() ); - return rv; + { + auto v = mod.m_value_items.find(name); + if( v != mod.m_value_items.end() ) { + const auto& b = v->second.path.binding(); + switch( b.tag() ) + { + case ::AST::PathBinding::TAG_EnumVar: + case ::AST::PathBinding::TAG_Static: + path = ::AST::Path( v->second.path ); + return true; + default: + break; } } } - else { - // ignore. - // TODO: Integer generics + 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; } + AST::Path lookup_opt(const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const { + DEBUG("name=" << name <<", src_context=" << src_context); + for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) + { + TU_MATCH(Ent, (*it), (e), + (Module, + DEBUG("- Module"); + ::AST::Path rv; + if( this->lookup_in_mod(*e.mod, name, mode, rv) ) { + return rv; + } + ), + (ConcreteSelf, + DEBUG("- ConcreteSelf"); + if( ( mode == LookupMode::Type || mode == LookupMode::Namespace ) && name == "Self" ) { + return ::AST::Path( ::AST::Path::TagUfcs(), e->clone(), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); + } + ), + (VarBlock, + DEBUG("- VarBlock"); + assert(e.level <= m_block_level); + if( mode != LookupMode::Variable ) { + // ignore + } + else { + for( auto it2 = e.variables.rbegin(); it2 != e.variables.rend(); ++ it2 ) + { + if( it2->first.name == name && it2->first.hygiene.is_visible(src_context) ) { + ::AST::Path rv(name); + rv.bind_variable( it2->second ); + return rv; + } + } + } + ), + (Generic, + DEBUG("- Generic"); + if( mode == LookupMode::Type || mode == LookupMode::Namespace ) { + for( auto it2 = e.types.rbegin(); it2 != e.types.rend(); ++ it2 ) + { + if( it2->name == name ) { + ::AST::Path rv(name); + rv.bind_variable( it2->value.to_binding() ); + return rv; + } + } + } + else { + // ignore. + // TODO: Integer generics + } + ) + ) + } - // Top-level module - DEBUG("- Top module (" << m_mod.path() << ")"); - ::AST::Path rv; - if( this->lookup_in_mod(m_mod, name, mode, rv) ) { - return rv; - } + // Top-level module + DEBUG("- Top module (" << m_mod.path() << ")"); + ::AST::Path rv; + if( this->lookup_in_mod(m_mod, name, mode, rv) ) { + return rv; + } - DEBUG("- Primitives"); - switch(mode) - { - case LookupMode::Namespace: - case LookupMode::Type: { - // Look up primitive types - auto ct = coretype_fromstring(name); - if( ct != CORETYPE_INVAL ) + DEBUG("- Primitives"); + switch(mode) { - return ::AST::Path( ::AST::Path::TagUfcs(), TypeRef(Span("-",0,0,0,0), ct), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); + case LookupMode::Namespace: + case LookupMode::Type: { + // Look up primitive types + auto ct = coretype_fromstring(name); + if( ct != CORETYPE_INVAL ) + { + return ::AST::Path( ::AST::Path::TagUfcs(), TypeRef(Span("-",0,0,0,0), ct), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); + } + } break; + default: + break; } - } break; - default: - break; - } - return AST::Path(); - } + return AST::Path(); + } - unsigned int lookup_local(const Span& sp, const ::std::string name, LookupMode mode) { - for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) - { - TU_MATCH(Ent, (*it), (e), - (Module, - ), - (ConcreteSelf, - ), - (VarBlock, - if( mode == LookupMode::Variable ) { - for( auto it2 = e.variables.rbegin(); it2 != e.variables.rend(); ++ it2 ) - { - // TODO: Hyginic lookup? - if( it2->first.name == name ) { - return it2->second; + unsigned int lookup_local(const Span& sp, const ::std::string name, LookupMode mode) { + for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) + { + TU_MATCH(Ent, (*it), (e), + (Module, + ), + (ConcreteSelf, + ), + (VarBlock, + if( mode == LookupMode::Variable ) { + for( auto it2 = e.variables.rbegin(); it2 != e.variables.rend(); ++ it2 ) + { + // TODO: Hyginic lookup? + if( it2->first.name == name ) { + return it2->second; + } } } - } - ), - (Generic, - if( mode == LookupMode::Type ) { - for( auto it2 = e.types.rbegin(); it2 != e.types.rend(); ++ it2 ) - { - if( it2->name == name ) { - return it2->value.to_binding(); + ), + (Generic, + if( mode == LookupMode::Type ) { + for( auto it2 = e.types.rbegin(); it2 != e.types.rend(); ++ it2 ) + { + if( it2->name == name ) { + return it2->value.to_binding(); + } } } - } - else { - // ignore. - // TODO: Integer generics - } + else { + // ignore. + // TODO: Integer generics + } + ) ) - ) - } + } - ERROR(sp, E0000, "Unable to find local " << (mode == LookupMode::Variable ? "variable" : "type") << " '" << name << "'"); - } + ERROR(sp, E0000, "Unable to find local " << (mode == LookupMode::Variable ? "variable" : "type") << " '" << name << "'"); + } - /// Clones the context, including only the module-level items (i.e. just the Module entries) - Context clone_mod() const { - auto rv = Context(this->m_crate, this->m_mod); - for(const auto& v : m_name_context) { - TU_IFLET(Ent, v, Module, e, - rv.m_name_context.push_back( Ent::make_Module(e) ); - ) + /// Clones the context, including only the module-level items (i.e. just the Module entries) + Context clone_mod() const { + auto rv = Context(this->m_crate, this->m_mod); + for(const auto& v : m_name_context) { + TU_IFLET(Ent, v, Module, e, + rv.m_name_context.push_back( Ent::make_Module(e) ); + ) + } + return rv; } - return rv; - } -}; + }; +} // Namespace ::std::ostream& operator<<(::std::ostream& os, const Context::LookupMode& v) { switch(v) |