ast: fn main, structification
parser: unified post/infix, context-full grammar repl: modes
This commit is contained in:
76
src/ast.rs
76
src/ast.rs
@@ -58,7 +58,7 @@ pub struct MakeArm<A: Annotation = Span>(pub String, pub Option<Anno<Expr<A>, A>
|
||||
/// (Pat |)* Pat? => Expr
|
||||
/// ```
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MatchArm<A: Annotation = Span>(pub Vec<Pat>, pub Anno<Expr<A>, A>);
|
||||
pub struct MatchArm<A: Annotation = Span>(pub Pat, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// In-universe types
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -77,6 +77,22 @@ pub enum Ty {
|
||||
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)?`
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Let<A: Annotation = Span>(pub Pat, pub Option<Anno<Expr<A>, A>>);
|
||||
|
||||
/// `match Expr { MatchArm,* }``
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match<A: Annotation = Span>(pub Anno<Expr<A>, A>, pub Vec<MatchArm<A>>);
|
||||
|
||||
/// Expressions: The beating heart of Dough
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Expr<A: Annotation = Span> {
|
||||
@@ -87,15 +103,15 @@ pub enum Expr<A: Annotation = Span> {
|
||||
/// A literal bool, string, char, or int
|
||||
Lit(Literal),
|
||||
/// let Pat<NoTopAlt> = expr
|
||||
Let(Pat, Option<Box<Anno<Self, A>>>),
|
||||
Let(Box<Let<A>>),
|
||||
/// `const Pat<NoTopAlt> (= Expr)?` (Basically let rec)
|
||||
Const(Pat, Box<Anno<Self, A>>),
|
||||
/// `| Pat<Tuple> | Expr` | `|| Expr` | `fn (Pat,*) Expr`
|
||||
Fn(Pat, Box<Anno<Self, A>>),
|
||||
Const(Box<Const<A>>),
|
||||
/// `| Pat<Tuple> | Expr` | `|| Expr` | `fn Ident? (Pat,*) Expr`
|
||||
Fn(Box<Fn<A>>),
|
||||
/// Expr { (Ident (: Expr)?),* }
|
||||
Make(Box<Anno<Self, A>>, Vec<MakeArm<A>>),
|
||||
/// match Expr { MatchArm,* }
|
||||
Match(Box<Anno<Self, A>>, Vec<MatchArm<A>>),
|
||||
Match(Box<Match<A>>),
|
||||
/// Op Expr | Expr Op | Expr (Op Expr)+ | Op Expr Expr else Expr
|
||||
Op(Op, Vec<Anno<Self, A>>),
|
||||
}
|
||||
@@ -205,22 +221,52 @@ 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 {
|
||||
Self(Some(name), pat, expr) => write!(f, "fn {name} {pat} {expr}"),
|
||||
Self(None, pat, expr) => write!(f, "|{pat}| {expr}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Let<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self(pat, Some(expr)) => write!(f, "let {pat} = {expr}"),
|
||||
Self(pat, None) => write!(f, "let ({pat})"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Match<A> {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Expr<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Id(id) => id.fmt(f),
|
||||
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::Const(pat, expr) => write!(f, "const {pat} = {expr}"),
|
||||
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::Match(expr, match_arms) => f
|
||||
.delimit_indented(fmt!("match {expr} {{"), "}")
|
||||
.list_wrap("\n", match_arms, ",\n", ",\n"),
|
||||
Self::Fn(pat, expr) => write!(f, "fn {pat} {expr}"),
|
||||
Self::Match(v) => v.fmt(f),
|
||||
Self::Fn(v) => v.fmt(f),
|
||||
|
||||
Self::Op(op @ (Op::If | Op::While), exprs) => match exprs.as_slice() {
|
||||
[cond, pass, fail] => write!(f, "{op}{cond} {pass} else {fail}"),
|
||||
@@ -315,8 +361,8 @@ 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(pats, expr) = self;
|
||||
f.delimit("", fmt!(" => {expr}")).list(pats, " | ")
|
||||
let Self(pat, expr) = self;
|
||||
write!(f, "{pat} => {expr}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user