summaryrefslogtreecommitdiff
path: root/src/convert/resolve.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/convert/resolve.cpp')
-rw-r--r--src/convert/resolve.cpp96
1 files changed, 94 insertions, 2 deletions
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 504fec93..e1dea29f 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -1,4 +1,9 @@
/*
+ * "mrustc" Rust->C converter
+ * - By John Hodge (Mutabah / thePowersGang)
+ *
+ * convert/resolve.cpp
+ * - Resolve names into absolute format
*/
#include "../common.hpp"
#include "../ast/ast.hpp"
@@ -8,6 +13,7 @@ class CPathResolver
{
const AST::Crate& m_crate;
const AST::Module& m_module;
+ const AST::Path m_module_path;
::std::vector< ::std::string > m_locals;
// TODO: Maintain a stack of variable scopes
@@ -47,12 +53,20 @@ public:
{
}
+ void visit(AST::ExprNode_Macro& node) {
+ throw ParseError::Todo("Resolve-time expanding of macros");
+
+ //MacroExpander expanded_macro = Macro_Invoke(node.m_name.c_str(), node.m_tokens);
+ // TODO: Requires being able to replace the node with a completely different type of node
+ //node.replace( Parse_Expr0(expanded_macro) );
+ }
+
void visit(AST::ExprNode_NamedValue& node) {
m_res.resolve_path(node.m_path, true);
}
- void visit(AST::ExprNode_Match& node) {
-
+ void visit(AST::ExprNode_Match& node)
+ {
AST::NodeVisitor::visit(node.m_val);
for( auto& arm : node.m_arms )
@@ -110,6 +124,33 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
}
}
// Search relative to current module
+ // > Search local use definitions (function-level)
+ // - TODO: Local use statements (scoped)
+ // > Search module-level definitions
+ for( const auto& item_mod : m_module.submods() )
+ {
+ if( item_mod.first.name() == path[0].name() ) {
+ // Check name down?
+ // Add current module path
+ path = m_module_path + path;
+ }
+ }
+ for( const auto& item_fcn : m_module.functions() )
+ {
+ if( item_fcn.first.name() == path[0].name() ) {
+ path = m_module_path + path;
+ break;
+ }
+ }
+ for( const auto& import : m_module.imports() )
+ {
+ const ::std::string& bind_name = ::std::get<0>(import);
+ const AST::Path& bind_path = ::std::get<1>(import);
+ if( bind_name == path[0].name() ) {
+ path = AST::Path::add_tailing(bind_path, path);
+ }
+ }
+
throw ParseError::Todo("CPathResolver::resolve_path()");
}
}
@@ -117,15 +158,66 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
void CPathResolver::resolve_type(TypeRef& type) const
{
// TODO: Convert type into absolute
+ DEBUG("type = " << type);
throw ParseError::Todo("CPathResolver::resolve_type()");
}
void CPathResolver::handle_pattern(AST::Pattern& pat)
{
DEBUG("pat = " << pat);
+ // Resolve names
+ switch(pat.type())
+ {
+ case AST::Pattern::ANY:
+ // Wildcard, nothing to do
+ break;
+ case AST::Pattern::MAYBE_BIND: {
+ ::std::string name = pat.binding();
+ // Locate a _constant_ within the current namespace which matches this name
+ // - Variables don't count
+ AST::Path newpath;
+ newpath.append( AST::PathNode(name, {}) );
+ resolve_path(newpath, false);
+ if( newpath.is_relative() )
+ {
+ // It's a name binding (desugar to 'name @ _')
+ pat = AST::Pattern();
+ pat.set_bind(name);
+ }
+ else
+ {
+ // It's a constant (value)
+
+ pat = AST::Pattern(
+ AST::Pattern::TagValue(),
+ ::std::unique_ptr<AST::ExprNode>( new AST::ExprNode_NamedValue( ::std::move(newpath) ) )
+ );
+ }
+ break; }
+ case AST::Pattern::VALUE: {
+ CResolvePaths_NodeVisitor nv(*this);
+ pat.node().visit(nv);
+ break; }
+ case AST::Pattern::TUPLE:
+ // Tuple is handled by subpattern code
+ break;
+ case AST::Pattern::TUPLE_STRUCT:
+ // Resolve the path!
+ // - TODO: Restrict to types and enum variants
+ resolve_path( pat.path(), false );
+ break;
+ }
+ // Extract bindings and add to namespace
+ if( pat.binding().size() > 0 )
+ m_locals.push_back( pat.binding() );
+ for( auto& subpat : pat.sub_patterns() )
+ handle_pattern(subpat);
+
+
throw ParseError::Todo("CPathResolver::handle_pattern()");
}
+/// Perform name resolution in a function
void CPathResolver::handle_function(AST::Function& fcn)
{
CResolvePaths_NodeVisitor node_visitor(*this);