ast: pub, mod, and Ty::Fn parsing
This commit is contained in:
108
src/ast.rs
108
src/ast.rs
@@ -46,20 +46,6 @@ pub enum Pat {
|
||||
Typed(Box<Pat>, Ty),
|
||||
}
|
||||
|
||||
/// The arms of a make expression
|
||||
/// ```ignore
|
||||
/// Identifier (':' Expr)?
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MakeArm<A: Annotation = Span>(pub String, pub Option<Anno<Expr<A>, A>>);
|
||||
|
||||
/// The arms of a match expression
|
||||
/// ```ignore
|
||||
/// (Pat |)* Pat? => Expr
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MatchArm<A: Annotation = Span>(pub Pat, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// In-universe types
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Ty {
|
||||
@@ -73,26 +59,66 @@ pub enum Ty {
|
||||
Slice(Box<Ty>),
|
||||
/// `[Ty; _]`
|
||||
Array(Box<Ty>, Box<Expr>),
|
||||
/// `[Rety, ..Args]`
|
||||
/// `[..Args, Rety]`
|
||||
Fn(Vec<Ty>),
|
||||
}
|
||||
|
||||
/// A `const` binding (which defines its name before executing)
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Const<A: Annotation = Span>(pub Pat, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// A function definition `fn Ident? (Pat,*) Expr`
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Fn<A: Annotation = Span>(pub Option<String>, pub Pat, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// A `let` binding: `let Pat (= Expr)?`
|
||||
/// A `let` binding
|
||||
/// ```ignore
|
||||
/// let Pat (= Expr)?
|
||||
/// ``````
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Let<A: Annotation = Span>(pub Pat, pub Option<Anno<Expr<A>, A>>);
|
||||
|
||||
/// `match Expr { MatchArm,* }``
|
||||
/// 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>);
|
||||
|
||||
/// A function definition
|
||||
/// ```ignore
|
||||
/// fn Ident? (Pat) Expr
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Fn<A: Annotation = Span>(pub Option<String>, pub Pat, 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)?),* }
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Make<A: Annotation = Span>(pub Box<Anno<Expr<A>, A>>, pub Vec<MakeArm<A>>);
|
||||
|
||||
/// A single "arm" of a make expression
|
||||
/// ```ignore
|
||||
/// Identifier (':' Expr)?
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MakeArm<A: Annotation = Span>(pub String, pub Option<Anno<Expr<A>, A>>);
|
||||
|
||||
/// An inline namespace
|
||||
/// ```ignore
|
||||
/// mod Ty Expr
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Mod<A: Annotation = Span>(pub Ty, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// Expressions: The beating heart of Dough
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Expr<A: Annotation = Span> {
|
||||
@@ -109,9 +135,11 @@ pub enum Expr<A: Annotation = Span> {
|
||||
/// `| Pat<Tuple> | Expr` | `|| Expr` | `fn Ident? (Pat,*) Expr`
|
||||
Fn(Box<Fn<A>>),
|
||||
/// Expr { (Ident (: Expr)?),* }
|
||||
Make(Box<Anno<Self, A>>, Vec<MakeArm<A>>),
|
||||
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
|
||||
Op(Op, Vec<Anno<Self, A>>),
|
||||
}
|
||||
@@ -149,6 +177,7 @@ pub enum Op {
|
||||
Macro, // macro Expr => Expr
|
||||
Block, // { Expr }
|
||||
Array, // [ Expr,* ]
|
||||
ArRep, // [ Expr ; Expr ]
|
||||
Group, // ( Expr ,?)
|
||||
Tuple, // Expr (, Expr)*
|
||||
|
||||
@@ -156,6 +185,7 @@ pub enum Op {
|
||||
Index, // Expr [ Expr,* ]
|
||||
Call, // Expr ( Expr,* )
|
||||
|
||||
Pub, // pub Expr
|
||||
Loop, // loop Expr
|
||||
If, // if Expr Expr (else Expr)?
|
||||
While, // while Expr Expr (else Expr)?
|
||||
@@ -254,6 +284,20 @@ impl<A: Annotation> Display for Match<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Make<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(expr, make_arms) = self;
|
||||
f.delimit(fmt!("({expr} {{"), "})").list(make_arms, ", ")
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Mod<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(ty, expr) = self;
|
||||
write!(f, "mod {ty} {expr}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Expr<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@@ -262,10 +306,9 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
Self::Lit(literal) => literal.fmt(f),
|
||||
Self::Let(v) => v.fmt(f),
|
||||
Self::Const(v) => v.fmt(f),
|
||||
Self::Make(expr, make_arms) => {
|
||||
f.delimit(fmt!("({expr} {{"), "})").list(make_arms, ", ")
|
||||
}
|
||||
Self::Make(v) => v.fmt(f),
|
||||
Self::Match(v) => v.fmt(f),
|
||||
Self::Mod(v) => v.fmt(f),
|
||||
Self::Fn(v) => v.fmt(f),
|
||||
|
||||
Self::Op(op @ (Op::If | Op::While), exprs) => match exprs.as_slice() {
|
||||
@@ -273,6 +316,7 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
other => f.delimit(fmt!("({op}, "), ")").list(other, ", "),
|
||||
},
|
||||
Self::Op(Op::Array, exprs) => f.delimit("[", "]").list(exprs, ", "),
|
||||
Self::Op(Op::ArRep, exprs) => f.delimit("[", "]").list(exprs, "; "),
|
||||
Self::Op(Op::Block, exprs) => f
|
||||
.delimit_indented("{", "}")
|
||||
.list_wrap("\n", exprs, "\n", "\n"),
|
||||
@@ -292,7 +336,7 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
Self::Op(op @ Op::Macro, exprs) => f.delimit(op, "").list(exprs, " => "),
|
||||
Self::Op(op @ Op::Try, exprs) => f.delimit("(", fmt!("){op}")).list(exprs, ", "),
|
||||
Self::Op(op, exprs) => match exprs.as_slice() {
|
||||
[one] => write!(f, "{op}({one})"),
|
||||
[one] => write!(f, "{op}{one}"),
|
||||
many => f.delimit("(", ")").list(many, op),
|
||||
},
|
||||
}
|
||||
@@ -307,11 +351,13 @@ impl Display for Op {
|
||||
Op::Macro => "macro ".fmt(f),
|
||||
Op::Block => "{}".fmt(f),
|
||||
Op::Array => "[]".fmt(f),
|
||||
Op::ArRep => "[;]".fmt(f),
|
||||
Op::Group => "()".fmt(f),
|
||||
Op::Tuple => "()".fmt(f),
|
||||
Op::Try => "?".fmt(f),
|
||||
Op::Index => "".fmt(f),
|
||||
Op::Call => "".fmt(f),
|
||||
Op::Pub => "pub ".fmt(f),
|
||||
Op::Loop => "loop ".fmt(f),
|
||||
Op::If => "if ".fmt(f),
|
||||
Op::While => "while ".fmt(f),
|
||||
@@ -393,7 +439,7 @@ impl Display for Ty {
|
||||
Self::Array(ty, n) => write!(f, "[{ty}; {n}]"),
|
||||
Self::Fn(items) => match items.as_slice() {
|
||||
[] => write!(f, "fn ()"),
|
||||
[rety, args @ ..] => f
|
||||
[args @ .., rety] => f
|
||||
.delimit(fmt!("fn ("), fmt!(") -> {rety}"))
|
||||
.list(args, ", "),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user