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
{
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
}
};
+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 */
// 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 ())
{}
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)
{}
{
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;
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;
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-expr.h"
+#include "rust-system.h"
namespace Rust {
namespace HIR {
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 ());
}
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 (
}
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
= 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 (
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
{
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 (
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),
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 ();
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