summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-02 22:56:19 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-02 22:56:19 +0800
commitdc69b7313160536c4a361a4474ec361ec3b1e55b (patch)
treede593eda4fb273edc1cd18d063109fa3461d4559 /src
parente31eef7a4a00d46ce184dd33aea4d8c07b7ffb39 (diff)
downloadmrust-dc69b7313160536c4a361a4474ec361ec3b1e55b.tar.gz
Hygiene - Possibly working
Diffstat (limited to 'src')
-rw-r--r--src/ident.cpp15
-rw-r--r--src/include/ident.hpp19
-rw-r--r--src/macro_rules/eval.cpp8
-rw-r--r--src/macro_rules/macro_rules.hpp2
-rw-r--r--src/macro_rules/parse.cpp3
5 files changed, 34 insertions, 13 deletions
diff --git a/src/ident.cpp b/src/ident.cpp
index 8543d6fa..45c96f2e 100644
--- a/src/ident.cpp
+++ b/src/ident.cpp
@@ -15,8 +15,17 @@ unsigned int Ident::Hygiene::g_next_scope = 0;
bool Ident::Hygiene::is_visible(const Hygiene& src) const
{
// HACK: Disable hygiene for now
- return true;
- //return this->scope_index == src.scope_index;
+ //return true;
+
+ if( this->contexts.size() == 0 ) {
+ return src.contexts.size() == 0;
+ }
+
+ auto des = this->contexts.back();
+ for(const auto& c : src.contexts)
+ if( des == c )
+ return true;
+ return false;
}
::std::ostream& operator<<(::std::ostream& os, const Ident& x) {
@@ -25,7 +34,7 @@ bool Ident::Hygiene::is_visible(const Hygiene& src) const
}
::std::ostream& operator<<(::std::ostream& os, const Ident::Hygiene& x) {
- os << "{" << x.scope_index << "}";
+ os << "{" << x.contexts << "}";
return os;
}
diff --git a/src/include/ident.hpp b/src/include/ident.hpp
index cff918ca..1122a68b 100644
--- a/src/include/ident.hpp
+++ b/src/include/ident.hpp
@@ -14,20 +14,29 @@ struct Ident
class Hygiene
{
static unsigned g_next_scope;
- unsigned int scope_index;
+
+ ::std::vector<unsigned int> contexts;
Hygiene(unsigned int index):
- scope_index(index)
+ contexts({index})
{}
public:
Hygiene():
- scope_index(0)
+ contexts({})
{}
static Hygiene new_scope()
{
return Hygiene(++g_next_scope);
}
+ static Hygiene new_scope_chained(const Hygiene& parent)
+ {
+ Hygiene rv;
+ rv.contexts.reserve( parent.contexts.size() + 1 );
+ rv.contexts.insert( rv.contexts.begin(), parent.contexts.begin(), parent.contexts.end() );
+ rv.contexts.push_back( ++g_next_scope );
+ return rv;
+ }
Hygiene(Hygiene&& x) = default;
Hygiene(const Hygiene& x) = default;
@@ -36,8 +45,8 @@ struct Ident
// Returns true if an ident with hygine `souce` can see an ident with this hygine
bool is_visible(const Hygiene& source) const;
- bool operator==(const Hygiene& x) const { return scope_index == x.scope_index; }
- bool operator!=(const Hygiene& x) const { return scope_index != x.scope_index; }
+ //bool operator==(const Hygiene& x) const { return scope_index == x.scope_index; }
+ //bool operator!=(const Hygiene& x) const { return scope_index != x.scope_index; }
friend ::std::ostream& operator<<(::std::ostream& os, const Hygiene& v);
};
diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp
index 3a55f500..5f2ac6b0 100644
--- a/src/macro_rules/eval.cpp
+++ b/src/macro_rules/eval.cpp
@@ -571,12 +571,12 @@ class MacroExpander:
public:
MacroExpander(const MacroExpander& x) = delete;
- MacroExpander(const ::std::string& macro_name, const ::std::vector<MacroExpansionEnt>& contents, ParameterMappings mappings, ::std::string crate_name):
+ MacroExpander(const ::std::string& macro_name, const Ident::Hygiene& parent_hygiene, const ::std::vector<MacroExpansionEnt>& contents, ParameterMappings mappings, ::std::string crate_name):
m_macro_filename( FMT("Macro:" << macro_name) ),
m_crate_name( mv$(crate_name) ),
m_mappings( mv$(mappings) ),
m_state( contents, m_mappings ),
- m_hygiene( Ident::Hygiene::new_scope() )
+ m_hygiene( Ident::Hygiene::new_scope_chained(parent_hygiene) )
{
}
@@ -708,7 +708,7 @@ void Macro_HandlePatternCap(TokenStream& lex, unsigned int index, MacroPatEnt::T
;
else
CHECK_TOK(tok, TOK_IDENT);
- bound_tts.insert( index, iterations, InterpolatedFragment( TokenTree(tok) ) );
+ bound_tts.insert( index, iterations, InterpolatedFragment( TokenTree(lex.getHygiene(), tok) ) );
break;
}
}
@@ -786,7 +786,7 @@ bool Macro_HandlePattern(TokenStream& lex, const MacroPatEnt& pat, ::std::vector
// Run through the expansion counting the number of times each fragment is used
Macro_InvokeRules_CountSubstUses(bound_tts, rule.m_contents);
- TokenStream* ret_ptr = new MacroExpander(name, rule.m_contents, mv$(bound_tts), rules.m_source_crate);
+ TokenStream* ret_ptr = new MacroExpander(name, rules.m_hygiene, rule.m_contents, mv$(bound_tts), rules.m_source_crate);
return ::std::unique_ptr<TokenStream>( ret_ptr );
}
diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp
index 30e3e45b..337a4707 100644
--- a/src/macro_rules/macro_rules.hpp
+++ b/src/macro_rules/macro_rules.hpp
@@ -142,6 +142,8 @@ public:
/// - Populated on deserialise if not already set
::std::string m_source_crate;
+ Ident::Hygiene m_hygiene;
+
/// Expansion rules
::std::vector<MacroRulesArm> m_rules;
diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp
index c7a6ef89..4da91a90 100644
--- a/src/macro_rules/parse.cpp
+++ b/src/macro_rules/parse.cpp
@@ -473,7 +473,8 @@ MacroRulesPtr Parse_MacroRules(TokenStream& lex)
rule_arms.push_back( mv$(arm) );
}
- auto rv = new MacroRules();
+ auto rv = new MacroRules( );
+ rv->m_hygiene = lex.getHygiene();
rv->m_rules = mv$(rule_arms);
return MacroRulesPtr(rv);