Skip to content

Commit 143aad6

Browse files
committed
substitute_repetition: Add parsing of repetition pattern
1 parent ae1f91a commit 143aad6

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

gcc/rust/expand/rust-macro-expand.cc

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3905,20 +3905,58 @@ MacroExpander::substitute_metavar (
39053905
return expanded;
39063906
}
39073907

3908+
std::vector<std::unique_ptr<AST::Token>>
3909+
MacroExpander::substitute_repetition (
3910+
std::vector<std::unique_ptr<AST::Token>> &input,
3911+
std::map<std::string, MatchedFragment> &fragments,
3912+
std::vector<std::unique_ptr<AST::Token>> &pattern)
3913+
{
3914+
// If the repetition is not anything we know (ie no declared metavars, or
3915+
// metavars which aren't present in the fragment), we can just error out. No
3916+
// need to paste the tokens as if nothing had happened.
3917+
for (auto &token : pattern)
3918+
rust_debug ("[repetition pattern]: %s", token->as_string ().c_str ());
3919+
3920+
return std::vector<std::unique_ptr<AST::Token>> ();
3921+
}
3922+
39083923
std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
39093924
MacroExpander::substitute_token (
3925+
std::vector<std::unique_ptr<AST::Token>> &macro,
39103926
std::vector<std::unique_ptr<AST::Token>> &input,
3911-
std::map<std::string, MatchedFragment> &fragments,
3912-
std::unique_ptr<AST::Token> &token)
3927+
std::map<std::string, MatchedFragment> &fragments, size_t token_idx)
39133928
{
3929+
auto &token = macro.at (token_idx);
39143930
switch (token->get_id ())
39153931
{
39163932
case IDENTIFIER:
39173933
rust_debug ("expanding metavar");
39183934
return {substitute_metavar (input, fragments, token), 1};
3919-
case LEFT_PAREN:
3920-
rust_debug ("expanding repetition");
3921-
break;
3935+
case LEFT_PAREN: {
3936+
// We need to parse up until the closing delimiter and expand this
3937+
// fragment->n times.
3938+
rust_debug ("expanding repetition");
3939+
std::vector<std::unique_ptr<AST::Token>> repetition_pattern;
3940+
for (size_t rep_idx = token_idx + 1;
3941+
rep_idx < macro.size ()
3942+
&& macro.at (rep_idx)->get_id () != RIGHT_PAREN;
3943+
rep_idx++)
3944+
repetition_pattern.emplace_back (macro.at (rep_idx)->clone_token ());
3945+
3946+
// FIXME: This skips whitespaces... Is that okay??
3947+
// FIXME: Is there any existing parsing function that allows us to parse
3948+
// a macro pattern?
3949+
3950+
// FIXME: Add error handling in the case we haven't found a matching
3951+
// closing delimiter
3952+
3953+
// FIXME: We need to parse the repetition token now
3954+
3955+
return {
3956+
substitute_repetition (input, fragments, repetition_pattern),
3957+
// + 2 for the opening and closing parenthesis which are mandatory
3958+
repetition_pattern.size () + 2};
3959+
}
39223960
// TODO: We need to check if the $ was alone. In that case, do
39233961
// not error out: Simply act as if there was an empty identifier
39243962
// with no associated fragment and paste the dollar sign in the
@@ -3956,10 +3994,9 @@ MacroExpander::substitute_tokens (
39563994
auto &tok = macro.at (i);
39573995
if (tok->get_id () == DOLLAR_SIGN)
39583996
{
3959-
auto &next_tok = macro.at (i + 1);
39603997
// Aaaaah, if only we had C++17 :)
39613998
// auto [expanded, tok_to_skip] = ...
3962-
auto p = substitute_token (input, fragments, next_tok);
3999+
auto p = substitute_token (macro, input, fragments, i + 1);
39634000
auto expanded = std::move (p.first);
39644001
auto tok_to_skip = p.second;
39654002

gcc/rust/expand/rust-macro-expand.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,24 @@ struct MacroExpander
199199
std::map<std::string, MatchedFragment> &fragments,
200200
std::unique_ptr<AST::Token> &metavar);
201201

202+
/**
203+
* Substitute a macro repetition by its given fragments
204+
*
205+
* @param input Tokens given to the transcribing context
206+
* @param fragments Fragments given to the macro substitution
207+
* @param repetition Set of tokens to substitute and replace
208+
*
209+
* @return A vector containing the repeated pattern
210+
*/
211+
static std::vector<std::unique_ptr<AST::Token>>
212+
substitute_repetition (std::vector<std::unique_ptr<AST::Token>> &input,
213+
std::map<std::string, MatchedFragment> &fragments,
214+
std::vector<std::unique_ptr<AST::Token>> &pattern);
215+
202216
/**
203217
* Substitute a given token by its appropriate representation
204218
*
219+
* @param macro Tokens used in the macro declaration
205220
* @param input Tokens given to the transcribing context
206221
* @param fragments Fragments given to the macro substitution
207222
* @param token Current token to try and substitute
@@ -213,9 +228,10 @@ struct MacroExpander
213228
* ahead of the input to avoid mis-substitutions
214229
*/
215230
static std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
216-
substitute_token (std::vector<std::unique_ptr<AST::Token>> &input,
231+
substitute_token (std::vector<std::unique_ptr<AST::Token>> &macro,
232+
std::vector<std::unique_ptr<AST::Token>> &input,
217233
std::map<std::string, MatchedFragment> &fragments,
218-
std::unique_ptr<AST::Token> &token);
234+
size_t token_idx);
219235

220236
static std::vector<std::unique_ptr<AST::Token>>
221237
substitute_tokens (std::vector<std::unique_ptr<AST::Token>> &input,

0 commit comments

Comments
 (0)