diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-02-21 10:48:00 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-02-22 12:05:58 +0100 |
commit | 143aad62e16ea96e8c562b96857c2497f74ba7c7 (patch) | |
tree | 7ed8c0d23acc92be08d775ed9512b848f7f3149b /gcc | |
parent | ae1f91a698022a5600a2d54e48fc90895ea834fd (diff) | |
download | gcc-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.cc | 51 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.h | 20 |
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>> ¯o, 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>> ¯o, + 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, |