parser: Move parse_for below impl Parse<'t> for Expr, and allow a single semi at EOF
This commit is contained in:
185
src/parser.rs
185
src/parser.rs
@@ -731,93 +731,6 @@ impl<'t> Parse<'t> for MakeArm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_for<'t>(p: &mut Parser<'t>, _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;
|
|
||||||
// else Expr?
|
|
||||||
let fail = match p.next_if(TKind::Else).allow_eof()? {
|
|
||||||
Some(Ok(_)) => p.parse(Prec::Body.next())?,
|
|
||||||
_ => Expr::Op(Op::Tuple, vec![]).anno(pspan),
|
|
||||||
};
|
|
||||||
let fspan = fail.1;
|
|
||||||
/*
|
|
||||||
for `pat in `iter `pass else `fail
|
|
||||||
==>
|
|
||||||
match (`iter).into_iter() {
|
|
||||||
#iter => loop match #iter.next() {
|
|
||||||
None => break `fail,
|
|
||||||
Some(`pat) => `pass,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
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(
|
|
||||||
BindKind::Match,
|
|
||||||
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(
|
|
||||||
BindKind::Match,
|
|
||||||
Pat::Name("None".into()),
|
|
||||||
vec![Expr::Op(Op::Break, vec![fail]).anno(fspan)],
|
|
||||||
)))
|
|
||||||
.anno(fspan),
|
|
||||||
Expr::Bind(Box::new(Bind(
|
|
||||||
BindKind::Match,
|
|
||||||
Pat::NamedTuple(
|
|
||||||
"Some".into(),
|
|
||||||
Box::new(Pat::Op(PatOp::Tuple, vec![pat])),
|
|
||||||
),
|
|
||||||
vec![pass],
|
|
||||||
)))
|
|
||||||
.anno(pspan),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.anno(pspan),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.anno(pspan),
|
|
||||||
],
|
|
||||||
)))
|
|
||||||
.anno(pspan),
|
|
||||||
],
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'t> Parse<'t> for Expr {
|
impl<'t> Parse<'t> for Expr {
|
||||||
type Prec = usize;
|
type Prec = usize;
|
||||||
|
|
||||||
@@ -939,7 +852,14 @@ impl<'t> Parse<'t> for Expr {
|
|||||||
// As is ImplicitDo (semicolon elision)
|
// As is ImplicitDo (semicolon elision)
|
||||||
Ps::ImplicitDo if p.elide_do => head.and_do(span, p.parse(prec.next())?),
|
Ps::ImplicitDo if p.elide_do => head.and_do(span, p.parse(prec.next())?),
|
||||||
Ps::ImplicitDo => break,
|
Ps::ImplicitDo => break,
|
||||||
Ps::Op(Op::Do) => head.and_do(span, p.consume().parse(prec.next())?),
|
// Allow `;` at end of file
|
||||||
|
Ps::Op(Op::Do) => head.and_do(
|
||||||
|
span,
|
||||||
|
match p.consume().peek().allow_eof()? {
|
||||||
|
Some(_) => p.parse(prec.next())?,
|
||||||
|
None => Anno(Default::default(), span),
|
||||||
|
},
|
||||||
|
),
|
||||||
Ps::Op(Op::Index) => Expr::Op(
|
Ps::Op(Op::Index) => Expr::Op(
|
||||||
Op::Index,
|
Op::Index,
|
||||||
p.consume()
|
p.consume()
|
||||||
@@ -1008,6 +928,95 @@ fn parse_match<'t>(p: &mut Parser<'t>) -> PResult<Expr> {
|
|||||||
Ok(expr)
|
Ok(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_for<'t>(p: &mut Parser<'t>, _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;
|
||||||
|
// else Expr?
|
||||||
|
let fail = match p.next_if(TKind::Else).allow_eof()? {
|
||||||
|
Some(Ok(_)) => p.parse(Prec::Body.next())?,
|
||||||
|
_ => Expr::Op(Op::Tuple, vec![]).anno(pspan),
|
||||||
|
};
|
||||||
|
let fspan = fail.1;
|
||||||
|
/*
|
||||||
|
for `pat in `iter `pass else `fail
|
||||||
|
==>
|
||||||
|
match (`iter).into_iter() {
|
||||||
|
#iter => loop match #iter.next() {
|
||||||
|
None => break `fail,
|
||||||
|
Some(`pat) => `pass,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 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(
|
||||||
|
BindKind::Match,
|
||||||
|
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(
|
||||||
|
BindKind::Match,
|
||||||
|
Pat::Name("None".into()),
|
||||||
|
vec![Expr::Op(Op::Break, vec![fail]).anno(fspan)],
|
||||||
|
)))
|
||||||
|
.anno(fspan),
|
||||||
|
Expr::Bind(Box::new(Bind(
|
||||||
|
BindKind::Match,
|
||||||
|
Pat::NamedTuple(
|
||||||
|
"Some".into(),
|
||||||
|
Box::new(Pat::Op(PatOp::Tuple, vec![pat])),
|
||||||
|
),
|
||||||
|
vec![pass],
|
||||||
|
)))
|
||||||
|
.anno(pspan),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.anno(pspan),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.anno(pspan),
|
||||||
|
],
|
||||||
|
)))
|
||||||
|
.anno(pspan),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
impl<'t, P: Parse<'t> + Annotation> Parse<'t> for Anno<P> {
|
impl<'t, P: Parse<'t> + Annotation> Parse<'t> for Anno<P> {
|
||||||
type Prec = P::Prec;
|
type Prec = P::Prec;
|
||||||
fn parse(p: &mut Parser<'t>, level: P::Prec) -> PResult<Self>
|
fn parse(p: &mut Parser<'t>, level: P::Prec) -> PResult<Self>
|
||||||
|
|||||||
Reference in New Issue
Block a user