doughlang: enums, ref patterns, ref types
This commit is contained in:
62
src/ast.rs
62
src/ast.rs
@@ -71,10 +71,14 @@ pub enum Pat {
|
||||
/// Operators on lists of patterns
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum PatOp {
|
||||
/// Matches the dereference of a pointer (`&pat`)
|
||||
Ref,
|
||||
/// Matches a partial decomposition (`..rest`) or upper-bounded range (`..100`)
|
||||
Rest,
|
||||
/// Matches an exclusive bounded range (`0..100`)
|
||||
RangeEx,
|
||||
/// Matches an inclusive bounded range (`0..=100`)
|
||||
RangeIn,
|
||||
/// Matches the elements of a tuple
|
||||
Tuple,
|
||||
/// Matches the elements of a slice or array
|
||||
@@ -90,6 +94,8 @@ pub enum Ty {
|
||||
Infer,
|
||||
/// `(Identifier :: )* Identifier`
|
||||
Named(FqPath),
|
||||
/// `&Ty`
|
||||
Ref(Box<Ty>),
|
||||
/// `(..Tys)`
|
||||
Tuple(Vec<Ty>),
|
||||
/// `[Ty]`
|
||||
@@ -156,9 +162,17 @@ pub struct MakeArm<A: Annotation = Span>(pub String, pub Option<Anno<Expr<A>, A>
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Mod<A: Annotation = Span>(pub Ty, pub Anno<Expr<A>, A>);
|
||||
|
||||
/// The type of type being defined
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum TypedefKind {
|
||||
Alias,
|
||||
Struct,
|
||||
Enum,
|
||||
}
|
||||
|
||||
/// A record-type definition
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Struct(pub Pat);
|
||||
pub struct Typedef(pub TypedefKind, pub Pat);
|
||||
|
||||
/// Expressions: The beating heart of Dough
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -173,8 +187,8 @@ pub enum Expr<A: Annotation = Span> {
|
||||
Let(Box<Let<A>>),
|
||||
/// `const Pat<NoTopAlt> (= Expr)?` (Basically let rec)
|
||||
Const(Box<Const<A>>),
|
||||
/// struct Pat<NoTopAlt>
|
||||
Struct(Box<Struct>),
|
||||
/// (struct | enum | type) Pat<NoTopAlt>
|
||||
Struct(Box<Typedef>),
|
||||
/// `| Pat<Tuple> | Expr` | `|| Expr` | `fn Ident? (Pat,*) Expr`
|
||||
Fn(Box<Fn<A>>),
|
||||
/// Expr { (Ident (: Expr)?),* }
|
||||
@@ -364,17 +378,22 @@ impl<A: Annotation> Display for Mod<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Struct {
|
||||
impl Display for Typedef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(pat) = self;
|
||||
let Self(kind, pat) = self;
|
||||
let kind = match kind {
|
||||
TypedefKind::Alias => "type",
|
||||
TypedefKind::Struct => "struct",
|
||||
TypedefKind::Enum => "enum",
|
||||
};
|
||||
match pat {
|
||||
Pat::Struct(name, bind) => match bind.as_ref() {
|
||||
Pat::Op(PatOp::Tuple, parts) => f
|
||||
.delimit_indented(fmt!("struct {name} {{"), "}")
|
||||
.delimit_indented(fmt!("{kind} {name} {{"), "}")
|
||||
.list_wrap("\n", parts, ",\n", ",\n"),
|
||||
other => write!(f, "{name} {{ {other} }}"),
|
||||
},
|
||||
_ => write!(f, "struct {pat}"),
|
||||
_ => write!(f, "{kind} {pat}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,25 +529,38 @@ impl Display for Pat {
|
||||
},
|
||||
Self::TupStruct(name, bind) => write!(f, "{name} {bind}"),
|
||||
Self::Typed(pat, ty) => write!(f, "{pat}: {ty}"),
|
||||
Self::Op(PatOp::Rest, pats) => match pats.as_slice() {
|
||||
[] => write!(f, ".."),
|
||||
[rest] => write!(f, "..{rest}"),
|
||||
[from, to] => write!(f, "{from}..{to}"),
|
||||
_ => f.list(pats, "<..>"),
|
||||
},
|
||||
Self::Op(PatOp::RangeEx, pats) => f.delimit("(", ")").list(pats, ".."),
|
||||
Self::Op(PatOp::Tuple, pats) => f.delimit("(", ")").list(pats, ", "),
|
||||
Self::Op(PatOp::Slice, pats) => f.delimit("[", "]").list(pats, ", "),
|
||||
Self::Op(PatOp::Alt, pats) => f.delimit("<", ">").list(pats, " | "),
|
||||
Self::Op(op @ PatOp::Alt, pats) => f.delimit("<", ">").list(pats, op),
|
||||
Self::Op(op, pats) => match pats.as_slice() {
|
||||
[] => op.fmt(f),
|
||||
[rest] => write!(f, "{op}{rest}"),
|
||||
_ => f.delimit("(", ")").list(pats, op),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PatOp {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(match self {
|
||||
Self::Rest => "..",
|
||||
Self::RangeEx => "..",
|
||||
Self::RangeIn => "..=",
|
||||
Self::Ref => "&",
|
||||
Self::Tuple => ", ",
|
||||
Self::Slice => ", ",
|
||||
Self::Alt => " | ",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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::Ref(ty) => write!(f, "&{ty}"),
|
||||
Self::Tuple(items) => f.delimit('(', ')').list(items, ", "),
|
||||
Self::Slice(ty) => write!(f, "[{ty}]"),
|
||||
Self::Array(ty, n) => write!(f, "[{ty}; {n}]"),
|
||||
|
||||
Reference in New Issue
Block a user