parser/pat: allow ranges in function type annotations
This commit is contained in:
@@ -18,26 +18,36 @@ pub enum Prec {
|
||||
Tuple,
|
||||
/// Type annotation: `Pat : Pat`
|
||||
Typed,
|
||||
/// Range pattern: `Pat .. Pat`, `Pat ..= Pat`
|
||||
Range,
|
||||
/// Function pattern: `Pat -> Pat`
|
||||
Fn,
|
||||
/// Range pattern: `Pat .. Pat`, `Pat ..= Pat`
|
||||
Range,
|
||||
/// The highest precedence
|
||||
Max,
|
||||
}
|
||||
|
||||
macro_rules! intify {
|
||||
($enum:ident($value:path) = $min:ident, $max: ident, $($variant:ident),*$(,)?) => {
|
||||
#[expect(non_upper_case_globals)] {
|
||||
const $min: u32 = $enum::$min as _;
|
||||
const $max: u32 = $enum::$max as _;
|
||||
$(const $variant: u32 = $enum::$variant as _;)*
|
||||
match $value {
|
||||
..=$min => $enum::$min,
|
||||
$($variant => $enum::$variant,)*
|
||||
$max.. => $enum::$max,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
impl Prec {
|
||||
const fn from_int(value: u32) -> Self {
|
||||
intify! {Prec(value) = Min, Max, Alt, Tuple, Typed, Fn, Range}
|
||||
}
|
||||
|
||||
/// Returns the level of precedence higher than this one
|
||||
const fn next(self) -> Self {
|
||||
match self {
|
||||
Self::Min => Self::Alt,
|
||||
Self::Alt => Self::Tuple,
|
||||
Self::Tuple => Self::Typed,
|
||||
Self::Typed => Self::Range,
|
||||
Self::Range => Self::Fn,
|
||||
Self::Fn => Self::Max,
|
||||
Self::Max => Self::Max,
|
||||
}
|
||||
Self::from_int(self as u32 + 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,12 +55,12 @@ impl Prec {
|
||||
/// and its [precedence level](Prec)
|
||||
fn from_infix(token: &Token) -> Option<(PatOp, Prec)> {
|
||||
Some(match token.kind {
|
||||
TKind::DotDot => (PatOp::RangeEx, Prec::Range),
|
||||
TKind::DotDotEq => (PatOp::RangeIn, Prec::Range),
|
||||
TKind::Colon => (PatOp::Typed, Prec::Typed),
|
||||
TKind::Comma => (PatOp::Tuple, Prec::Tuple),
|
||||
TKind::Arrow => (PatOp::Fn, Prec::Fn),
|
||||
TKind::Bar => (PatOp::Alt, Prec::Alt),
|
||||
TKind::Colon => (PatOp::Typed, Prec::Typed),
|
||||
TKind::Comma => (PatOp::Tuple, Prec::Tuple),
|
||||
TKind::DotDot => (PatOp::RangeEx, Prec::Range),
|
||||
TKind::DotDotEq => (PatOp::RangeIn, Prec::Range),
|
||||
_ => None?,
|
||||
})
|
||||
}
|
||||
@@ -135,7 +145,7 @@ impl<'t> Parse<'t> for Pat {
|
||||
{
|
||||
let kind = tok.kind;
|
||||
head = match op {
|
||||
PatOp::Typed => Pat::Op(PatOp::Typed, vec![head, p.consume().parse(Prec::Max)?]),
|
||||
PatOp::Typed => Pat::Op(PatOp::Typed, vec![head, p.consume().parse(prec.next())?]),
|
||||
PatOp::Fn => Pat::Op(PatOp::Fn, vec![head, p.consume().parse(Prec::Fn.next())?]),
|
||||
op @ (PatOp::RangeEx | PatOp::RangeIn) => Pat::Op(
|
||||
op,
|
||||
|
||||
Reference in New Issue
Block a user