AST: merge let, const, static, match_arm into one binder
This commit is contained in:
208
src/parser.rs
208
src/parser.rs
@@ -5,7 +5,7 @@ use crate::{
|
||||
span::Span,
|
||||
token::{Lexeme, TKind, Token},
|
||||
};
|
||||
use std::{error::Error, fmt::Display, vec};
|
||||
use std::{error::Error, fmt::Display, iter, vec};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum ParseError {
|
||||
@@ -546,8 +546,9 @@ pub enum Ps {
|
||||
Id, // Identifier
|
||||
Mid, // MetaIdentifier
|
||||
Lit, // Literal
|
||||
Let, // let Pat = Expr
|
||||
Let, // let Pat = Expr (else Expr)?
|
||||
Const, // const Pat = Expr
|
||||
Static, // static Pat = Expr
|
||||
Typedef, // struct { Pat } | struct ( Pat )
|
||||
For, // for Pat in Expr Expr else Expr
|
||||
Fn, // fn ( Pat,* ) Expr
|
||||
@@ -555,7 +556,6 @@ pub enum Ps {
|
||||
Lambda, // | Pat,* | Expr
|
||||
DoubleRef, // && Expr
|
||||
Make, // Expr{ Expr,* }
|
||||
Match, // match Expr { MatchArm,* }
|
||||
Mod, // mod Ty Expr
|
||||
ImplicitDo, // An implicit semicolon
|
||||
ExplicitDo, // An explicit leading semicolon
|
||||
@@ -577,7 +577,7 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
TKind::Public => (Ps::Op(Op::Pub), Prec::Body),
|
||||
TKind::For => (Ps::For, Prec::Body),
|
||||
TKind::Fn => (Ps::Fn, Prec::Body),
|
||||
TKind::Match => (Ps::Match, Prec::Body),
|
||||
TKind::Match => (Ps::Op(Op::Match), Prec::Body),
|
||||
TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
|
||||
TKind::Module => (Ps::Mod, Prec::Body),
|
||||
TKind::Let => (Ps::Let, Prec::Tuple),
|
||||
@@ -663,17 +663,6 @@ fn from_infix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
})
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Const {
|
||||
type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
Ok(Self(
|
||||
p.consume().parse(PPrec::Tuple)?,
|
||||
p.expect(TKind::Eq)?.parse(Prec::Tuple.value())?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Typedef {
|
||||
type Prec = ();
|
||||
|
||||
@@ -717,46 +706,36 @@ impl<'t> Parse<'t> for Fn {
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Let {
|
||||
type Prec = ();
|
||||
type Prec = LetKind;
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
let pat = p.consume().parse(PPrec::Tuple)?;
|
||||
if p.next_if(TKind::Eq).allow_eof()?.is_none_or(|v| v.is_err()) {
|
||||
return Ok(Self(pat, vec![]));
|
||||
fn parse(p: &mut Parser<'t>, level: Self::Prec) -> PResult<Self> {
|
||||
if let LetKind::Match = level {
|
||||
// |? Pat => Expr
|
||||
p.next_if(TKind::Bar)?.ok(); // and discard
|
||||
return Ok(Self(
|
||||
level,
|
||||
p.parse(PPrec::Min)?,
|
||||
vec![p.expect(TKind::FatArrow)?.parse(Prec::Body.next())?],
|
||||
));
|
||||
}
|
||||
|
||||
// let Pat
|
||||
let pat = p.consume().parse(PPrec::Tuple)?;
|
||||
if p.next_if(TKind::Eq).allow_eof()?.is_none_or(|v| v.is_err()) {
|
||||
return Ok(Self(level, pat, vec![]));
|
||||
}
|
||||
|
||||
// = Expr
|
||||
let body = p.parse(Prec::Tuple.value())?;
|
||||
if p.next_if(TKind::Else)
|
||||
.allow_eof()?
|
||||
.is_none_or(|v| v.is_err())
|
||||
{
|
||||
return Ok(Self(pat, vec![body]));
|
||||
return Ok(Self(level, pat, vec![body]));
|
||||
}
|
||||
|
||||
Ok(Self(pat, vec![body, p.parse(Prec::Body.next())?]))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Match {
|
||||
type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
Ok(Self(p.consume().parse(Prec::Logical.value())?, {
|
||||
p.expect(TKind::LCurly)?;
|
||||
p.list(vec![], Prec::Body.next(), TKind::Comma, TKind::RCurly)?
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for MatchArm {
|
||||
type Prec = usize;
|
||||
|
||||
fn parse(p: &mut Parser<'t>, level: usize) -> PResult<Self> {
|
||||
p.next_if(TKind::Bar)?.ok(); // and discard
|
||||
Ok(MatchArm(
|
||||
p.parse(PPrec::Min)?,
|
||||
p.expect(TKind::FatArrow)?.parse(level)?,
|
||||
))
|
||||
// else Expr
|
||||
Ok(Self(level, pat, vec![body, p.parse(Prec::Body.next())?]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,76 +788,66 @@ fn parse_for<'t>(p: &mut Parser<'t>, _level: ()) -> PResult<Expr> {
|
||||
},
|
||||
}
|
||||
*/
|
||||
// let mut tmp_p = Parser::new(Lexer::new(
|
||||
// "match `iter.into_iter() {
|
||||
// `iterator => loop match `iterator.next() {
|
||||
// None => break `fail,
|
||||
// Some(`pat) => `pass,
|
||||
// },
|
||||
// }",
|
||||
// ));
|
||||
|
||||
// let mut template: Expr = tmp_p.parse(Prec::MIN)?;
|
||||
|
||||
// let mut subst = Subst::<Span> { exp: Default::default(), pat: Default::default() };
|
||||
// subst.exp.extend([
|
||||
// ("iterator".into(), Expr::Id("#iter".into())),
|
||||
// ("iter".into(), iter.0),
|
||||
// ("fail".into(), fail.0),
|
||||
// ("pass".into(), pass.0),
|
||||
// ]);
|
||||
// subst.pat.extend([
|
||||
// ("iterator".into(), Pat::Name("#iter".into())),
|
||||
// ("pat".into(), pat),
|
||||
// ]);
|
||||
|
||||
// template.apply(&subst);
|
||||
// Ok(template)
|
||||
|
||||
Ok(Expr::Match(Box::new(Match(
|
||||
Expr::Op(
|
||||
Op::Dot,
|
||||
vec![
|
||||
iter,
|
||||
Expr::Op(Op::Call, vec![Expr::Id("into_iter".into()).anno(cspan)]).anno(cspan),
|
||||
],
|
||||
)
|
||||
.anno(cspan),
|
||||
vec![MatchArm(
|
||||
Pat::Name("#iter".into()),
|
||||
Ok(Expr::Op(
|
||||
Op::Match,
|
||||
vec![
|
||||
Expr::Op(
|
||||
Op::Loop,
|
||||
Op::Dot,
|
||||
vec![
|
||||
Expr::Match(Box::new(Match(
|
||||
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),
|
||||
vec![
|
||||
MatchArm(
|
||||
Pat::Name("None".into()),
|
||||
Expr::Op(Op::Break, vec![fail]).anno(fspan),
|
||||
),
|
||||
MatchArm(
|
||||
Pat::TupStruct(
|
||||
"Some".into(),
|
||||
Box::new(Pat::Op(PatOp::Tuple, vec![pat])),
|
||||
),
|
||||
pass,
|
||||
),
|
||||
],
|
||||
)))
|
||||
.anno(pspan),
|
||||
iter,
|
||||
Expr::Op(Op::Call, vec![Expr::Id("into_iter".into()).anno(cspan)]).anno(cspan),
|
||||
],
|
||||
)
|
||||
.anno(cspan),
|
||||
Expr::Let(Box::new(Let(
|
||||
LetKind::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::Let(Box::new(Let(
|
||||
LetKind::Match,
|
||||
Pat::Name("None".into()),
|
||||
vec![Expr::Op(Op::Break, vec![fail]).anno(fspan)],
|
||||
)))
|
||||
.anno(fspan),
|
||||
Expr::Let(Box::new(Let(
|
||||
LetKind::Match,
|
||||
Pat::TupStruct(
|
||||
"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 {
|
||||
@@ -907,12 +876,13 @@ impl<'t> Parse<'t> for Expr {
|
||||
Ps::Id => Expr::Id(p.parse(())?),
|
||||
Ps::Mid => Expr::MetId(p.consume().next()?.lexeme.to_string()),
|
||||
Ps::Lit => Expr::Lit(p.parse(())?),
|
||||
Ps::Let => Expr::Let(p.parse(())?),
|
||||
Ps::Let => Expr::Let(p.parse(LetKind::Let)?),
|
||||
Ps::Const => Expr::Let(p.parse(LetKind::Const)?),
|
||||
Ps::Static => Expr::Let(p.parse(LetKind::Static)?),
|
||||
Ps::For => parse_for(p, ())?,
|
||||
Ps::Const => Expr::Const(p.parse(())?),
|
||||
Ps::Typedef => Expr::Struct(p.parse(())?),
|
||||
Ps::Match => Expr::Match(p.parse(())?),
|
||||
Ps::Mod => Expr::Mod(p.parse(())?),
|
||||
Ps::Op(Op::Match) => parse_match(p)?,
|
||||
Ps::Op(Op::Meta) => Expr::Op(
|
||||
Op::Meta,
|
||||
vec![
|
||||
@@ -1049,6 +1019,20 @@ fn parse_array<'t>(p: &mut Parser<'t>) -> PResult<Expr> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_match<'t>(p: &mut Parser<'t>) -> PResult<Expr> {
|
||||
let scrutinee = p.consume().parse(Prec::Logical.value())?;
|
||||
|
||||
let arms = p
|
||||
.expect(TKind::LCurly)?
|
||||
.list(vec![], LetKind::Match, TKind::Comma, TKind::RCurly)?
|
||||
.into_iter()
|
||||
.map(|Anno(arm, span)| Anno(Expr::Let(Box::new(arm)), span));
|
||||
|
||||
let expr = Expr::Op(Op::Match, iter::once(scrutinee).chain(arms).collect());
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
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