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