From cf0bc71ad1bd5a9bc1c9ee19305aec0e31641986 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 26 Sep 2016 16:05:59 +0800 Subject: AST - Move module-level macro invocations into the Item list --- src/ast/ast.cpp | 3 +++ src/ast/ast.hpp | 4 +--- src/expand/mod.cpp | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 885ea677..7b92be33 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -271,6 +271,9 @@ void Module::add_ext_crate(bool is_public, ::std::string ext_name, ::std::string void Module::add_alias(bool is_public, UseStmt us, ::std::string name, MetaItems attrs) { this->add_item( is_public, mv$(name), Item(mv$(us)), mv$(attrs) ); } +void Module::add_macro_invocation(MacroInvocation item) { + this->add_item( false, "", Item( mv$(item) ), ::AST::MetaItems {} ); +} void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro) { m_macros.push_back( Named( mv$(name), mv$(macro), is_exported ) ); } diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 533832e2..1b5a04d0 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -517,6 +517,7 @@ public: void add_item(bool is_pub, ::std::string name, Item it, MetaItems attrs); void add_ext_crate(bool is_public, ::std::string ext_name, ::std::string imp_name, MetaItems attrs); void add_alias(bool is_public, UseStmt path, ::std::string name, MetaItems attrs); + void add_macro_invocation(MacroInvocation item); void add_impl(Impl impl) { m_impls.emplace_back( mv$(impl) ); @@ -528,9 +529,6 @@ public: void add_macro_import(::std::string name, const MacroRules& mr) { m_macro_import_res.push_back( NamedNS( mv$(name), &mr, false ) ); } - void add_macro_invocation(MacroInvocation item) { - m_macro_invocations.push_back( mv$(item) ); - } diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index bb79a0bc..791d0206 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -614,8 +614,10 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList mo // 3. General items DEBUG("Items"); - for( auto& i : mod.items() ) + for( unsigned int idx = 0; idx < mod.items().size(); idx ++ ) { + auto& i = mod.items()[idx]; + DEBUG("- " << i.name << " (" << ::AST::Item::tag_to_str(i.data.tag()) << ") :: " << i.data.attrs); ::AST::Path path = modpath + i.name; @@ -627,7 +629,33 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList mo // Skip, nothing ), (MacroInv, - TODO(i.data.span, "Macro invocation in item list"); + // Move out of the module to avoid invalidation if a new macro invocation is added + auto mi_owned = mv$(e); + + auto& attrs = mi_owned.attrs(); + Expand_Attrs(attrs, stage_pre(is_early), [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); }); + + auto ttl = Expand_Macro(is_early, crate, modstack, mod, mi_owned); + + if( ! ttl.get() ) + { + Expand_Attrs(attrs, stage_post(is_early), [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); }); + // - Return ownership to the list + if( mi_owned.name() == "" ) { + mod.items()[idx].data = AST::Item(); + } + else { + mod.items()[idx].data = AST::Item( mv$(mi_owned) ); + } + } + else + { + // Re-parse tt + assert(ttl.get()); + Parse_ModRoot_Items(*ttl, mod); + // - Any new macro invocations ends up at the end of the list and handled + mod.items()[idx].data = AST::Item(); + } ), (Use, // No inner expand. @@ -749,8 +777,11 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList mo ) Expand_Attrs(attrs, stage_post(is_early), crate, path, mod, i.data); - if( i.data.attrs.m_items.size() == 0 ) - i.data.attrs = mv$(attrs); + + // TODO: When would this _not_ be empty? + auto& i2 = mod.items()[idx]; + if( i2.data.attrs.m_items.size() == 0 ) + i2.data.attrs = mv$(attrs); } // IGNORE m_anon_modules, handled as part of expressions -- cgit v1.2.3