summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-12 11:49:05 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-12 11:49:05 +0800
commit25fc71ff92e8fb940377b4f4a513d535e2eb040f (patch)
tree501c8b5a596689c0bd09d40e08a0cec3e5108dda /src
parent1c3f5cd57013c067cfea41f26c28f93b451b6b84 (diff)
downloadmrust-25fc71ff92e8fb940377b4f4a513d535e2eb040f.tar.gz
Resolve - Fix variable scoping
Diffstat (limited to 'src')
-rw-r--r--src/include/debug.hpp11
-rw-r--r--src/resolve/absolute.cpp32
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 {