aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2024-05-21 17:45:34 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-17 16:35:34 +0100
commitcc7ec3925c3371deca5fa891e0a7a82950956c54 (patch)
treecac2e8fa3678325493ca7c1d9fc21550edd9de4a /gcc
parentea32c9b17fa6485a0a53f12984a976650725a48e (diff)
downloadgcc-cc7ec3925c3371deca5fa891e0a7a82950956c54.zip
gcc-cc7ec3925c3371deca5fa891e0a7a82950956c54.tar.gz
gcc-cc7ec3925c3371deca5fa891e0a7a82950956c54.tar.bz2
gccrs: Parse exclusive range pattern
Exclusive range pattern were not handled by the parser as this an experimental feature. gcc/rust/ChangeLog: * ast/rust-pattern.cc (tokenid_to_rangekind): Add a new function to get a range kind from the current token type. (RangePattern::as_string): Change the string representation for range pattern in order to handle excluded ranges. * ast/rust-pattern.h (enum class): Add new enum class to differentiate range kinds. (tokenid_to_rangekind): New prototype for a function that converts a token id to it's corresponding range kind. (class RangePattern): Change the class to accept a range kind instead of an ellipsis boolean. * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::visit): Abort when an excluded pattern has been found as we do not handle their lowering yet. * parse/rust-parse-impl.h (Parser::parse_literal_or_range_pattern): Parse excluded range patterns. (Parser::parse_pattern_no_alt): Likewise. (Parser::parse_ident_leading_pattern): Likewise. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-pattern.cc31
-rw-r--r--gcc/rust/ast/rust-pattern.h32
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc3
-rw-r--r--gcc/rust/parse/rust-parse-impl.h33
4 files changed, 72 insertions, 27 deletions
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index 85b3f5f..98fd8e5 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -30,6 +30,22 @@ along with GCC; see the file COPYING3. If not see
namespace Rust {
namespace AST {
+RangeKind
+tokenid_to_rangekind (TokenId id)
+{
+ switch (id)
+ {
+ case DOT_DOT_EQ:
+ return RangeKind::INCLUDED;
+ case ELLIPSIS:
+ return RangeKind::ELLIPSIS;
+ case DOT_DOT:
+ return RangeKind::EXCLUDED;
+ default:
+ rust_unreachable ();
+ }
+}
+
std::string
LiteralPattern::as_string () const
{
@@ -73,10 +89,17 @@ std::string
RangePattern::as_string () const
{
// TODO: maybe rewrite to work with non-linearisable bounds
- if (has_ellipsis_syntax)
- return lower->as_string () + "..." + upper->as_string ();
- else
- return lower->as_string () + "..=" + upper->as_string ();
+ switch (range_kind)
+ {
+ case RangeKind::EXCLUDED:
+ return lower->as_string () + ".." + upper->as_string ();
+ case RangeKind::INCLUDED:
+ return lower->as_string () + "..=" + upper->as_string ();
+ case RangeKind::ELLIPSIS:
+ return lower->as_string () + "..." + upper->as_string ();
+ default:
+ rust_unreachable ();
+ }
}
std::string
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 7cb09a5..383a5ee 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -368,13 +368,22 @@ protected:
}
};
+enum class RangeKind
+{
+ INCLUDED,
+ ELLIPSIS,
+ EXCLUDED,
+};
+
+RangeKind
+tokenid_to_rangekind (TokenId id);
// AST node for matching within a certain range (range pattern)
class RangePattern : public Pattern
{
std::unique_ptr<RangePatternBound> lower;
std::unique_ptr<RangePatternBound> upper;
- bool has_ellipsis_syntax;
+ RangeKind range_kind;
/* location only stored to avoid a dereference - lower pattern should give
* correct location so maybe change in future */
@@ -386,10 +395,10 @@ public:
// Constructor
RangePattern (std::unique_ptr<RangePatternBound> lower,
- std::unique_ptr<RangePatternBound> upper, location_t locus,
- bool has_ellipsis_syntax = false)
+ std::unique_ptr<RangePatternBound> upper, RangeKind range_kind,
+ location_t locus)
: lower (std::move (lower)), upper (std::move (upper)),
- has_ellipsis_syntax (has_ellipsis_syntax), locus (locus),
+ range_kind (range_kind), locus (locus),
node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
@@ -397,7 +406,7 @@ public:
RangePattern (RangePattern const &other)
: lower (other.lower->clone_range_pattern_bound ()),
upper (other.upper->clone_range_pattern_bound ()),
- has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus),
+ range_kind (other.range_kind), locus (other.locus),
node_id (other.node_id)
{}
@@ -406,7 +415,7 @@ public:
{
lower = other.lower->clone_range_pattern_bound ();
upper = other.upper->clone_range_pattern_bound ();
- has_ellipsis_syntax = other.has_ellipsis_syntax;
+ range_kind = other.range_kind;
locus = other.locus;
node_id = other.node_id;
@@ -419,11 +428,16 @@ public:
location_t get_locus () const override final { return locus; }
- bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; }
+ bool get_has_ellipsis_syntax () const
+ {
+ return range_kind == RangeKind::ELLIPSIS;
+ }
+
+ RangeKind get_range_kind () const { return range_kind; }
- bool get_has_lower_bound () { return lower != nullptr; }
+ bool get_has_lower_bound () const { return lower != nullptr; }
- bool get_has_upper_bound () { return upper != nullptr; }
+ bool get_has_upper_bound () const { return upper != nullptr; }
void accept_vis (ASTVisitor &vis) override;
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index b64cf3a..b7a4c56 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -18,6 +18,7 @@
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-expr.h"
+#include "rust-system.h"
namespace Rust {
namespace HIR {
@@ -253,6 +254,8 @@ ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
void
ASTLoweringPattern::visit (AST::RangePattern &pattern)
{
+ if (pattern.get_range_kind () == AST::RangeKind::EXCLUDED)
+ rust_unreachable (); // Not supported yet
auto upper_bound = lower_range_pattern_bound (pattern.get_upper_bound ());
auto lower_bound = lower_range_pattern_bound (pattern.get_lower_bound ());
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 91f09f6..cabfb5b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -10261,8 +10261,10 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
}
const_TokenPtr next = lexer.peek_token ();
- if (next->get_id () == DOT_DOT_EQ || next->get_id () == ELLIPSIS)
+ if (next->get_id () == DOT_DOT_EQ || next->get_id () == ELLIPSIS
+ || next->get_id () == DOT_DOT)
{
+ AST::RangeKind kind = AST::tokenid_to_rangekind (next->get_id ());
// range pattern
lexer.skip_token ();
std::unique_ptr<AST::RangePatternBound> lower (
@@ -10283,7 +10285,7 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
}
return std::unique_ptr<AST::RangePattern> (
- new AST::RangePattern (std::move (lower), std::move (upper),
+ new AST::RangePattern (std::move (lower), std::move (upper), kind,
range_lower->get_locus ()));
}
else
@@ -10532,11 +10534,12 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
= parse_qualified_path_in_expression ();
if (lexer.peek_token ()->get_id () == DOT_DOT_EQ
- || lexer.peek_token ()->get_id () == ELLIPSIS)
+ || lexer.peek_token ()->get_id () == ELLIPSIS
+ || lexer.peek_token ()->get_id () == DOT_DOT)
{
// qualified range pattern bound, so parse rest of range pattern
- bool has_ellipsis_syntax
- = lexer.peek_token ()->get_id () == ELLIPSIS;
+ AST::RangeKind kind
+ = AST::tokenid_to_rangekind (lexer.peek_token ()->get_id ());
lexer.skip_token ();
std::unique_ptr<AST::RangePatternBoundQualPath> lower_bound (
@@ -10546,8 +10549,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
return std::unique_ptr<AST::RangePattern> (
new AST::RangePattern (std::move (lower_bound),
- std::move (upper_bound), t->get_locus (),
- has_ellipsis_syntax));
+ std::move (upper_bound), kind,
+ t->get_locus ()));
}
else
{
@@ -10569,10 +10572,10 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
switch (next->get_id ())
{
case DOT_DOT_EQ:
+ case DOT_DOT:
case ELLIPSIS: {
// qualified range pattern bound, so parse rest of range pattern
- bool has_ellipsis_syntax
- = lexer.peek_token ()->get_id () == ELLIPSIS;
+ AST::RangeKind kind = AST::tokenid_to_rangekind (next->get_id ());
lexer.skip_token ();
std::unique_ptr<AST::RangePatternBoundPath> lower_bound (
@@ -10582,8 +10585,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
return std::unique_ptr<AST::RangePattern> (
new AST::RangePattern (std::move (lower_bound),
- std::move (upper_bound),
- UNKNOWN_LOCATION, has_ellipsis_syntax));
+ std::move (upper_bound), kind,
+ UNKNOWN_LOCATION));
}
case EXCLAM:
return parse_macro_invocation_partial (std::move (path),
@@ -11093,9 +11096,11 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
std::move (elems)));
}
case DOT_DOT_EQ:
+ case DOT_DOT:
case ELLIPSIS: {
// range
- bool has_ellipsis_syntax = lexer.peek_token ()->get_id () == ELLIPSIS;
+ AST::RangeKind kind
+ = AST::tokenid_to_rangekind (lexer.peek_token ()->get_id ());
lexer.skip_token ();
@@ -11106,8 +11111,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
return std::unique_ptr<AST::RangePattern> (
new AST::RangePattern (std::move (lower_bound),
- std::move (upper_bound), UNKNOWN_LOCATION,
- has_ellipsis_syntax));
+ std::move (upper_bound), kind,
+ UNKNOWN_LOCATION));
}
case PATTERN_BIND: {
// only allow on single-segment paths