From d0461823a2359e0eb052dd10813bc6a3d66f7c74 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Thu, 1 Jan 2015 13:51:57 +0800 Subject: Name resolve framework coming along --- src/convert/resolve.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 12 deletions(-) (limited to 'src/convert/resolve.cpp') 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) -- cgit v1.2.3