summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-10-09 12:53:11 +0800
committerJohn Hodge <tpg@mutabah.net>2016-10-09 12:53:11 +0800
commitbc0bc36123727c258dd3f2a61b7e46507485777b (patch)
tree069fced4cc9226d3cd49abfb1b401bddf3b48fef
parentbaaca746b480d0ede1c15ae24327f57475d04353 (diff)
downloadmrust-bc0bc36123727c258dd3f2a61b7e46507485777b.tar.gz
Expand - #[macro_reexport]
-rw-r--r--src/ast/ast.cpp3
-rw-r--r--src/ast/ast.hpp4
-rw-r--r--src/expand/macro_rules.cpp39
-rw-r--r--src/expand/mod.cpp1
-rw-r--r--src/hir/deserialise.cpp3
-rw-r--r--src/hir/from_ast.cpp27
-rw-r--r--src/macro_rules/macro_rules_ptr.hpp2
7 files changed, 62 insertions, 17 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 25a1c82f..08aad21b 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -299,6 +299,9 @@ void Module::add_macro_invocation(MacroInvocation item) {
void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro) {
m_macros.push_back( Named<MacroRulesPtr>( mv$(name), mv$(macro), is_exported ) );
}
+void Module::add_macro_import(::std::string name, const MacroRules& mr) {
+ m_macro_import_res.push_back( NamedNS<const MacroRules*>( mv$(name), &mr, false ) );
+}
Item Item::clone() const
{
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index e65ba2c2..700a7e40 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -549,9 +549,7 @@ public:
m_neg_impls.emplace_back( mv$(impl) );
}
void add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro);
- 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_import(::std::string name, const MacroRules& mr);
diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp
index 99e7680b..c460e35d 100644
--- a/src/expand/macro_rules.cpp
+++ b/src/expand/macro_rules.cpp
@@ -1,4 +1,14 @@
-
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * expand/macro_rules.cpp
+ * - Top-level handling of macro_rules! macros
+ * > macro_rules! dispatch handler
+ * > #[macro_use]
+ * > #[macro_export]
+ * > #[macro_reexport]
+ */
#include <synext.hpp>
#include "../ast/expr.hpp"
#include "../ast/ast.hpp"
@@ -6,6 +16,7 @@
#include <ast/crate.hpp>
#include "macro_rules.hpp"
#include <macro_rules/macro_rules.hpp>
+#include <hir/hir.hpp> // for HIR::Crate
class CMacroRulesExpander:
public ExpandProcMacro
@@ -115,6 +126,7 @@ class CMacroExportHandler:
auto it = ::std::find_if( mod.macros().begin(), mod.macros().end(), [&](const auto& x){ return x.name == name; } );
ASSERT_BUG(sp, it != mod.macros().end(), "Macro '" << name << "' not defined in this module");
it->data->m_exported = true;
+ DEBUG("- Export macro " << name << "!");
}
else {
ERROR(sp, E0000, "Use of #[macro_export] on non-macro - " << i.tag_str());
@@ -128,13 +140,28 @@ class CMacroReexportHandler:
AttrStage stage() const override { return AttrStage::Post; }
void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override
{
- if( i.is_Crate() ) {
- // TODO: Need to look up this crate in the crate list, then import all of the macros listed with the "export" flag set
- // - For now, all externally loaded macros are exported (weakly) so things work...
- }
- else {
+ if( !i.is_Crate() ) {
ERROR(sp, E0000, "Use of #[macro_reexport] on non-crate - " << i.tag_str());
}
+
+ const auto& crate_name = i.as_Crate().name;
+ auto& ext_crate = *crate.m_extern_crates.at(crate_name).m_hir;
+
+ if( mi.has_sub_items() )
+ {
+ for( const auto& si : mi.items() )
+ {
+ const auto& name = si.name();
+ auto it = ext_crate.m_exported_macros.find(name);
+ if( it == ext_crate.m_exported_macros.end() )
+ ERROR(sp, E0000, "Could not find macro " << name << "! in crate " << crate_name);
+ it->second->m_exported = true;
+ }
+ }
+ else
+ {
+ ERROR(sp, E0000, "#[macro_reexport] requires a list of macros");
+ }
}
};
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index 7c3206dd..485c0032 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -100,6 +100,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate&
return e;
}
}
+ // TODO: Shouldn't this use the _last_ located macro? Allowing later (local) defininitions to override it?
for( const auto& mri : mac_mod.macro_imports_res() )
{
//DEBUG("- " << mri.name);
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index be8cccc9..f9ad4460 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -286,7 +286,8 @@ namespace {
::MacroRules deserialise_macrorules()
{
::MacroRules rv;
- rv.m_exported = true;
+ // NOTE: This is set after loading.
+ //rv.m_exported = true;
rv.m_rules = deserialise_vec_c< ::MacroRulesArm>( [&](){ return deserialise_macrorulesarm(); });
rv.m_source_crate = read_string();
if(rv.m_source_crate == "")
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 02aa7e02..fb0b3186 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -1309,14 +1309,29 @@ public:
auto& macros = rv.m_exported_macros;
// - Extract macros from root module
- for( auto& mac : crate.m_root_module.macro_imports_res() ) {
- //if( mac.data->export ) {
- macros.insert( ::std::make_pair( mac.name, MacroRulesPtr(new MacroRules( mv$(*const_cast<MacroRules*>(mac.data)) )) ) );
- //}
- }
for( /*const*/ auto& mac : crate.m_root_module.macros() ) {
if( mac.data->m_exported ) {
- macros.insert( ::std::make_pair( mac.name, mv$(mac.data) ) );
+ auto res = macros.insert( ::std::make_pair( mac.name, mv$(mac.data) ) );
+ if( res.second )
+ DEBUG("- Define " << mac.name << "!");
+ }
+ else {
+ DEBUG("- Non-exported " << mac.name << "!");
+ }
+ }
+ for( auto& mac : crate.m_root_module.macro_imports_res() ) {
+ if( mac.data->m_exported && mac.name != "" ) {
+ auto v = ::std::make_pair( mac.name, MacroRulesPtr(new MacroRules( mv$(*const_cast<MacroRules*>(mac.data)) )) );
+ auto it = macros.find(mac.name);
+ if( it == macros.end() )
+ {
+ auto res = macros.insert( mv$(v) );
+ DEBUG("- Import " << mac.name << "! (from \"" << res.first->second->m_source_crate << "\")");
+ }
+ else {
+ DEBUG("- Replace " << mac.name << "! (from \"" << it->second->m_source_crate << "\") with one from \"" << v.second->m_source_crate << "\"");
+ it->second = mv$( v.second );
+ }
}
}
diff --git a/src/macro_rules/macro_rules_ptr.hpp b/src/macro_rules/macro_rules_ptr.hpp
index b910d2af..c5c01488 100644
--- a/src/macro_rules/macro_rules_ptr.hpp
+++ b/src/macro_rules/macro_rules_ptr.hpp
@@ -13,7 +13,7 @@ class MacroRulesPtr
{
MacroRules* m_ptr;
public:
- MacroRulesPtr() {}
+ MacroRulesPtr(): m_ptr(nullptr) {}
MacroRulesPtr(MacroRules* p): m_ptr(p) {}
MacroRulesPtr(MacroRulesPtr&& x):
m_ptr(x.m_ptr)