From def96a573903b5fcb95e8a8dffb94a3a9a7f8501 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Sun, 18 Jan 2015 19:28:14 +0800 Subject: Most types iterating well, special case for Self type --- src/ast/ast.hpp | 8 +++++++ src/convert/ast_iterate.cpp | 46 +++++++++++++++++++++++++++++++------ src/convert/ast_iterate.hpp | 1 + src/convert/resolve.cpp | 56 ++++++++++++++++++++++++++++++++++++--------- src/types.cpp | 1 + 5 files changed, 94 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 849587f1..b684379f 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -176,6 +176,9 @@ public: const TypeParams& params() const { return m_params; } const TypeRef& type() const { return m_type; } + TypeParams& params() { return m_params; } + TypeRef& type() { return m_type; } + SERIALISABLE_PROTOTYPES(); }; @@ -265,7 +268,12 @@ public: } const TypeParams& params() const { return m_params; } + const ItemList& functions() const { return m_functions; } const ItemList& types() const { return m_types; } + + TypeParams& params() { return m_params; } + ItemList& functions() { return m_functions; } + ItemList& types() { return m_types; } void add_type(::std::string name, TypeRef type) { m_types.push_back( Item(move(name), move(type), true) ); diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index f9d1f927..5d8961f9 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -92,12 +92,9 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) void CASTIterator::handle_module(AST::Path path, AST::Module& mod) { + INDENT(); start_scope(); - for( auto& fcn : mod.functions() ) - { - DEBUG("Handling function '" << fcn.name << "'"); - handle_function(path + fcn.name, fcn.data); - } + for( auto& item : mod.structs() ) { DEBUG("Handling struct " << item.name); @@ -108,12 +105,28 @@ void CASTIterator::handle_module(AST::Path path, AST::Module& mod) DEBUG("Handling enum " << item.name); handle_enum(path + item.name, item.data); } + for( auto& item : mod.traits() ) + { + DEBUG("Handling trait " << item.name); + handle_trait(path + item.name, item.data); + } + for( auto& item : mod.type_aliases() ) + { + DEBUG("Handling alias " << item.name); + handle_alias(path + item.name, item.data); + } + for( auto& fcn : mod.functions() ) + { + DEBUG("Handling function '" << fcn.name << "'"); + handle_function(path + fcn.name, fcn.data); + } for( auto& impl : mod.impls() ) { DEBUG("Handling 'impl' " << impl); handle_impl(path, impl); } + // End scope before handling sub-modules end_scope(); @@ -122,6 +135,7 @@ void CASTIterator::handle_module(AST::Path path, AST::Module& mod) DEBUG("Handling submod '" << submod.first.name() << "'"); handle_module(path + submod.first.name(), submod.first); } + UNINDENT(); } void CASTIterator::handle_function(AST::Path path, AST::Function& fcn) { @@ -138,7 +152,10 @@ void CASTIterator::handle_function(AST::Path path, AST::Function& fcn) handle_pattern( pat, arg.second ); } - handle_expr( fcn.code().node() ); + if( fcn.code().is_valid() ) + { + handle_expr( fcn.code().node() ); + } end_scope(); } @@ -168,17 +185,32 @@ void CASTIterator::handle_impl(AST::Path modpath, AST::Impl& impl) void CASTIterator::handle_struct(AST::Path path, AST::Struct& str) { + start_scope(); handle_params( str.params() ); for( auto& f : str.fields() ) handle_type( f.second ); + end_scope(); } void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) { + start_scope(); handle_params( enm.params() ); for( auto& f : enm.variants() ) handle_type( f.second ); + end_scope(); +} +void CASTIterator::handle_trait(AST::Path path, AST::Trait& trait) +{ + start_scope(); + handle_params( trait.params() ); + for( auto& fcn : trait.functions() ) + handle_function( path + fcn.name, fcn.data ); + end_scope(); } void CASTIterator::handle_alias(AST::Path path, AST::TypeAlias& alias) { - throw ::std::runtime_error("TODO - handle_alias"); + start_scope(); + handle_params( alias.params() ); + handle_type( alias.type() ); + end_scope(); } diff --git a/src/convert/ast_iterate.hpp b/src/convert/ast_iterate.hpp index fad77926..5a51a78d 100644 --- a/src/convert/ast_iterate.hpp +++ b/src/convert/ast_iterate.hpp @@ -44,6 +44,7 @@ public: virtual void handle_struct(AST::Path path, AST::Struct& str); virtual void handle_enum(AST::Path path, AST::Enum& enm); + virtual void handle_trait(AST::Path path, AST::Trait& trait); virtual void handle_alias(AST::Path path, AST::TypeAlias& alias); }; diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 2e961f1f..5c71cd8f 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -151,6 +151,7 @@ void CPathResolver::end_scope() void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) { + INDENT(); DEBUG("path = " << path); // Handle generic components of the path @@ -179,6 +180,7 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) // If there's a single node, and we're in expresion mode, look for a variable // Otherwise, search for a type bool is_trivial_path = path.size() == 1 && path[0].args().size() == 0; + LocalItem::Type search_type = (is_trivial_path && mode == MODE_EXPR ? LocalItem::VAR : LocalItem::TYPE); auto local = lookup_local( search_type, path[0].name() ); if( local.is_some() ) @@ -230,14 +232,20 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) return ; } } - for( const auto& item_fcn : m_module->functions() ) + for( const auto& import : m_module->imports() ) { - if( item_fcn.name == path[0].name() ) { - path = m_module_path + path; + const ::std::string& bind_name = import.name; + const AST::Path& bind_path = import.data; + if( bind_name == "" ) { + } + else if( bind_name == path[0].name() ) { + path = AST::Path::add_tailing(bind_path, path); path.resolve( m_crate ); return ; } } + + // Types for( const auto& item : m_module->structs() ) { if( item.name == path[0].name() ) { @@ -246,7 +254,7 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) return ; } } - for( const auto& item : m_module->statics() ) + for( const auto& item : m_module->enums() ) { if( item.name == path[0].name() ) { path = m_module_path + path; @@ -254,14 +262,28 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) return ; } } - for( const auto& import : m_module->imports() ) + for( const auto& item : m_module->traits() ) { - const ::std::string& bind_name = import.name; - const AST::Path& bind_path = import.data; - if( bind_name == "" ) { + if( item.name == path[0].name() ) { + path = m_module_path + path; + path.resolve( m_crate ); + return ; } - else if( bind_name == path[0].name() ) { - path = AST::Path::add_tailing(bind_path, path); + } + + // Values / Functions + for( const auto& item_fcn : m_module->functions() ) + { + if( item_fcn.name == path[0].name() ) { + path = m_module_path + path; + path.resolve( m_crate ); + return ; + } + } + for( const auto& item : m_module->statics() ) + { + if( item.name == path[0].name() ) { + path = m_module_path + path; path.resolve( m_crate ); return ; } @@ -272,13 +294,22 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) if( mode != MODE_BIND ) throw ParseError::Generic("Name resolution failed"); } + + UNINDENT(); } void CPathResolver::handle_type(TypeRef& type) { if( type.is_path() && type.path().is_relative() && type.path().size() == 1 ) { const auto& name = type.path()[0].name(); - if( lookup_local(LocalItem::TYPE, name).is_some() ) + + if( name == "Self" ) + { + // TODO: Handle "Self" correctly + // THIS IS WRONG! (well, I think) + type = TypeRef(TypeRef::TagArg(), "Self"); + } + else if( lookup_local(LocalItem::TYPE, name).is_some() ) { type = TypeRef(TypeRef::TagArg(), name); } @@ -433,6 +464,7 @@ void SetCrateName_Mod(::std::string name, AST::Module& mod) // - Convert all paths into absolute paths (or local variable references) void ResolvePaths(AST::Crate& crate) { + DEBUG(" >>>"); // Pre-process external crates to tag all paths for(auto& ec : crate.extern_crates()) { @@ -441,8 +473,10 @@ void ResolvePaths(AST::Crate& crate) // Handle 'use' statements in an initial parss ResolvePaths_HandleModule_Use(crate, AST::Path(AST::Path::TagAbsolute()), crate.root_module()); + DEBUG(" ---"); // Then do path resolution on all other items CPathResolver pr(crate); pr.handle_module(AST::Path(AST::Path::TagAbsolute()), crate.root_module()); + DEBUG(" <<<"); } diff --git a/src/types.cpp b/src/types.cpp index f674d446..25598d45 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -35,6 +35,7 @@ bool TypeRef::operator==(const TypeRef& x) const case TypeRef::ASSOCIATED: return m_path == x.m_path && m_inner_types == x.m_inner_types; } + throw ::std::runtime_error(FMT("BUGCHECK - Unhandled TypeRef class '" << m_class << "'")); } ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr) { -- cgit v1.2.3