AST: merge let, const, static, match_arm into one binder
This commit is contained in:
89
src/ast.rs
89
src/ast.rs
@@ -111,14 +111,19 @@ pub enum Ty {
|
||||
/// let Pat (= Expr)?
|
||||
/// ``````
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Let<A: Annotation = Span>(pub Pat, pub Vec<Anno<Expr<A>, A>>);
|
||||
pub struct Let<A: Annotation = Span>(pub LetKind, pub Pat, pub Vec<Anno<Expr<A>, A>>);
|
||||
|
||||
/// A `const` binding (which defines its name before executing)
|
||||
/// ```ignore
|
||||
/// const Pat = Expr
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Const<A: Annotation = Span>(pub Pat, pub Anno<Expr<A>, A>);
|
||||
pub enum LetKind {
|
||||
/// A `let Pat (= Expr (else Expr)?)?` binding
|
||||
Let,
|
||||
/// A `const Pat = Expr` binding
|
||||
Const,
|
||||
/// A `static Pat = Expr` binding
|
||||
Static,
|
||||
/// A `Pat => Expr` binding
|
||||
Match,
|
||||
}
|
||||
|
||||
/// A function definition
|
||||
/// ```ignore
|
||||
@@ -127,20 +132,6 @@ pub struct Const<A: Annotation = Span>(pub Pat, pub Anno<Expr<A>, A>);
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Fn<A: Annotation = Span>(pub Option<String>, pub Pat, pub Ty, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// A match expression
|
||||
/// ```ignore
|
||||
/// match Expr { MatchArm,* }
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match<A: Annotation = Span>(pub Anno<Expr<A>, A>, pub Vec<MatchArm<A>>);
|
||||
|
||||
/// The "arms" of a match expression
|
||||
/// ```ignore
|
||||
/// Pat => Expr
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MatchArm<A: Annotation = Span>(pub Pat, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// A make (constructor) expression
|
||||
/// ```ignore
|
||||
/// Expr { (Ident (: Expr)?),* }
|
||||
@@ -185,16 +176,12 @@ pub enum Expr<A: Annotation = Span> {
|
||||
Lit(Literal),
|
||||
/// let Pat<NoTopAlt> = expr
|
||||
Let(Box<Let<A>>),
|
||||
/// `const Pat<NoTopAlt> (= Expr)?` (Basically let rec)
|
||||
Const(Box<Const<A>>),
|
||||
/// (struct | enum | type) Pat<NoTopAlt>
|
||||
Struct(Box<Typedef>),
|
||||
/// `| Pat<Tuple> | Expr` | `|| Expr` | `fn Ident? (Pat,*) Expr`
|
||||
Fn(Box<Fn<A>>),
|
||||
/// Expr { (Ident (: Expr)?),* }
|
||||
Make(Box<Make<A>>),
|
||||
/// match Expr { MatchArm,* }
|
||||
Match(Box<Match<A>>),
|
||||
/// mod Ty Expr
|
||||
Mod(Box<Mod<A>>),
|
||||
/// Op Expr | Expr Op | Expr (Op Expr)+ | Op Expr Expr else Expr
|
||||
@@ -259,6 +246,7 @@ pub enum Op {
|
||||
|
||||
Pub, // pub Expr
|
||||
Loop, // loop Expr
|
||||
Match, // match Expr { <Let(Match, ..)>,* }
|
||||
If, // if Expr Expr (else Expr)?
|
||||
While, // while Expr Expr (else Expr)?
|
||||
Break, // break Expr
|
||||
@@ -339,13 +327,6 @@ impl<T: Display + Annotation, A: Annotation> Display for Anno<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Const<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(pat, expr) = self;
|
||||
write!(f, "const {pat} = {expr}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Fn<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@@ -357,21 +338,29 @@ impl<A: Annotation> Display for Fn<A> {
|
||||
|
||||
impl<A: Annotation> Display for Let<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(pat, exprs) = self;
|
||||
let Self(op, pat, exprs) = self;
|
||||
|
||||
if let LetKind::Match = op {
|
||||
return f.delimit(fmt!("{pat} => "), "").list(exprs, ",!? ");
|
||||
}
|
||||
|
||||
match exprs.as_slice() {
|
||||
[] => write!(f, "let {pat}"),
|
||||
[value] => write!(f, "let {pat} = {value}"),
|
||||
[value, fail] => write!(f, "let {pat} = {value} else {fail}"),
|
||||
other => f.delimit(fmt!("let! {pat} ("), ")").list(other, ", "),
|
||||
[] => write!(f, "{op} {pat}"),
|
||||
[value] => write!(f, "{op} {pat} = {value}"),
|
||||
[value, fail] => write!(f, "{op} {pat} = {value} else {fail}"),
|
||||
other => f.delimit(fmt!("{op}?! {pat} ("), ")").list(other, ", "),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Match<A> {
|
||||
impl Display for LetKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(expr, match_arms) = self;
|
||||
f.delimit_indented(fmt!("match {expr} {{"), "}")
|
||||
.list_wrap("\n", match_arms, ",\n", ",\n")
|
||||
f.write_str(match self {
|
||||
Self::Let => "let",
|
||||
Self::Const => "const",
|
||||
Self::Static => "static",
|
||||
Self::Match => "| ",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,10 +405,8 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
Self::MetId(id) => write!(f, "`{id}"),
|
||||
Self::Lit(literal) => literal.fmt(f),
|
||||
Self::Let(v) => v.fmt(f),
|
||||
Self::Const(v) => v.fmt(f),
|
||||
Self::Struct(v) => v.fmt(f),
|
||||
Self::Make(v) => v.fmt(f),
|
||||
Self::Match(v) => v.fmt(f),
|
||||
Self::Mod(v) => v.fmt(f),
|
||||
Self::Fn(v) => v.fmt(f),
|
||||
|
||||
@@ -430,6 +417,12 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
[cond, pass, fail] => write!(f, "{op}{cond} {pass} else {fail}"),
|
||||
other => f.delimit(fmt!("({op}, "), ")").list(other, ", "),
|
||||
},
|
||||
Self::Op(op @ Op::Match, exprs) => match exprs.as_slice() {
|
||||
[scrutinee, arms @ ..] => f
|
||||
.delimit_indented(fmt!("{op}{scrutinee} {{"), "}")
|
||||
.list_wrap("\n", arms, ",\n", ",\n"),
|
||||
[] => write!(f, "{op} () {{}}"), // invalid, but whatever.
|
||||
},
|
||||
Self::Op(Op::Array, exprs) => f.delimit("[", "]").list(exprs, ", "),
|
||||
Self::Op(Op::ArRep, exprs) => f.delimit("[", "]").list(exprs, "; "),
|
||||
Self::Op(Op::Block, exprs) => f
|
||||
@@ -479,6 +472,7 @@ impl Display for Op {
|
||||
Op::Call => "",
|
||||
Op::Pub => "pub ",
|
||||
Op::Loop => "loop ",
|
||||
Op::Match => "match ",
|
||||
Op::If => "if ",
|
||||
Op::While => "while ",
|
||||
Op::Break => "break ",
|
||||
@@ -534,13 +528,6 @@ impl<A: Annotation> Display for MakeArm<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for MatchArm<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(pat, expr) = self;
|
||||
write!(f, "{pat} => {expr}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Pat {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@@ -550,7 +537,9 @@ impl Display for Pat {
|
||||
Self::Name(name) => name.fmt(f),
|
||||
Self::Path(path) => path.fmt(f),
|
||||
Self::Struct(name, bind) => match bind.as_ref() {
|
||||
Pat::Op(PatOp::Tuple, parts) => f.delimit(fmt!("{name} {{ "), " }").list(parts, ", "),
|
||||
Pat::Op(PatOp::Tuple, parts) => {
|
||||
f.delimit(fmt!("{name} {{ "), " }").list(parts, ", ")
|
||||
}
|
||||
other => write!(f, "{name} {{ {other} }}"),
|
||||
},
|
||||
Self::TupStruct(name, bind) => write!(f, "{name} {bind}"),
|
||||
|
||||
Reference in New Issue
Block a user