ast: pub, mod, and Ty::Fn parsing
This commit is contained in:
@@ -318,6 +318,28 @@ impl<'t> Parse<'t> for Ty {
|
||||
tok => Err(ParseError::NotType(tok.kind, tok.span))?,
|
||||
}
|
||||
}
|
||||
TKind::Fn => {
|
||||
p.consume().consume_if(TKind::LParen)?;
|
||||
|
||||
let mut tys = p.list(vec![], (), TKind::Comma, TKind::RParen)?;
|
||||
match p.next_if(TKind::Arrow) {
|
||||
Ok(_) => {
|
||||
tys.push(p.parse(())?);
|
||||
Ty::Fn(tys)
|
||||
}
|
||||
_ => Ty::Tuple(tys),
|
||||
}
|
||||
}
|
||||
TKind::LParen => {
|
||||
let mut tys = p.consume().list(vec![], (), TKind::Comma, TKind::RParen)?;
|
||||
match p.next_if(TKind::Arrow) {
|
||||
Ok(_) => {
|
||||
tys.push(p.parse(())?);
|
||||
Ty::Fn(tys)
|
||||
}
|
||||
_ => Ty::Tuple(tys),
|
||||
}
|
||||
}
|
||||
_ => Err(ParseError::NotType(tok.kind, tok.span))?,
|
||||
};
|
||||
|
||||
@@ -399,6 +421,7 @@ pub enum Ps {
|
||||
DoubleRef, // && Expr
|
||||
Make, // Expr{ Expr,* }
|
||||
Match, // match Expr { MatchArm,* }
|
||||
Mod, // mod Ty Expr
|
||||
End, // Produces an empty value.
|
||||
Op(Op), // A normal [ast::Op]
|
||||
}
|
||||
@@ -414,9 +437,11 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
(Ps::Lit, Prec::Max)
|
||||
}
|
||||
|
||||
TKind::Public => (Ps::Op(Op::Pub), Prec::Body),
|
||||
TKind::Fn => (Ps::Fn, Prec::Body),
|
||||
TKind::Match => (Ps::Match, Prec::Body),
|
||||
TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
|
||||
TKind::Module => (Ps::Mod, Prec::Body),
|
||||
TKind::Let => (Ps::Let, Prec::Tuple),
|
||||
TKind::Const => (Ps::Const, Prec::Body),
|
||||
TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
|
||||
@@ -427,7 +452,7 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
|
||||
TKind::LCurly => (Ps::Op(Op::Block), Prec::Min),
|
||||
TKind::RCurly => (Ps::End, Prec::Do),
|
||||
TKind::LBrack => (Ps::Op(Op::Array), Prec::Min),
|
||||
TKind::LBrack => (Ps::Op(Op::Array), Prec::Tuple),
|
||||
TKind::RBrack => (Ps::End, Prec::Tuple),
|
||||
TKind::LParen => (Ps::Op(Op::Group), Prec::Min),
|
||||
TKind::RParen => (Ps::End, Prec::Tuple),
|
||||
@@ -560,6 +585,13 @@ impl<'t> Parse<'t> for MakeArm {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Mod {
|
||||
type Prec = ();
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
Ok(Mod(p.consume().parse(())?, p.parse(Prec::Body.value())?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Expr {
|
||||
type Prec = usize;
|
||||
|
||||
@@ -585,22 +617,13 @@ impl<'t> Parse<'t> for Expr {
|
||||
Ps::Lit => Expr::Lit(p.parse(())?),
|
||||
Ps::Let => Expr::Let(p.parse(())?),
|
||||
Ps::Const => Expr::Const(p.parse(())?),
|
||||
Ps::Op(Op::Macro) => Expr::Op(
|
||||
Op::Macro,
|
||||
vec![p.consume().parse(prec.next())?, {
|
||||
p.next_if(TKind::FatArrow)?;
|
||||
p.parse(prec.next())?
|
||||
}],
|
||||
),
|
||||
Ps::Match => Expr::Match(p.parse(())?),
|
||||
Ps::Mod => Expr::Mod(p.parse(())?),
|
||||
Ps::Op(Op::Block) => Expr::Op(
|
||||
Op::Block,
|
||||
p.consume().opt(MIN, TKind::RCurly)?.into_iter().collect(),
|
||||
),
|
||||
Ps::Op(Op::Array) => Expr::Op(
|
||||
Op::Array,
|
||||
p.consume().list(vec![], 0, TKind::Comma, TKind::RBrack)?,
|
||||
),
|
||||
Ps::Op(Op::Array) => parse_array(p)?,
|
||||
Ps::Op(Op::Group) => match p.consume().opt(MIN, TKind::RParen)? {
|
||||
Some(value) => Expr::Op(Op::Group, vec![value]),
|
||||
None => Expr::Op(Op::Tuple, vec![]),
|
||||
@@ -629,10 +652,12 @@ impl<'t> Parse<'t> for Expr {
|
||||
Ps::Lambda0 => Expr::Fn(Box::new(Fn(None, Pat::Tuple(vec![]), {
|
||||
p.consume().parse(Prec::Body.next())?
|
||||
}))),
|
||||
Ps::DoubleRef => Expr::Op(
|
||||
Op::Refer,
|
||||
vec![Expr::Op(Op::Refer, vec![p.consume().parse(prec.next())?]).anno(span)],
|
||||
),
|
||||
Ps::DoubleRef => p.consume().parse(prec.next()).map(|Anno(expr, span)| {
|
||||
Expr::Op(
|
||||
Op::Refer,
|
||||
vec![Anno(Expr::Op(Op::Refer, vec![Anno(expr, span)]), span)],
|
||||
)
|
||||
})?,
|
||||
|
||||
Ps::Op(op) => Expr::Op(op, vec![p.consume().parse(prec.next())?]),
|
||||
_ => unimplemented!("prefix {op:?}"),
|
||||
@@ -650,10 +675,12 @@ impl<'t> Parse<'t> for Expr {
|
||||
head = match op {
|
||||
// Make (structor expressions) are context-sensitive
|
||||
Ps::Make => match &head {
|
||||
Expr::Op(Op::Path, _) | Expr::Id(_) | Expr::MetId(_) => Expr::Make(
|
||||
head.anno(span).into(),
|
||||
p.consume().list(vec![], (), TKind::Comma, TKind::RCurly)?,
|
||||
),
|
||||
Expr::Op(Op::Path, _) | Expr::Id(_) | Expr::MetId(_) => {
|
||||
Expr::Make(Box::new(Make(
|
||||
head.anno(span).into(),
|
||||
p.consume().list(vec![], (), TKind::Comma, TKind::RCurly)?,
|
||||
)))
|
||||
}
|
||||
_ => break,
|
||||
},
|
||||
Ps::Op(Op::Index) => Expr::Op(
|
||||
@@ -686,6 +713,25 @@ impl<'t> Parse<'t> for Expr {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses an array with 0 or more elements, or an array-repetition
|
||||
fn parse_array<'t>(p: &mut Parser<'t>) -> PResult<Expr> {
|
||||
if p.consume().peek()?.kind == TKind::RBrack {
|
||||
p.consume();
|
||||
return Ok(Expr::Op(Op::Array, vec![]));
|
||||
}
|
||||
|
||||
let prec = Prec::Tuple;
|
||||
let item = p.parse(prec.value())?;
|
||||
let repeat = p.opt_if(prec.next(), TKind::Semi)?;
|
||||
p.next_if(TKind::RBrack)?;
|
||||
|
||||
Ok(match (repeat, item) {
|
||||
(Some(repeat), item) => Expr::Op(Op::ArRep, vec![item, repeat]),
|
||||
(None, Anno(Expr::Op(Op::Tuple, items), _)) => Expr::Op(Op::Array, items),
|
||||
(None, item) => Expr::Op(Op::Array, vec![item]),
|
||||
})
|
||||
}
|
||||
|
||||
impl<'t, P: Parse<'t> + Annotation> Parse<'t> for Anno<P> {
|
||||
type Prec = P::Prec;
|
||||
fn parse(p: &mut Parser<'t>, level: P::Prec) -> PResult<Self>
|
||||
|
||||
Reference in New Issue
Block a user