summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-01 12:28:30 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-01 12:28:30 +0800
commitb613f53aecc651ca36b550345175554d2d2def8d (patch)
tree9fc61679df3d7e6031c34465804ce70d8b0f2ad0
parent19a8b93c162c5e93ea65e5b828652f0c1887cdce (diff)
downloadmrust-b613f53aecc651ca36b550345175554d2d2def8d.tar.gz
Resolve/absolute - Handle super paths, local variables
-rw-r--r--src/ast/path.hpp2
-rw-r--r--src/resolve/absolute.cpp251
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() );
)
)
}