summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-10-22 22:48:57 +0800
committerJohn Hodge <tpg@mutabah.net>2016-10-22 22:48:57 +0800
commit539d1302e087dab9dd1919251956b5a1a3a4bee0 (patch)
tree6f084e5c0fb9e98b7532b81674fde277c551159f
parentdbc1d54d5c4fa19bee5c787f15868da3ebf07ddf (diff)
downloadmrust-539d1302e087dab9dd1919251956b5a1a3a4bee0.tar.gz
macro_rules - Hack to allow :ident and TOK_IDENT to match each other
-rw-r--r--src/macro_rules/eval.cpp52
-rw-r--r--src/parse/token.hpp2
2 files changed, 34 insertions, 20 deletions
diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp
index 3ccb6f6f..49cb7ed7 100644
--- a/src/macro_rules/eval.cpp
+++ b/src/macro_rules/eval.cpp
@@ -765,8 +765,7 @@ bool Macro_HandlePattern(TokenStream& lex, const MacroPatEnt& pat, ::std::vector
const auto& rule = rules.m_rules.at(rule_index);
DEBUG( rule.m_contents.size() << " rule contents with " << bound_tts.mappings().size() << " bound values - " << name );
- assert( rule.m_param_names.size() >= bound_tts.mappings().size() );
- for( unsigned int i = 0; i < bound_tts.mappings().size(); i ++ )
+ for( unsigned int i = 0; i < ::std::min( bound_tts.mappings().size(), rule.m_param_names.size() ); i ++ )
{
DEBUG("- #" << i << " " << rule.m_param_names.at(i) << " = [" << bound_tts.mappings()[i] << "]");
}
@@ -785,7 +784,6 @@ unsigned int Macro_InvokeRules_MatchPattern(const MacroRules& rules, TokenTree i
TRACE_FUNCTION;
Span sp;// = input.span();
- unsigned int rule_index;
// - List of active rules (rules that haven't yet failed)
::std::vector< ::std::pair<unsigned, MacroPatternStream> > active_arms;
active_arms.reserve( rules.m_rules.size() );
@@ -889,13 +887,36 @@ unsigned int Macro_InvokeRules_MatchPattern(const MacroRules& rules, TokenTree i
auto tok = lex.getToken();
ERROR(tok.get_pos(), E0000, "No rules expected " << tok);
}
+
+
// 3. Check that all remaining arms are the same pattern.
+ unsigned int active_pat_idx = 0;
for(unsigned int i = 1; i < arm_pats.size(); i ++)
{
- if( arm_pats[0].tag() != arm_pats[i].tag() ) {
- ERROR(lex.getPosition(), E0000, "Incompatible macro arms - " << arm_pats[0].tag_str() << " vs " << arm_pats[i].tag_str());
+ const auto& active_pat = arm_pats[active_pat_idx];
+ const auto& this_pat = arm_pats[i];
+ // - TODO: You can end up with e.g. TOK_IDENT and :ident
+ // > In the above case, both the token and the patern consume the same number of input tokens, this is not always the case
+ if( active_pat.is_ExpectTok() && this_pat.is_ExpectPat() ) {
+ const auto& active_pat_tok = active_pat.as_ExpectTok();
+ const auto& this_pat_cap = this_pat.as_ExpectPat();
+ // :ident + TOK_IDENT = use the :ident
+ if( this_pat_cap.type == MacroPatEnt::PAT_IDENT ) {
+ if( active_pat_tok.type() == TOK_IDENT ) {
+ active_pat_idx = i;
+ continue ;
+ }
+ }
}
- TU_MATCH( SimplePatEnt, (arm_pats[0], arm_pats[i]), (e1, e2),
+ //else if( active_pat.is_ExpectPat() && this_pat.is_ExpectTok() ) {
+ // const auto& active_pat_cap = active_pat.as_ExpectPat();
+ // const auto& this_pat_tok = this_pat.as_ExpectTok();
+ //}
+
+ if( active_pat.tag() != arm_pats[i].tag() ) {
+ ERROR(lex.getPosition(), E0000, "Incompatible macro arms - SimplePatEnt::" << active_pat.tag_str() << " vs SimplePatEnt::" << arm_pats[i].tag_str());
+ }
+ TU_MATCH( SimplePatEnt, (active_pat, arm_pats[i]), (e1, e2),
(IfPat, BUG(sp, "IfPat unexpected here");),
(IfTok, BUG(sp, "IfTok unexpected here");),
(ExpectTok,
@@ -917,19 +938,17 @@ unsigned int Macro_InvokeRules_MatchPattern(const MacroRules& rules, TokenTree i
)
)
}
+
// 4. Apply patterns.
-
- // - Check for an end rule outside of the match so it can break correctly.
- if( arm_pats[0].is_End() ) {
+ TU_MATCH( SimplePatEnt, (arm_pats[active_pat_idx]), (e),
+ (End,
auto tok = lex.getToken();
if( tok.type() != TOK_EOF ) {
ERROR(lex.getPosition(), E0000, "Unexpected " << tok << ", expected TOK_EOF");
}
// NOTE: There can be multiple arms active, take the first.
- rule_index = active_arms[0].first;
- break ;
- }
- TU_MATCH( SimplePatEnt, (arm_pats[0]), (e),
+ return active_arms[0].first;
+ ),
(IfPat, BUG(sp, "IfPat unexpected here");),
(IfTok, BUG(sp, "IfTok unexpected here");),
(ExpectTok,
@@ -983,16 +1002,11 @@ unsigned int Macro_InvokeRules_MatchPattern(const MacroRules& rules, TokenTree i
// Use the shallowest iteration state
// TODO: All other should be on the first iteration.
Macro_HandlePatternCap(lex, e.idx, e.type, *shortest, bound_tts);
- ),
- (End,
- BUG(sp, "SimplePatEnt::End unexpected here");
)
)
- // Keep looping - breakout is handled by an if above
+ // Keep looping - breakout is handled in 'End' above
}
-
- return rule_index;
}
void Macro_InvokeRules_CountSubstUses(ParameterMappings& bound_tts, const ::std::vector<MacroExpansionEnt>& contents)
diff --git a/src/parse/token.hpp b/src/parse/token.hpp
index 39d3654f..5fdcbc77 100644
--- a/src/parse/token.hpp
+++ b/src/parse/token.hpp
@@ -122,7 +122,7 @@ public:
)
throw "";
}
- bool operator!=(const Token& r) { return !(*this == r); }
+ bool operator!=(const Token& r) const { return !(*this == r); }
::std::string to_str() const;