do: Elaborate on pattern syntax, add binary as operator

This commit is contained in:
2025-09-16 04:18:12 -04:00
parent b6949147c4
commit 7b05da1334
6 changed files with 150 additions and 78 deletions

View File

@@ -42,6 +42,8 @@ pub enum Pat {
Slice(Vec<Pat>),
/// Matches one of the provided alternates
Alt(Vec<Pat>),
/// Matches a typed pattern
Typed(Box<Pat>, Ty),
}
/// The arms of a make expression
@@ -70,7 +72,7 @@ pub enum Ty {
/// `[Ty]`
Slice(Box<Ty>),
/// `[Ty; _]`
Array(Box<Ty>, usize),
Array(Box<Ty>, Box<Expr>),
/// `[Rety, ..Args]`
Fn(Vec<Ty>),
}
@@ -113,12 +115,21 @@ impl<A: Annotation> Expr<A> {
| Self::Op(Op::Deref, _)
)
}
#[allow(clippy::type_complexity)]
pub fn as_slice(&self) -> Option<(Op, &[Anno<Expr<A>, A>])> {
match self {
Expr::Op(op, args) => Some((*op, args.as_slice())),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Op {
// -- true operators
Do, // Expr ; Expr
As, // Expr as Expr
Macro, // macro Expr => Expr
Block, // { Expr }
Array, // [ Expr,* ]
@@ -201,13 +212,13 @@ impl<A: Annotation> Display for Expr<A> {
Self::MetId(id) => write!(f, "`{id}"),
Self::Lit(literal) => literal.fmt(f),
Self::Let(pat, Some(expr)) => write!(f, "let {pat} = {expr}"),
Self::Let(pat, None) => write!(f, "let {pat}"),
Self::Let(pat, None) => write!(f, "let ({pat})"),
Self::Const(pat, expr) => write!(f, "const {pat} = {expr}"),
Self::Make(expr, make_arms) => {
f.delimit(fmt!("({expr} {{"), "})").list(make_arms, ", ")
}
Self::Match(expr, match_arms) => f
.delimit_indented(fmt!("match {expr} {{\n"), "}")
.delimit_indented(fmt!("match {expr} {{"), "}")
.list_wrap("\n", match_arms, ",\n", ",\n"),
Self::Fn(pat, expr) => write!(f, "fn {pat} {expr}"),
@@ -246,6 +257,7 @@ impl Display for Op {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Op::Do => "; ".fmt(f),
Op::As => " as ".fmt(f),
Op::Macro => "macro ".fmt(f),
Op::Block => "{}".fmt(f),
Op::Array => "[]".fmt(f),
@@ -261,8 +273,8 @@ impl Display for Op {
Op::Return => "return ".fmt(f),
Op::Dot => ".".fmt(f),
Op::Path => "::".fmt(f),
Op::RangeEx => " .. ".fmt(f),
Op::RangeIn => " ..= ".fmt(f),
Op::RangeEx => "..".fmt(f),
Op::RangeIn => "..=".fmt(f),
Op::Neg => "-".fmt(f),
Op::Not => "!".fmt(f),
Op::Identity => "!!".fmt(f),
@@ -320,6 +332,25 @@ impl Display for Pat {
Self::Tuple(pats) => f.delimit("(", ")").list(pats, ", "),
Self::Slice(pats) => f.delimit("[", "]").list(pats, ", "),
Self::Alt(pats) => f.delimit("<", ">").list(pats, " | "),
Self::Typed(pat, ty) => write!(f, "{pat}: {ty}"),
}
}
}
impl Display for Ty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Infer => "_".fmt(f),
Self::Named(name) => name.fmt(f),
Self::Tuple(items) => f.delimit('(', ')').list(items, ", "),
Self::Slice(ty) => write!(f, "[{ty}]"),
Self::Array(ty, n) => write!(f, "[{ty}; {n}]"),
Self::Fn(items) => match items.as_slice() {
[] => write!(f, "fn ()"),
[rety, args @ ..] => f
.delimit(fmt!("fn ("), fmt!(") -> {rety}"))
.list(args, ", "),
},
}
}
}