diff options
author | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-01 13:51:57 +0800 |
---|---|---|
committer | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-01 13:51:57 +0800 |
commit | d0461823a2359e0eb052dd10813bc6a3d66f7c74 (patch) | |
tree | 7173e4f9c0c2acc98db0d29d5bc10822a15d9237 /src/convert/resolve.cpp | |
parent | 90d17906a39d521e36ff9e4f6089a1fb67a0aab7 (diff) | |
download | mrust-d0461823a2359e0eb052dd10813bc6a3d66f7c74.tar.gz |
Name resolve framework coming along
Diffstat (limited to 'src/convert/resolve.cpp')
-rw-r--r-- | src/convert/resolve.cpp | 107 |
1 files changed, 95 insertions, 12 deletions
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index edc649cc..504fec93 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -8,13 +8,30 @@ class CPathResolver {
const AST::Crate& m_crate;
const AST::Module& m_module;
+ ::std::vector< ::std::string > m_locals;
+ // TODO: Maintain a stack of variable scopes
public:
CPathResolver(const AST::Crate& crate, const AST::Module& mod);
-
- void resolve_type(TypeRef& type);
+
+ void resolve_path(AST::Path& path, bool allow_variables) const;
+ void resolve_type(TypeRef& type) const;
void handle_function(AST::Function& fcn);
+ void handle_pattern(AST::Pattern& pat);
+
+ void push_scope() {
+ m_locals.push_back( ::std::string() );
+ }
+ void pop_scope() {
+ for( auto it = m_locals.end(); --it != m_locals.begin(); ) {
+ if( *it == "" ) {
+ m_locals.erase(it, m_locals.end());
+ return ;
+ }
+ }
+ m_locals.clear();
+ }
};
// Path resolution checking
@@ -23,16 +40,28 @@ void ResolvePaths(AST::Crate& crate); class CResolvePaths_NodeVisitor:
public AST::NodeVisitor
{
- const CPathResolver& m_res;
+ CPathResolver& m_res;
public:
- CResolvePaths_NodeVisitor(const CPathResolver& res):
+ CResolvePaths_NodeVisitor(CPathResolver& res):
m_res(res)
{
}
void visit(AST::ExprNode_NamedValue& node) {
- // TODO: Convert into a real absolute path
- throw ParseError::Todo("CResolvePaths_NodeVisitor::visit(TagNamedValue)");
+ m_res.resolve_path(node.m_path, true);
+ }
+
+ void visit(AST::ExprNode_Match& node) {
+
+ AST::NodeVisitor::visit(node.m_val);
+
+ for( auto& arm : node.m_arms )
+ {
+ m_res.push_scope();
+ m_res.handle_pattern(arm.first);
+ AST::NodeVisitor::visit(arm.second);
+ m_res.pop_scope();
+ }
}
};
@@ -42,24 +71,78 @@ CPathResolver::CPathResolver(const AST::Crate& crate, const AST::Module& mod): {
}
-void CPathResolver::resolve_type(TypeRef& type)
+void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
+{
+ // Handle generic components of the path
+ for( auto& ent : path.nodes() )
+ {
+ for( auto& arg : ent.args() )
+ {
+ resolve_type(arg);
+ }
+ }
+
+ // Convert to absolute
+ if( !path.is_relative() )
+ {
+ // Already absolute, our job is done
+ }
+ else
+ {
+ if( allow_variables && path.size() == 1 && path[0].args().size() == 0 )
+ {
+ // One non-generic component, look in the current function for a variable
+ const ::std::string& var = path[0].name();
+ DEBUG("varname = " << var);
+ auto varslot = m_locals.end();
+ for(auto slot = m_locals.begin(); slot != m_locals.end(); ++slot)
+ {
+ if( *slot == var ) {
+ varslot = slot;
+ }
+ }
+
+ if( varslot != m_locals.end() )
+ {
+ DEBUG("Located slot");
+ path = AST::Path(AST::Path::TagLocal(), var);
+ return ;
+ }
+ }
+ // Search relative to current module
+ throw ParseError::Todo("CPathResolver::resolve_path()");
+ }
+}
+
+void CPathResolver::resolve_type(TypeRef& type) const
{
// TODO: Convert type into absolute
- throw ParseError::Todo("ResolvePaths_Type");
+ throw ParseError::Todo("CPathResolver::resolve_type()");
+}
+
+void CPathResolver::handle_pattern(AST::Pattern& pat)
+{
+ DEBUG("pat = " << pat);
+ throw ParseError::Todo("CPathResolver::handle_pattern()");
}
void CPathResolver::handle_function(AST::Function& fcn)
{
CResolvePaths_NodeVisitor node_visitor(*this);
+ for( auto& arg : fcn.args() )
+ m_locals.push_back(arg.first);
+
fcn.code().visit_nodes( node_visitor );
resolve_type(fcn.rettype());
- FOREACH_M(AST::Function::Arglist, arg, fcn.args())
- {
- resolve_type(arg->second);
- }
+ for( auto& arg : fcn.args() )
+ resolve_type(arg.second);
+
+ pop_scope();
+ if( m_locals.size() != 0 )
+ throw ParseError::BugCheck("m_locals.size() != 0");
}
void ResolvePaths_HandleFunction(const AST::Crate& crate, const AST::Module& mod, AST::Function& fcn)
|