ast: Give for loops a dedicated node and remove eager desugar
This commit is contained in:
@@ -398,19 +398,12 @@ fn parse_match(p: &mut Parser<'_>) -> PResult<Expr> {
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Parses and desugars a `for` loop expression
|
||||
///
|
||||
/// Assumes the existence of the following items:
|
||||
///
|
||||
/// 1. `enum<T> Option { None, Some(T) }`
|
||||
/// 2. `fn T::into_iter(&mut self) -> U`
|
||||
/// 3. `U::next() -> Option<V>`
|
||||
/// Parses a `for` loop expression
|
||||
fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
|
||||
// for Pat
|
||||
let pat = p.consume().parse(PPrec::Tuple)?;
|
||||
// in Expr
|
||||
let iter: Anno<Expr> = p.expect(TKind::In)?.parse(Prec::Logical.next())?;
|
||||
let cspan = iter.1;
|
||||
// Expr
|
||||
let pass: Anno<Expr> = p.parse(Prec::Body.next())?;
|
||||
let pspan = pass.1;
|
||||
@@ -419,8 +412,8 @@ fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
|
||||
Some(Ok(_)) => p.parse(Prec::Body.next())?,
|
||||
_ => Expr::Op(Op::Tuple, vec![]).anno(pspan),
|
||||
};
|
||||
let fspan = fail.1;
|
||||
/*
|
||||
TODO: desugar for into loop-match:
|
||||
for `pat in `iter `pass else `fail
|
||||
==>
|
||||
match (`iter).into_iter() {
|
||||
@@ -431,70 +424,12 @@ fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: A better way to do this kind of substitution desugaring
|
||||
// without losing span information!
|
||||
Ok(Expr::Op(
|
||||
Op::Match,
|
||||
vec![
|
||||
Expr::Op(
|
||||
Op::Dot,
|
||||
vec![
|
||||
iter,
|
||||
Expr::Op(Op::Call, vec![Expr::Id("into_iter".into()).anno(cspan)]).anno(cspan),
|
||||
],
|
||||
)
|
||||
.anno(cspan),
|
||||
Expr::Bind(Box::new(Bind(
|
||||
BindOp::Match,
|
||||
vec![],
|
||||
Pat::Name("#iter".into()),
|
||||
vec![
|
||||
Expr::Op(
|
||||
Op::Loop,
|
||||
vec![
|
||||
Expr::Op(
|
||||
Op::Match,
|
||||
vec![
|
||||
Expr::Op(
|
||||
Op::Dot,
|
||||
vec![
|
||||
Expr::Id("#iter".into()).anno(cspan),
|
||||
Expr::Op(
|
||||
Op::Call,
|
||||
vec![Expr::Id("next".into()).anno(cspan)],
|
||||
)
|
||||
.anno(cspan),
|
||||
],
|
||||
)
|
||||
.anno(cspan),
|
||||
Expr::Bind(Box::new(Bind(
|
||||
BindOp::Match,
|
||||
vec![],
|
||||
Pat::Name("None".into()),
|
||||
vec![Expr::Op(Op::Break, vec![fail]).anno(fspan)],
|
||||
)))
|
||||
.anno(fspan),
|
||||
Expr::Bind(Box::new(Bind(
|
||||
BindOp::Match,
|
||||
vec![],
|
||||
Pat::NamedTuple(
|
||||
"Some".into(),
|
||||
Box::new(Pat::Op(PatOp::Tuple, vec![pat])),
|
||||
),
|
||||
vec![pass],
|
||||
)))
|
||||
.anno(pspan),
|
||||
],
|
||||
)
|
||||
.anno(pspan),
|
||||
],
|
||||
)
|
||||
.anno(pspan),
|
||||
],
|
||||
)))
|
||||
.anno(pspan),
|
||||
],
|
||||
))
|
||||
Ok(Expr::Bind(Box::new(Bind(
|
||||
BindOp::For,
|
||||
vec![],
|
||||
pat,
|
||||
vec![iter, pass, fail],
|
||||
))))
|
||||
}
|
||||
|
||||
/// Returns the [BindOp], [pattern precedence](PPrec), [arrow TKind](TKind), [body precedence](Prec),
|
||||
|
||||
Reference in New Issue
Block a user