diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-01 12:28:30 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-01 12:28:30 +0800 |
commit | b613f53aecc651ca36b550345175554d2d2def8d (patch) | |
tree | 9fc61679df3d7e6031c34465804ce70d8b0f2ad0 | |
parent | 19a8b93c162c5e93ea65e5b828652f0c1887cdce (diff) | |
download | mrust-b613f53aecc651ca36b550345175554d2d2def8d.tar.gz |
Resolve/absolute - Handle super paths, local variables
-rw-r--r-- | src/ast/path.hpp | 2 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 251 |
2 files changed, 220 insertions, 33 deletions
diff --git a/src/ast/path.hpp b/src/ast/path.hpp index bf0ff59a..3b2b9969 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -120,7 +120,7 @@ public: ::std::vector<PathNode> nodes; } ), (Super, struct { // Parent-relative - unsigned int count; + unsigned int count; // Number of `super` keywords, must be >= 1 ::std::vector<PathNode> nodes; } ), (Absolute, struct { // Absolute diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index fac61978..de555c37 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -14,8 +14,8 @@ struct GenericSlot { enum class Level { - Impl, - Function, + Top, + Method, } level; unsigned short index; }; @@ -33,6 +33,7 @@ struct Context const ::AST::Module* mod; }), (VarBlock, struct { + unsigned int level; // "Map" of names to function-level variable slots ::std::vector< Named< unsigned int > > variables; }), @@ -47,12 +48,87 @@ struct Context 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; - Context(const ::AST::Crate& crate, const::AST::Module& mod): + Context(const ::AST::Crate& crate, const ::AST::Module& mod): m_crate(crate), - m_mod(mod) + m_mod(mod), + m_var_count(0), + m_block_level(0) {} + void push(const ::AST::GenericParams& params, GenericSlot::Level level) { + auto e = Ent::make_Generic({}); + auto& data = e.as_Generic(); + + 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) - " << params); + } + + m_name_context.push_back(mv$(e)); + } + void pop(const ::AST::GenericParams& ) { + if( !m_name_context.back().is_Generic() ) + 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(); + } + + void push_block() { + m_block_level += 1; + } + void push_var(const ::std::string& name) { + assert( m_block_level > 0 ); + if( !m_name_context.back().is_VarBlock() ) { + m_name_context.push_back( Ent::make_VarBlock({ m_block_level, {} }) ); + } + m_name_context.back().as_VarBlock().variables.push_back( Named<unsigned int> { name, m_var_count } ); + m_var_count += 1; + } + void pop_block() { + assert( m_block_level > 0 ); + if( m_name_context.back().is_VarBlock() ) { + if( m_name_context.back().as_VarBlock().level == m_block_level ) { + m_name_context.pop_back(); + } + } + m_block_level -= 1; + } + + + bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, bool is_type, ::AST::Path& path) const { + // TODO: m_type_items/m_value_items should store the path + if( is_type ) { + auto v = mod.m_type_items.find(name); + if( v != mod.m_type_items.end() ) { + path = mod.path() + name; + return true; + } + } + else { + auto v = mod.m_value_items.find(name); + if( v != mod.m_value_items.end() ) { + path = mod.path() + name; + return true; + } + } + return false; + } + AST::Path lookup_type(const Span& sp, const ::std::string& name) const { return this->lookup(sp, name, true); } @@ -64,18 +140,9 @@ struct Context { TU_MATCH(Ent, (*it), (e), (Module, - // TODO: m_type_items/m_value_items should store the path - if( is_type ) { - auto v = e.mod->m_type_items.find(name); - if( v != e.mod->m_type_items.end() ) { - return e.mod->path() + name; - } - } - else { - auto v = e.mod->m_value_items.find(name); - if( v != e.mod->m_value_items.end() ) { - return e.mod->path() + name; - } + ::AST::Path rv; + if( this->lookup_in_mod(*e.mod, name, is_type, rv) ) { + return rv; } ), (VarBlock, @@ -98,17 +165,9 @@ struct Context } // Top-level module - if( is_type ) { - auto v = m_mod.m_type_items.find(name); - if( v != m_mod.m_type_items.end() ) { - return m_mod.path() + name; - } - } - else { - auto v = m_mod.m_value_items.find(name); - if( v != m_mod.m_value_items.end() ) { - return m_mod.path() + name; - } + ::AST::Path rv; + if( this->lookup_in_mod(m_mod, name, is_type, rv) ) { + return rv; } ERROR(sp, E0000, "Couldn't find name '" << name << "'"); @@ -121,6 +180,7 @@ void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, void Resolve_Absolute_Type(const Context& context, TypeRef& type); void Resolve_Absolute_Expr(const Context& context, ::AST::Expr& expr); void Resolve_Absolute_Expr(const Context& context, ::AST::ExprNode& node); +void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pattern& pat); void Resolve_Absolute_Mod(const ::AST::Crate& crate, ::AST::Module& mod); @@ -153,7 +213,23 @@ void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, TODO(sp, "Resolve_Absolute_Path - Self-relative paths - " << path); ), (Super, - TODO(sp, "Resolve_Absolute_Path - Super-relative paths - " << path); + // - Determine how many components of the `self` path to use + const auto& mp_nodes = context.m_mod.path().nodes(); + assert( e.count >= 1 ); + unsigned int start_len = e.count > mp_nodes.size() ? 0 : mp_nodes.size() - e.count; + + // - Create a new path + ::AST::Path np("", {}); + auto& np_nodes = np.nodes(); + np_nodes.reserve( start_len + e.nodes.size() ); + for(unsigned int i = 0; i < start_len; i ++ ) + np_nodes.push_back( mp_nodes[i] ); + for(auto& en : e.nodes) + np_nodes.push_back( mv$(en) ); + + // TODO: Resolve to the actual item? + + path = mv$(np); ), (Absolute, // Nothing to do (TODO: Bind?) @@ -267,38 +343,149 @@ void Resolve_Absolute_Expr(const Context& context, ::AST::ExprNode& node) node.visit( expr_iter ); } +void Resolve_Absolute_Generic(const Context& context, ::AST::GenericParams& params) +{ + for( auto& bound : params.bounds() ) + { + TODO(Span(), "Resolve_Absolute_Generic - " << bound); + } +} + +void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pattern& pat) +{ + if( pat.binding() != "" ) { + if( !pat.data().is_Any() && ! allow_refutable ) + TODO(Span(), "Resolve_Absolute_Pattern - Encountered bound destructuring pattern"); + context.push_var( pat.binding() ); + } + + TU_MATCH( ::AST::Pattern::Data, (pat.data()), (e), + (MaybeBind, + BUG(Span(), "Resolve_Absolute_Pattern - Encountered MaybeBind"); + ), + (Macro, + BUG(Span(), "Resolve_Absolute_Pattern - Encountered Macro"); + ), + (Any, + // Ignore '_' + ), + (Box, + Resolve_Absolute_Pattern(context, allow_refutable, *e.sub); + ), + (Ref, + Resolve_Absolute_Pattern(context, allow_refutable, *e.sub); + ), + (Value, + if( ! allow_refutable ) + BUG(Span(), "Resolve_Absolute_Pattern - Enountered refutable pattern where only irrefutable allowed"); + // TODO: Value patterns should be resolved with a different context (disallowing locals) + Resolve_Absolute_Expr(context, *e.start); + if( e.end ) + Resolve_Absolute_Expr(context, *e.end); + ), + (Tuple, + for(auto& sp : e.sub_patterns) + Resolve_Absolute_Pattern(context, allow_refutable, sp); + ), + (StructTuple, + Resolve_Absolute_Path(context, Span(), true, e.path); + for(auto& sp : e.sub_patterns) + Resolve_Absolute_Pattern(context, allow_refutable, sp); + ), + (Struct, + Resolve_Absolute_Path(context, Span(), true, e.path); + for(auto& sp : e.sub_patterns) + Resolve_Absolute_Pattern(context, allow_refutable, sp.second); + ), + (Slice, + if( !allow_refutable ) + BUG(Span(), "Resolve_Absolute_Pattern - Enountered refutable pattern where only irrefutable allowed"); + for(auto& sp : e.leading) + Resolve_Absolute_Pattern(context, allow_refutable, sp); + if( e.extra_bind != "" && e.extra_bind != "_" ) { + context.push_var( e.extra_bind ); + } + for(auto& sp : e.trailing) + Resolve_Absolute_Pattern(context, allow_refutable, sp); + ) + ) +} + void Resolve_Absolute_Mod(const ::AST::Crate& crate, ::AST::Module& mod) { TRACE_FUNCTION_F("(mod="<<mod.path()<<")"); for( auto& i : mod.items() ) { + Context item_context { crate, mod }; + TU_MATCH(AST::Item, (i.data), (e), (None, ), (Module, + DEBUG("Module - " << i.name); Resolve_Absolute_Mod(crate, e); ), (Crate, // - Nothing ), (Enum, + DEBUG("Enum - " << i.name); + item_context.push( e.params(), GenericSlot::Level::Top ); + Resolve_Absolute_Generic(item_context, e.params()); TODO(Span(), "Resolve_Absolute_Mod - Enum"); + item_context.pop( e.params() ); ), (Trait, + DEBUG("Trait - " << i.name); TODO(Span(), "Resolve_Absolute_Mod - Trait"); ), (Type, + DEBUG("Type - " << i.name); TODO(Span(), "Resolve_Absolute_Mod - Type"); ), (Struct, - TODO(Span(), "Resolve_Absolute_Mod - Struct"); + DEBUG("Struct - " << i.name); + item_context.push( e.params(), GenericSlot::Level::Top ); + Resolve_Absolute_Generic(item_context, e.params()); + + TU_MATCH(::AST::StructData, (e.m_data), (s), + (Tuple, + for(auto& field : s.ents) { + Resolve_Absolute_Type(item_context, field.m_type); + } + ), + (Struct, + for(auto& field : s.ents) { + Resolve_Absolute_Type(item_context, field.m_type); + } + ) + ) + + item_context.pop( e.params() ); ), (Function, - TODO(Span(), "Resolve_Absolute_Mod - Function"); + DEBUG("Function - " << i.name); + item_context.push( e.params(), GenericSlot::Level::Top ); + + Resolve_Absolute_Type( item_context, e.rettype() ); + for(auto& arg : e.args()) + Resolve_Absolute_Type( item_context, arg.second ); + + item_context.push_block(); + for(auto& arg : e.args()) { + Resolve_Absolute_Pattern( item_context, false, arg.first ); + } + + Resolve_Absolute_Expr( item_context, e.code() ); + + item_context.pop_block(); + + item_context.pop( e.params() ); ), (Static, - Resolve_Absolute_Type( Context(crate, mod), e.type() ); - Resolve_Absolute_Expr( Context(crate, mod), e.value() ); + DEBUG("Static - " << i.name); + Resolve_Absolute_Type( item_context, e.type() ); + Resolve_Absolute_Expr( item_context, e.value() ); ) ) } |