conlang: Introduce ..rest Patterns, refactor Ranges
This commit is contained in:
@@ -413,6 +413,7 @@ pub struct Let {
|
||||
pub enum Pattern {
|
||||
Name(Sym),
|
||||
Literal(Literal),
|
||||
Rest(Option<Box<Pattern>>),
|
||||
Ref(Mutability, Box<Pattern>),
|
||||
Tuple(Vec<Pattern>),
|
||||
Array(Vec<Pattern>),
|
||||
@@ -505,6 +506,8 @@ pub enum UnaryKind {
|
||||
Deref,
|
||||
Neg,
|
||||
Not,
|
||||
RangeInc,
|
||||
RangeExc,
|
||||
/// A Loop expression: `loop` [`Block`]
|
||||
Loop,
|
||||
/// Unused
|
||||
|
||||
@@ -463,6 +463,8 @@ mod display {
|
||||
match self {
|
||||
Pattern::Name(sym) => sym.fmt(f),
|
||||
Pattern::Literal(literal) => literal.fmt(f),
|
||||
Pattern::Rest(Some(name)) => write!(f, "..{name}"),
|
||||
Pattern::Rest(None) => "..".fmt(f),
|
||||
Pattern::Ref(mutability, pattern) => write!(f, "&{mutability}{pattern}"),
|
||||
Pattern::Tuple(patterns) => separate(patterns, ", ")(f.delimit(INLINE_PARENS)),
|
||||
Pattern::Array(patterns) => separate(patterns, ", ")(f.delimit(INLINE_SQUARE)),
|
||||
@@ -590,6 +592,8 @@ mod display {
|
||||
UnaryKind::Deref => "*",
|
||||
UnaryKind::Neg => "-",
|
||||
UnaryKind::Not => "!",
|
||||
UnaryKind::RangeExc => "..",
|
||||
UnaryKind::RangeInc => "..=",
|
||||
UnaryKind::At => "@",
|
||||
UnaryKind::Tilde => "~",
|
||||
}
|
||||
@@ -894,6 +898,9 @@ mod convert {
|
||||
};
|
||||
Pattern::TupleStruct(path, args)
|
||||
}
|
||||
ExprKind::Unary(Unary { kind: UnaryKind::RangeExc, tail }) => {
|
||||
Pattern::Rest(Some(Pattern::try_from(*tail)?.into()))
|
||||
}
|
||||
ExprKind::Structor(Structor { to, init }) => {
|
||||
let fields = init
|
||||
.into_iter()
|
||||
@@ -934,9 +941,9 @@ mod path {
|
||||
}
|
||||
|
||||
/// Checks whether this path ends in the given [Sym]
|
||||
pub fn ends_with(&self, name: &Sym) -> bool {
|
||||
pub fn ends_with(&self, name: &str) -> bool {
|
||||
match self.parts.as_slice() {
|
||||
[.., PathPart::Ident(last)] => name == last,
|
||||
[.., PathPart::Ident(last)] => name == &**last,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,6 +246,8 @@ pub trait Fold {
|
||||
match p {
|
||||
Pattern::Name(sym) => Pattern::Name(self.fold_sym(sym)),
|
||||
Pattern::Literal(literal) => Pattern::Literal(self.fold_literal(literal)),
|
||||
Pattern::Rest(Some(name)) => Pattern::Rest(Some(self.fold_pattern(*name).into())),
|
||||
Pattern::Rest(None) => Pattern::Rest(None),
|
||||
Pattern::Ref(mutability, pattern) => Pattern::Ref(
|
||||
self.fold_mutability(mutability),
|
||||
Box::new(self.fold_pattern(*pattern)),
|
||||
|
||||
@@ -211,6 +211,8 @@ pub trait Visit<'a>: Sized {
|
||||
match p {
|
||||
Pattern::Name(name) => self.visit_sym(name),
|
||||
Pattern::Literal(literal) => self.visit_literal(literal),
|
||||
Pattern::Rest(Some(name)) => self.visit_pattern(name),
|
||||
Pattern::Rest(None) => {}
|
||||
Pattern::Ref(mutability, pattern) => {
|
||||
self.visit_mutability(mutability);
|
||||
self.visit_pattern(pattern);
|
||||
@@ -247,7 +249,7 @@ pub trait Visit<'a>: Sized {
|
||||
self.visit_pattern(pat);
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
|
||||
|
||||
fn visit_assign(&mut self, a: &'a Assign) {
|
||||
let Assign { parts } = a;
|
||||
let (head, tail) = parts.as_ref();
|
||||
|
||||
Reference in New Issue
Block a user