diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-12 11:49:05 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-12 11:49:05 +0800 |
commit | 25fc71ff92e8fb940377b4f4a513d535e2eb040f (patch) | |
tree | 501c8b5a596689c0bd09d40e08a0cec3e5108dda /src | |
parent | 1c3f5cd57013c067cfea41f26c28f93b451b6b84 (diff) | |
download | mrust-25fc71ff92e8fb940377b4f4a513d535e2eb040f.tar.gz |
Resolve - Fix variable scoping
Diffstat (limited to 'src')
-rw-r--r-- | src/include/debug.hpp | 11 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 32 |
2 files changed, 35 insertions, 8 deletions
diff --git a/src/include/debug.hpp b/src/include/debug.hpp index 7e68bbfa..af8dcf10 100644 --- a/src/include/debug.hpp +++ b/src/include/debug.hpp @@ -49,6 +49,17 @@ public: TraceLog(const char* tag); ~TraceLog(); }; + +struct FmtLambda +{ + ::std::function<void(::std::ostream&)> m_cb; + friend ::std::ostream& operator<<(::std::ostream& os, const FmtLambda& x) { + x.m_cb(os); + return os; + } +}; +#define FMT_CB(os, ...) ::FmtLambda { [&](auto& os) { __VA_ARGS__ } } + #define TRACE_FUNCTION TraceLog _tf_(__func__) #define TRACE_FUNCTION_F(ss) TraceLog _tf_(__func__, FMT(ss)) #define TRACE_FUNCTION_FR(ss,ss2) TraceLog _tf_(__func__, FMT(ss), [&](::std::ostream&__os){ __os << ss2;}) diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 0fd1a8d7..62b528a4 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -165,6 +165,7 @@ struct Context void push_block() { m_block_level += 1; + DEBUG("Push block to " << m_block_level); } unsigned int push_var(const Span& sp, const ::std::string& name) { if( m_var_count == ~0u ) { @@ -189,20 +190,34 @@ struct Context else { assert( m_block_level > 0 ); - if( !m_name_context.back().is_VarBlock() ) { + 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, {} }) ); } - m_name_context.back().as_VarBlock().variables.push_back( Named<unsigned int> { name, m_var_count } ); + 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( Named<unsigned int> { name, m_var_count } ); m_var_count += 1; - assert( m_var_count >= m_name_context.back().as_VarBlock().variables.size() ); + assert( m_var_count >= vb.variables.size() ); return 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(); + if( 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.name << "#" << v.value; + )); + 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 ); + ) } } m_block_level -= 1; @@ -352,6 +367,7 @@ struct Context } ), (VarBlock, + assert(e.level <= m_block_level); if( mode != LookupMode::Variable ) { // ignore } @@ -757,7 +773,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: else { // Look up value auto p = context.lookup(sp, e.nodes[0].name(), mode); - DEBUG("Found path " << p << " for " << path); + //DEBUG("Found path " << p << " for " << path); if( p.is_absolute() ) { assert( !p.nodes().empty() ); p.nodes().back().args() = mv$(e.nodes.back().args()); @@ -1040,7 +1056,7 @@ void Resolve_Absolute_ExprNode(Context& context, ::AST::ExprNode& node) AST::NodeVisitorDef::visit(node); } void visit(AST::ExprNode_NamedValue& node) override { - DEBUG("ExprNode_NamedValue - " << node.m_path); + DEBUG("(" << node.get_pos() << ") ExprNode_NamedValue - " << node.m_path); Resolve_Absolute_Path(this->context, Span(node.get_pos()), Context::LookupMode::Variable, node.m_path); } void visit(AST::ExprNode_Cast& node) override { |