aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-02-21 10:48:00 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2022-02-22 12:05:58 +0100
commit143aad62e16ea96e8c562b96857c2497f74ba7c7 (patch)
tree7ed8c0d23acc92be08d775ed9512b848f7f3149b /gcc
parentae1f91a698022a5600a2d54e48fc90895ea834fd (diff)
downloadgcc-143aad62e16ea96e8c562b96857c2497f74ba7c7.zip
gcc-143aad62e16ea96e8c562b96857c2497f74ba7c7.tar.gz
gcc-143aad62e16ea96e8c562b96857c2497f74ba7c7.tar.bz2
substitute_repetition: Add parsing of repetition pattern
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc51
-rw-r--r--gcc/rust/expand/rust-macro-expand.h20
2 files changed, 62 insertions, 9 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 7dc8f88..7aa4289 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -3905,20 +3905,58 @@ MacroExpander::substitute_metavar (
return expanded;
}
+std::vector<std::unique_ptr<AST::Token>>
+MacroExpander::substitute_repetition (
+ std::vector<std::unique_ptr<AST::Token>> &input,
+ std::map<std::string, MatchedFragment> &fragments,
+ std::vector<std::unique_ptr<AST::Token>> &pattern)
+{
+ // If the repetition is not anything we know (ie no declared metavars, or
+ // metavars which aren't present in the fragment), we can just error out. No
+ // need to paste the tokens as if nothing had happened.
+ for (auto &token : pattern)
+ rust_debug ("[repetition pattern]: %s", token->as_string ().c_str ());
+
+ return std::vector<std::unique_ptr<AST::Token>> ();
+}
+
std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
MacroExpander::substitute_token (
+ std::vector<std::unique_ptr<AST::Token>> &macro,
std::vector<std::unique_ptr<AST::Token>> &input,
- std::map<std::string, MatchedFragment> &fragments,
- std::unique_ptr<AST::Token> &token)
+ std::map<std::string, MatchedFragment> &fragments, size_t token_idx)
{
+ auto &token = macro.at (token_idx);
switch (token->get_id ())
{
case IDENTIFIER:
rust_debug ("expanding metavar");
return {substitute_metavar (input, fragments, token), 1};
- case LEFT_PAREN:
- rust_debug ("expanding repetition");
- break;
+ case LEFT_PAREN: {
+ // We need to parse up until the closing delimiter and expand this
+ // fragment->n times.
+ rust_debug ("expanding repetition");
+ std::vector<std::unique_ptr<AST::Token>> repetition_pattern;
+ for (size_t rep_idx = token_idx + 1;
+ rep_idx < macro.size ()
+ && macro.at (rep_idx)->get_id () != RIGHT_PAREN;
+ rep_idx++)
+ repetition_pattern.emplace_back (macro.at (rep_idx)->clone_token ());
+
+ // FIXME: This skips whitespaces... Is that okay??
+ // FIXME: Is there any existing parsing function that allows us to parse
+ // a macro pattern?
+
+ // FIXME: Add error handling in the case we haven't found a matching
+ // closing delimiter
+
+ // FIXME: We need to parse the repetition token now
+
+ return {
+ substitute_repetition (input, fragments, repetition_pattern),
+ // + 2 for the opening and closing parenthesis which are mandatory
+ repetition_pattern.size () + 2};
+ }
// TODO: We need to check if the $ was alone. In that case, do
// not error out: Simply act as if there was an empty identifier
// with no associated fragment and paste the dollar sign in the
@@ -3956,10 +3994,9 @@ MacroExpander::substitute_tokens (
auto &tok = macro.at (i);
if (tok->get_id () == DOLLAR_SIGN)
{
- auto &next_tok = macro.at (i + 1);
// Aaaaah, if only we had C++17 :)
// auto [expanded, tok_to_skip] = ...
- auto p = substitute_token (input, fragments, next_tok);
+ auto p = substitute_token (macro, input, fragments, i + 1);
auto expanded = std::move (p.first);
auto tok_to_skip = p.second;
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index f77acc7..943115d 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -200,8 +200,23 @@ struct MacroExpander
std::unique_ptr<AST::Token> &metavar);
/**
+ * Substitute a macro repetition by its given fragments
+ *
+ * @param input Tokens given to the transcribing context
+ * @param fragments Fragments given to the macro substitution
+ * @param repetition Set of tokens to substitute and replace
+ *
+ * @return A vector containing the repeated pattern
+ */
+ static std::vector<std::unique_ptr<AST::Token>>
+ substitute_repetition (std::vector<std::unique_ptr<AST::Token>> &input,
+ std::map<std::string, MatchedFragment> &fragments,
+ std::vector<std::unique_ptr<AST::Token>> &pattern);
+
+ /**
* Substitute a given token by its appropriate representation
*
+ * @param macro Tokens used in the macro declaration
* @param input Tokens given to the transcribing context
* @param fragments Fragments given to the macro substitution
* @param token Current token to try and substitute
@@ -213,9 +228,10 @@ struct MacroExpander
* ahead of the input to avoid mis-substitutions
*/
static std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
- substitute_token (std::vector<std::unique_ptr<AST::Token>> &input,
+ substitute_token (std::vector<std::unique_ptr<AST::Token>> &macro,
+ std::vector<std::unique_ptr<AST::Token>> &input,
std::map<std::string, MatchedFragment> &fragments,
- std::unique_ptr<AST::Token> &token);
+ size_t token_idx);
static std::vector<std::unique_ptr<AST::Token>>
substitute_tokens (std::vector<std::unique_ptr<AST::Token>> &input,