From 54af654480b0a686a0e0b6cd4fdc41feaafa7a77 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Sat, 17 Jan 2015 22:10:16 +0800 Subject: Split out AST iterator --- src/convert/ast_iterate.cpp | 164 +++++++++++++++++++++++++++++++++++ src/convert/ast_iterate.hpp | 51 +++++++++++ src/convert/resolve.cpp | 204 +++----------------------------------------- 3 files changed, 226 insertions(+), 193 deletions(-) create mode 100644 src/convert/ast_iterate.cpp create mode 100644 src/convert/ast_iterate.hpp (limited to 'src') diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp new file mode 100644 index 00000000..40133295 --- /dev/null +++ b/src/convert/ast_iterate.cpp @@ -0,0 +1,164 @@ +/** + */ +#include "ast_iterate.hpp" +#include "../ast/ast.hpp" + +// handle_path is pure virtual + +void CASTIterator::handle_type(TypeRef& type) +{ + DEBUG("type = " << type); + if( type.is_path() ) + { + handle_path(type.path(), MODE_TYPE); + } + else + { + for(auto& subtype : type.sub_types()) + handle_type(subtype); + } +} +void CASTIterator::handle_expr(AST::ExprNode& node) +{ +} +void CASTIterator::handle_params(AST::TypeParams& params) +{ + for( auto& param : params.params() ) + { + if( param.is_type() ) + local_type(param.name()); + } + for( auto& bound : params.bounds() ) + { + handle_type(bound.get_type()); + } +} + + +void CASTIterator::start_scope() +{ +} +void CASTIterator::local_type(::std::string name) +{ + DEBUG("type " << name); +} +void CASTIterator::local_variable(bool is_mut, ::std::string name, const TypeRef& type) +{ + DEBUG( (is_mut ? "mut " : "") << name << " : " << type ); +} +void CASTIterator::local_use(::std::string name, AST::Path path) +{ + DEBUG( name << " = " << path ); +} +void CASTIterator::end_scope() +{ +} + +void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) +{ + DEBUG("pat = " << pat); + // Resolve names + switch(pat.type()) + { + case AST::Pattern::ANY: + // Wildcard, nothing to do + break; + case AST::Pattern::MAYBE_BIND: + throw ::std::runtime_error("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid"); + case AST::Pattern::VALUE: + handle_expr( pat.node() ); + 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 + handle_path( pat.path(), CASTIterator::MODE_TYPE ); + break; + } + // Extract bindings and add to namespace + if( pat.binding().size() > 0 ) + { + // TODO: Mutable bindings + local_variable( false, pat.binding(), type_hint ); + } + for( auto& subpat : pat.sub_patterns() ) + handle_pattern(subpat, (const TypeRef&)TypeRef()); +} + +void CASTIterator::handle_module(AST::Path path, AST::Module& mod) +{ + start_scope(); + 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(); + + for( auto& submod : mod.submods() ) + { + DEBUG("Handling submod '" << submod.first.name() << "'"); + handle_module(path + submod.first.name(), submod.first); + } +} +void CASTIterator::handle_function(AST::Path path, AST::Function& fcn) +{ + start_scope(); + + handle_params(fcn.params()); + + handle_type(fcn.rettype()); + + for( auto& arg : fcn.args() ) + { + handle_type(arg.second); + AST::Pattern pat(AST::Pattern::TagBind(), arg.first); + handle_pattern( pat, arg.second ); + } + + handle_expr( fcn.code().node() ); + + end_scope(); +} +void CASTIterator::handle_impl(AST::Path modpath, AST::Impl& impl) +{ + start_scope(); + + // Generic params + handle_params( impl.params() ); + + // Trait + handle_type( impl.trait() ); + // Type + handle_type( impl.type() ); + + // TODO: Associated types + + // Functions + for( auto& fcn : impl.functions() ) + { + DEBUG("- Function '" << fcn.name << "'"); + handle_function(AST::Path() + fcn.name, fcn.data); + } + + end_scope(); +} + +void CASTIterator::handle_struct(AST::Path path, AST::Struct& str) +{ +} +void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) +{ +} +void CASTIterator::handle_alias(AST::Path path, AST::TypeAlias& alias) +{ +} diff --git a/src/convert/ast_iterate.hpp b/src/convert/ast_iterate.hpp new file mode 100644 index 00000000..3307159b --- /dev/null +++ b/src/convert/ast_iterate.hpp @@ -0,0 +1,51 @@ +#ifndef _AST_ITERATE_HPP_INCLUDED_ +#define _AST_ITERATE_HPP_INCLUDED_ + +#include +#include "../types.hpp" +#include "../ast/path.hpp" + +namespace AST { + +class ExprNode; +class Pattern; +class TypeParams; +class Impl; + +}; + +// Iterator for the AST, calls virtual functions on paths/types +class CASTIterator +{ +public: + enum PathMode { + MODE_EXPR, // Variables allowed + MODE_TYPE, + MODE_BIND, // Failure is allowed + }; + virtual void handle_path(AST::Path& path, PathMode mode) = 0; + virtual void handle_type(TypeRef& type); + virtual void handle_expr(AST::ExprNode& node); + + virtual void handle_params(AST::TypeParams& params); + + virtual void start_scope(); + virtual void local_type(::std::string name); + virtual void local_variable(bool is_mut, ::std::string name, const TypeRef& type); + virtual void local_use(::std::string name, AST::Path path); + virtual void end_scope(); + + virtual void handle_pattern(AST::Pattern& pat, const TypeRef& type_hint); + + virtual void handle_module(AST::Path path, AST::Module& mod); + + virtual void handle_function(AST::Path path, AST::Function& fcn); + virtual void handle_impl(AST::Path modpath, AST::Impl& impl); + + virtual void handle_struct(AST::Path path, AST::Struct& str); + virtual void handle_enum(AST::Path path, AST::Enum& enm); + virtual void handle_alias(AST::Path path, AST::TypeAlias& alias); +}; + +#endif + diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 309a433a..3fd7b7ea 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -8,199 +8,7 @@ #include "../common.hpp" #include "../ast/ast.hpp" #include "../parse/parseerror.hpp" - -// Iterator for the AST, calls virtual functions on paths/types -class CASTIterator -{ -public: - enum PathMode { - MODE_EXPR, // Variables allowed - MODE_TYPE, - MODE_BIND, // Failure is allowed - }; - virtual void handle_path(AST::Path& path, PathMode mode) = 0; - virtual void handle_type(TypeRef& type); - virtual void handle_expr(AST::ExprNode& node); - - virtual void handle_params(AST::TypeParams& params); - - virtual void start_scope(); - virtual void local_type(::std::string name); - virtual void local_variable(bool is_mut, ::std::string name, const TypeRef& type); - virtual void local_use(::std::string name, AST::Path path); - virtual void end_scope(); - - virtual void handle_pattern(AST::Pattern& pat, const TypeRef& type_hint); - - virtual void handle_module(AST::Path path, AST::Module& mod); - - virtual void handle_function(AST::Path path, AST::Function& fcn); - virtual void handle_impl(AST::Path modpath, AST::Impl& impl); - - virtual void handle_struct(AST::Path path, AST::Struct& str); - virtual void handle_enum(AST::Path path, AST::Enum& enm); - virtual void handle_alias(AST::Path path, AST::TypeAlias& alias); -}; - -// handle_path is pure virtual - -void CASTIterator::handle_type(TypeRef& type) -{ - DEBUG("type = " << type); - if( type.is_path() ) - { - handle_path(type.path(), MODE_TYPE); - } - else - { - for(auto& subtype : type.sub_types()) - handle_type(subtype); - } -} -void CASTIterator::handle_expr(AST::ExprNode& node) -{ -} -void CASTIterator::handle_params(AST::TypeParams& params) -{ - for( auto& param : params.params() ) - { - if( param.is_type() ) - local_type(param.name()); - } - for( auto& bound : params.bounds() ) - { - handle_type(bound.get_type()); - } -} - - -void CASTIterator::start_scope() -{ -} -void CASTIterator::local_type(::std::string name) -{ - DEBUG("type " << name); -} -void CASTIterator::local_variable(bool is_mut, ::std::string name, const TypeRef& type) -{ - DEBUG( (is_mut ? "mut " : "") << name << " : " << type ); -} -void CASTIterator::local_use(::std::string name, AST::Path path) -{ - DEBUG( name << " = " << path ); -} -void CASTIterator::end_scope() -{ -} - -void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) -{ - DEBUG("pat = " << pat); - // Resolve names - switch(pat.type()) - { - case AST::Pattern::ANY: - // Wildcard, nothing to do - break; - case AST::Pattern::MAYBE_BIND: - throw ParseError::BugCheck("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid"); - case AST::Pattern::VALUE: - handle_expr( pat.node() ); - 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 - handle_path( pat.path(), CASTIterator::MODE_TYPE ); - break; - } - // Extract bindings and add to namespace - if( pat.binding().size() > 0 ) - { - // TODO: Mutable bindings - local_variable( false, pat.binding(), type_hint ); - } - for( auto& subpat : pat.sub_patterns() ) - handle_pattern(subpat, (const TypeRef&)TypeRef()); -} - -void CASTIterator::handle_module(AST::Path path, AST::Module& mod) -{ - start_scope(); - 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(); - - for( auto& submod : mod.submods() ) - { - DEBUG("Handling submod '" << submod.first.name() << "'"); - handle_module(path + submod.first.name(), submod.first); - } -} -void CASTIterator::handle_function(AST::Path path, AST::Function& fcn) -{ - start_scope(); - - handle_params(fcn.params()); - - handle_type(fcn.rettype()); - - for( auto& arg : fcn.args() ) - { - handle_type(arg.second); - AST::Pattern pat(AST::Pattern::TagBind(), arg.first); - handle_pattern( pat, arg.second ); - } - - handle_expr( fcn.code().node() ); - - end_scope(); -} -void CASTIterator::handle_impl(AST::Path modpath, AST::Impl& impl) -{ - start_scope(); - - // Generic params - handle_params( impl.params() ); - - // Trait - handle_type( impl.trait() ); - // Type - handle_type( impl.type() ); - - // TODO: Associated types - - // Functions - for( auto& fcn : impl.functions() ) - { - DEBUG("- Function '" << fcn.name << "'"); - handle_function(AST::Path() + fcn.name, fcn.data); - } - - end_scope(); -} - -void CASTIterator::handle_struct(AST::Path path, AST::Struct& str) -{ -} -void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) -{ -} -void CASTIterator::handle_alias(AST::Path path, AST::TypeAlias& alias) -{ -} +#include "ast_iterate.hpp" // ==================================================================== // -- Path resolver (converts paths to absolute form) @@ -236,6 +44,7 @@ public: CPathResolver(const AST::Crate& crate); virtual void handle_path(AST::Path& path, CASTIterator::PathMode mode) override; + virtual void handle_expr(AST::ExprNode& node) override; virtual void handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) override; virtual void handle_module(AST::Path path, AST::Module& mod) override; @@ -462,6 +271,11 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) throw ParseError::Generic("Name resolution failed"); } } +void CPathResolver::handle_expr(AST::ExprNode& node) +{ + CResolvePaths_NodeVisitor nv(*this); + node.visit(nv); +} void CPathResolver::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) { @@ -595,6 +409,10 @@ void SetCrateName_Mod(::std::string name, AST::Module& mod) // TODO: All other types } + +// First pass of conversion +// - Tag paths of external crate items with crate name +// - Convert all paths into absolute paths (or local variable references) void ResolvePaths(AST::Crate& crate) { // Pre-process external crates to tag all paths -- cgit v1.2.3