cl-ast: Add inline closure expressions
This commit is contained in:
@@ -317,6 +317,8 @@ pub enum ExprKind {
|
||||
/// An empty expression: `(` `)`
|
||||
#[default]
|
||||
Empty,
|
||||
/// A [Closure] expression: `|` [`Expr`] `|` ( -> [`Ty`])? [`Expr`]
|
||||
Closure(Closure),
|
||||
/// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)`
|
||||
Tuple(Tuple),
|
||||
/// A [Struct creation](Structor) expression: [Path] `{` ([Fielder] `,`)* [Fielder]? `}`
|
||||
@@ -371,6 +373,13 @@ pub enum ExprKind {
|
||||
Continue,
|
||||
}
|
||||
|
||||
/// A Closure [expression](Expr): `|` [`Expr`] `|` ( -> [`Ty`])? [`Expr`]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Closure {
|
||||
pub arg: Box<Pattern>,
|
||||
pub body: Box<Expr>,
|
||||
}
|
||||
|
||||
/// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)`
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Tuple {
|
||||
|
||||
@@ -51,6 +51,7 @@ impl_from! {
|
||||
}
|
||||
impl From for ExprKind {
|
||||
Let => ExprKind::Let,
|
||||
Closure => ExprKind::Closure,
|
||||
Quote => ExprKind::Quote,
|
||||
Match => ExprKind::Match,
|
||||
Assign => ExprKind::Assign,
|
||||
|
||||
@@ -402,6 +402,7 @@ impl Display for ExprKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ExprKind::Empty => "()".fmt(f),
|
||||
ExprKind::Closure(v) => v.fmt(f),
|
||||
ExprKind::Quote(v) => v.fmt(f),
|
||||
ExprKind::Let(v) => v.fmt(f),
|
||||
ExprKind::Match(v) => v.fmt(f),
|
||||
@@ -431,6 +432,17 @@ impl Display for ExprKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Closure {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self { arg, body } = self;
|
||||
match arg.as_ref() {
|
||||
Pattern::Tuple(args) => separate(args, ", ")(f.delimit_with("|", "|")),
|
||||
_ => arg.fmt(f),
|
||||
}?;
|
||||
write!(f, " {body}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Quote {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self { quote } = self;
|
||||
|
||||
@@ -283,6 +283,7 @@ impl WeightOf for ExprKind {
|
||||
fn weight_of(&self) -> usize {
|
||||
match self {
|
||||
ExprKind::Empty => size_of_val(self),
|
||||
ExprKind::Closure(v) => v.weight_of(),
|
||||
ExprKind::Quote(v) => v.weight_of(),
|
||||
ExprKind::Let(v) => v.weight_of(),
|
||||
ExprKind::Match(v) => v.weight_of(),
|
||||
@@ -312,6 +313,13 @@ impl WeightOf for ExprKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl WeightOf for Closure {
|
||||
fn weight_of(&self) -> usize {
|
||||
let Self { arg, body } = self;
|
||||
arg.weight_of() + body.weight_of()
|
||||
}
|
||||
}
|
||||
|
||||
impl WeightOf for Quote {
|
||||
fn weight_of(&self) -> usize {
|
||||
let Self { quote } = self;
|
||||
|
||||
@@ -236,6 +236,10 @@ pub trait Fold {
|
||||
fn fold_expr_kind(&mut self, kind: ExprKind) -> ExprKind {
|
||||
or_fold_expr_kind(self, kind)
|
||||
}
|
||||
fn fold_closure(&mut self, value: Closure) -> Closure {
|
||||
let Closure { arg, body } = value;
|
||||
Closure { arg: Box::new(self.fold_pattern(*arg)), body: Box::new(self.fold_expr(*body)) }
|
||||
}
|
||||
fn fold_let(&mut self, l: Let) -> Let {
|
||||
let Let { mutable, name, ty, init } = l;
|
||||
Let {
|
||||
@@ -547,6 +551,7 @@ pub fn or_fold_stmt_kind<F: Fold + ?Sized>(folder: &mut F, kind: StmtKind) -> St
|
||||
pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> ExprKind {
|
||||
match kind {
|
||||
ExprKind::Empty => ExprKind::Empty,
|
||||
ExprKind::Closure(c) => ExprKind::Closure(folder.fold_closure(c)),
|
||||
ExprKind::Quote(q) => ExprKind::Quote(q), // quoted expressions are left unmodified
|
||||
ExprKind::Let(l) => ExprKind::Let(folder.fold_let(l)),
|
||||
ExprKind::Match(m) => ExprKind::Match(folder.fold_match(m)),
|
||||
|
||||
@@ -17,8 +17,9 @@ use super::walk::Walk;
|
||||
pub trait Visit<'a>: Sized {
|
||||
/// Visits a [Walker](Walk)
|
||||
#[inline]
|
||||
fn visit<W: Walk>(&mut self, walker: &'a W) {
|
||||
walker.visit_in(self)
|
||||
fn visit<W: Walk>(&mut self, walker: &'a W) -> &mut Self {
|
||||
walker.visit_in(self);
|
||||
self
|
||||
}
|
||||
/// Visits the children of a [Walker](Walk)
|
||||
fn visit_children<W: Walk>(&mut self, walker: &'a W) {
|
||||
@@ -160,6 +161,9 @@ pub trait Visit<'a>: Sized {
|
||||
fn visit_expr_kind(&mut self, value: &'a ExprKind) {
|
||||
value.children(self)
|
||||
}
|
||||
fn visit_closure(&mut self, value: &'a Closure) {
|
||||
value.children(self)
|
||||
}
|
||||
fn visit_quote(&mut self, value: &'a Quote) {
|
||||
value.children(self)
|
||||
}
|
||||
|
||||
@@ -504,25 +504,26 @@ impl Walk for ExprKind {
|
||||
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||
match self {
|
||||
ExprKind::Empty => {}
|
||||
ExprKind::Closure(value) => value.visit_in(v),
|
||||
ExprKind::Tuple(value) => value.visit_in(v),
|
||||
ExprKind::Structor(value) => value.visit_in(v),
|
||||
ExprKind::Array(value) => value.visit_in(v),
|
||||
ExprKind::ArrayRep(value) => value.visit_in(v),
|
||||
ExprKind::AddrOf(value) => value.visit_in(v),
|
||||
ExprKind::Quote(value) => value.visit_in(v),
|
||||
ExprKind::Let(value) => value.visit_in(v),
|
||||
ExprKind::Match(value) => value.visit_in(v),
|
||||
ExprKind::Literal(value) => value.visit_in(v),
|
||||
ExprKind::Group(value) => value.visit_in(v),
|
||||
ExprKind::Block(value) => value.visit_in(v),
|
||||
ExprKind::Assign(value) => value.visit_in(v),
|
||||
ExprKind::Modify(value) => value.visit_in(v),
|
||||
ExprKind::Binary(value) => value.visit_in(v),
|
||||
ExprKind::Unary(value) => value.visit_in(v),
|
||||
ExprKind::Cast(value) => value.visit_in(v),
|
||||
ExprKind::Member(value) => value.visit_in(v),
|
||||
ExprKind::Index(value) => value.visit_in(v),
|
||||
ExprKind::Structor(value) => value.visit_in(v),
|
||||
ExprKind::Cast(value) => value.visit_in(v),
|
||||
ExprKind::Path(value) => value.visit_in(v),
|
||||
ExprKind::Literal(value) => value.visit_in(v),
|
||||
ExprKind::Array(value) => value.visit_in(v),
|
||||
ExprKind::ArrayRep(value) => value.visit_in(v),
|
||||
ExprKind::AddrOf(value) => value.visit_in(v),
|
||||
ExprKind::Block(value) => value.visit_in(v),
|
||||
ExprKind::Group(value) => value.visit_in(v),
|
||||
ExprKind::Tuple(value) => value.visit_in(v),
|
||||
ExprKind::Let(value) => value.visit_in(v),
|
||||
ExprKind::Match(value) => value.visit_in(v),
|
||||
ExprKind::While(value) => value.visit_in(v),
|
||||
ExprKind::If(value) => value.visit_in(v),
|
||||
ExprKind::For(value) => value.visit_in(v),
|
||||
@@ -533,6 +534,18 @@ impl Walk for ExprKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Walk for Closure {
|
||||
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||
v.visit_closure(self);
|
||||
}
|
||||
|
||||
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||
let Self { arg, body } = self;
|
||||
v.visit_pattern(arg);
|
||||
v.visit_expr(body);
|
||||
}
|
||||
}
|
||||
|
||||
impl Walk for Tuple {
|
||||
#[inline]
|
||||
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
|
||||
|
||||
Reference in New Issue
Block a user