ast: Add use, tackle remaining low-hanging fruit
This commit is contained in:
46
src/ast.rs
46
src/ast.rs
@@ -45,6 +45,19 @@ pub enum Literal {
|
||||
Str(String),
|
||||
}
|
||||
|
||||
/// A compound import declaration
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Use {
|
||||
/// "*"
|
||||
Glob,
|
||||
/// Identifier
|
||||
Name(String),
|
||||
/// Identifier :: Use
|
||||
Path(String, Box<Use>),
|
||||
/// { Use, * }
|
||||
Tree(Vec<Use>),
|
||||
}
|
||||
|
||||
/// Binding patterns for each kind of matchable value.
|
||||
///
|
||||
/// This covers both patterns in Match expressions, and type annotations.
|
||||
@@ -71,6 +84,8 @@ pub enum Pat {
|
||||
/// Operators on lists of patterns
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum PatOp {
|
||||
/// Changes the binding mode to "mutable"
|
||||
Mut,
|
||||
/// Matches the dereference of a pointer (`&pat`)
|
||||
Ref,
|
||||
/// Matches a partial decomposition (`..rest`) or upper-bounded range (`..100`)
|
||||
@@ -83,6 +98,8 @@ pub enum PatOp {
|
||||
Tuple,
|
||||
/// Matches the elements of a slice or array
|
||||
Slice,
|
||||
/// Matches a constant-size slice with repeating elements
|
||||
Arrep,
|
||||
/// Matches a type annotation or struct member
|
||||
Typed,
|
||||
/// Matches a function signature
|
||||
@@ -96,6 +113,7 @@ pub enum PatOp {
|
||||
/// let Pat (= Expr (else Expr)?)?
|
||||
/// const Pat (= Expr (else Expr)?)?
|
||||
/// static Pat (= Expr (else Expr)?)?
|
||||
/// type Pat (= Expr)?
|
||||
/// fn Pat Expr
|
||||
/// mod Pat Expr
|
||||
/// impl Pat Expr
|
||||
@@ -112,6 +130,8 @@ pub enum BindKind {
|
||||
Const,
|
||||
/// A `static Pat = Expr` binding
|
||||
Static,
|
||||
/// A type-alias binding
|
||||
Type,
|
||||
/// A `fn Pat Expr` binding
|
||||
Fn,
|
||||
/// A `mod Pat Expr` binding
|
||||
@@ -143,7 +163,6 @@ pub struct Typedef(pub TypedefKind, pub Pat);
|
||||
/// The type of type being defined
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum TypedefKind {
|
||||
Alias,
|
||||
Struct,
|
||||
Enum,
|
||||
}
|
||||
@@ -157,6 +176,8 @@ pub enum Expr<A: Annotation = Span> {
|
||||
MetId(String),
|
||||
/// A literal bool, string, char, or int
|
||||
Lit(Literal),
|
||||
/// use Use
|
||||
Use(Use),
|
||||
/// `(let | const | static) Pat::NoTopAlt (= expr (else expr)?)?` |
|
||||
/// `(fn | mod | impl) Pat::Fn Expr`
|
||||
Bind(Box<Bind<A>>),
|
||||
@@ -310,6 +331,23 @@ impl<T: Display + Annotation, A: Annotation> Display for Anno<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Use {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Glob => "*".fmt(f),
|
||||
Self::Name(name) => name.fmt(f),
|
||||
Self::Path(segment, rest) => write!(f, "{segment}::{rest}"),
|
||||
Self::Tree(items) => match items.len() {
|
||||
0 => "{}".fmt(f),
|
||||
1..=3 => f.delimit("{ ", " }").list(items, ", "),
|
||||
_ => f
|
||||
.delimit_indented("{", "}")
|
||||
.list_wrap("\n", items, ",\n", ",\n"),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Annotation> Display for Bind<A> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(op, pat, exprs) = self;
|
||||
@@ -335,6 +373,7 @@ impl Display for BindKind {
|
||||
Self::Let => "let ",
|
||||
Self::Const => "const ",
|
||||
Self::Static => "static ",
|
||||
Self::Type => "type ",
|
||||
Self::Fn => "fn ",
|
||||
Self::Mod => "mod ",
|
||||
Self::Impl => "impl ",
|
||||
@@ -354,7 +393,6 @@ impl Display for Typedef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(kind, pat) = self;
|
||||
f.write_str(match kind {
|
||||
TypedefKind::Alias => "type ",
|
||||
TypedefKind::Struct => "struct ",
|
||||
TypedefKind::Enum => "enum ",
|
||||
})?;
|
||||
@@ -376,6 +414,7 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
Self::Id(id) => id.fmt(f),
|
||||
Self::MetId(id) => write!(f, "`{id}"),
|
||||
Self::Lit(literal) => literal.fmt(f),
|
||||
Self::Use(v) => write!(f, "use {v}"),
|
||||
Self::Bind(v) => v.fmt(f),
|
||||
Self::Struct(v) => v.fmt(f),
|
||||
Self::Make(v) => v.fmt(f),
|
||||
@@ -515,6 +554,7 @@ impl Display for Pat {
|
||||
Self::NamedTuple(name, bind) => write!(f, "{name} {bind}"),
|
||||
Self::Op(PatOp::Tuple, pats) => f.delimit("(", ")").list(pats, ", "),
|
||||
Self::Op(PatOp::Slice, pats) => f.delimit("[", "]").list(pats, ", "),
|
||||
Self::Op(op @ PatOp::Arrep, pats) => f.delimit("[", "]").list(pats, op),
|
||||
Self::Op(op @ (PatOp::Typed | PatOp::Fn), pats) => f.list(pats, op),
|
||||
Self::Op(op @ PatOp::Alt, pats) => f.delimit("<", ">").list(pats, op),
|
||||
Self::Op(op, pats) => match pats.as_slice() {
|
||||
@@ -529,12 +569,14 @@ impl Display for Pat {
|
||||
impl Display for PatOp {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(match self {
|
||||
Self::Mut => "mut ",
|
||||
Self::Ref => "&",
|
||||
Self::Rest => "..",
|
||||
Self::RangeEx => "..",
|
||||
Self::RangeIn => "..=",
|
||||
Self::Tuple => ", ",
|
||||
Self::Slice => ", ",
|
||||
Self::Arrep => "; ",
|
||||
Self::Typed => ": ",
|
||||
Self::Fn => " -> ",
|
||||
Self::Alt => " | ",
|
||||
|
||||
Reference in New Issue
Block a user