Merge #1041
1041: macros: Only expand merged repetitions if they contain the same amount r=CohenArthur a=CohenArthur Depends on #1040 Fixes #948 Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
This commit is contained in:
commit
cc6e405912
|
@ -30,18 +30,14 @@ SubstituteCtx::substitute_metavar (std::unique_ptr<AST::Token> &metavar)
|
||||||
return expanded;
|
return expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<AST::Token>>
|
bool
|
||||||
SubstituteCtx::substitute_repetition (
|
SubstituteCtx::check_repetition_amount (size_t pattern_start,
|
||||||
size_t pattern_start, size_t pattern_end,
|
size_t pattern_end,
|
||||||
std::unique_ptr<AST::Token> separator_token)
|
size_t &expected_repetition_amount)
|
||||||
{
|
{
|
||||||
rust_assert (pattern_end < macro.size ());
|
bool first_fragment_found = false;
|
||||||
|
bool is_valid = true;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<AST::Token>> expanded;
|
|
||||||
|
|
||||||
// Find the first fragment and get the amount of repetitions that we should
|
|
||||||
// perform
|
|
||||||
size_t repeat_amount = 0;
|
|
||||||
for (size_t i = pattern_start; i < pattern_end; i++)
|
for (size_t i = pattern_start; i < pattern_end; i++)
|
||||||
{
|
{
|
||||||
if (macro.at (i)->get_id () == DOLLAR_SIGN)
|
if (macro.at (i)->get_id () == DOLLAR_SIGN)
|
||||||
|
@ -59,17 +55,48 @@ SubstituteCtx::substitute_repetition (
|
||||||
rust_error_at (frag_token->get_locus (),
|
rust_error_at (frag_token->get_locus (),
|
||||||
"metavar %s used in repetition does not exist",
|
"metavar %s used in repetition does not exist",
|
||||||
frag_token->get_str ().c_str ());
|
frag_token->get_str ().c_str ());
|
||||||
// FIXME:
|
|
||||||
return expanded;
|
is_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Refactor, ugly
|
size_t repeat_amount = it->second.get_match_amount ();
|
||||||
repeat_amount = it->second.get_match_amount ();
|
if (!first_fragment_found)
|
||||||
|
{
|
||||||
|
first_fragment_found = true;
|
||||||
|
expected_repetition_amount = repeat_amount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (repeat_amount != expected_repetition_amount)
|
||||||
|
{
|
||||||
|
rust_error_at (
|
||||||
|
frag_token->get_locus (),
|
||||||
|
"different amount of matches used in merged "
|
||||||
|
"repetitions: expected %ld, got %ld",
|
||||||
|
expected_repetition_amount, repeat_amount);
|
||||||
|
is_valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return is_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<AST::Token>>
|
||||||
|
SubstituteCtx::substitute_repetition (
|
||||||
|
size_t pattern_start, size_t pattern_end,
|
||||||
|
std::unique_ptr<AST::Token> separator_token)
|
||||||
|
{
|
||||||
|
rust_assert (pattern_end < macro.size ());
|
||||||
|
|
||||||
|
size_t repeat_amount = 0;
|
||||||
|
if (!check_repetition_amount (pattern_start, pattern_end, repeat_amount))
|
||||||
|
return {};
|
||||||
|
|
||||||
rust_debug ("repetition amount to use: %lu", repeat_amount);
|
rust_debug ("repetition amount to use: %lu", repeat_amount);
|
||||||
|
std::vector<std::unique_ptr<AST::Token>> expanded;
|
||||||
std::vector<std::unique_ptr<AST::Token>> new_macro;
|
std::vector<std::unique_ptr<AST::Token>> new_macro;
|
||||||
|
|
||||||
// We want to generate a "new macro" to substitute with. This new macro
|
// We want to generate a "new macro" to substitute with. This new macro
|
||||||
|
|
|
@ -26,6 +26,17 @@ class SubstituteCtx
|
||||||
std::vector<std::unique_ptr<AST::Token>> ¯o;
|
std::vector<std::unique_ptr<AST::Token>> ¯o;
|
||||||
std::map<std::string, MatchedFragmentContainer> &fragments;
|
std::map<std::string, MatchedFragmentContainer> &fragments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the repetition amount to use when expanding a repetition, and
|
||||||
|
* check that all fragments used respect that repetition amount
|
||||||
|
*
|
||||||
|
* @param pattern_start Start of the repetition pattern
|
||||||
|
* @param pattern_end End of the repetition pattern
|
||||||
|
* @param repeat_amount Reference to fill with the matched repetition amount
|
||||||
|
*/
|
||||||
|
bool check_repetition_amount (size_t pattern_start, size_t pattern_end,
|
||||||
|
size_t &repeat_amount);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input,
|
SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input,
|
||||||
std::vector<std::unique_ptr<AST::Token>> ¯o,
|
std::vector<std::unique_ptr<AST::Token>> ¯o,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
macro_rules! repeat {
|
||||||
|
( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* ))
|
||||||
|
// { dg-error "different amount of matches used in merged repetitions" "" { target *-*-* } .-1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> i32 {
|
||||||
|
let _ = repeat!(1, 2, 3; 2, 3);
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
macro_rules! repeat {
|
||||||
|
( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* ))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> i32 {
|
||||||
|
let t = repeat!(1, 1; 2, 2);
|
||||||
|
|
||||||
|
t.0 .0 + t.0 .1 + t.1 .0 + t.1 .1 - 6
|
||||||
|
}
|
Loading…
Reference in New Issue