diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-26 16:05:59 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-26 16:05:59 +0800 |
commit | cf0bc71ad1bd5a9bc1c9ee19305aec0e31641986 (patch) | |
tree | 83ed832002ed45c2137ab71e22f6897d48ea79aa /src | |
parent | c7ab799892231de0bc91b16637c2f0fce11f3536 (diff) | |
download | mrust-cf0bc71ad1bd5a9bc1c9ee19305aec0e31641986.tar.gz |
AST - Move module-level macro invocations into the Item list
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 3 | ||||
-rw-r--r-- | src/ast/ast.hpp | 4 | ||||
-rw-r--r-- | src/expand/mod.cpp | 39 |
3 files changed, 39 insertions, 7 deletions
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<MacroRulesPtr>( 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<const MacroRules*>( 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<const AST::Module*> 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<const AST::Module*> 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<const AST::Module*> 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 |