ast: Merge Ty into Pat, merge Mod and Fn into Bind
This commit is contained in:
279
src/parser.rs
279
src/parser.rs
@@ -271,18 +271,13 @@ impl<'t> Parse<'t> for Literal {
|
||||
Ok(match tok.kind {
|
||||
TKind::True => p.consume().then(Literal::Bool(true)),
|
||||
TKind::False => p.consume().then(Literal::Bool(false)),
|
||||
TKind::Character => Literal::Char({
|
||||
let Token { lexeme, .. } = p.take().expect("should have Token");
|
||||
lexeme.char().expect("char token should have char")
|
||||
}),
|
||||
TKind::Integer => Literal::Int({
|
||||
let Token { lexeme, .. } = p.take().expect("should have Token");
|
||||
lexeme.int().expect("integer token should have int")
|
||||
}),
|
||||
TKind::String => Literal::Str({
|
||||
let Token { lexeme, .. } = p.take().expect("should have Token");
|
||||
lexeme.string().expect("string token should have string")
|
||||
}),
|
||||
TKind::Character | TKind::Integer | TKind::String => {
|
||||
match p.take().expect("should have Token").lexeme {
|
||||
Lexeme::String(str) => Literal::Str(str),
|
||||
Lexeme::Integer(int, base) => Literal::Int(int, base),
|
||||
Lexeme::Char(chr) => Literal::Char(chr),
|
||||
}
|
||||
}
|
||||
other => Err(ParseError::NotLiteral(other, tok.span))?,
|
||||
})
|
||||
}
|
||||
@@ -295,6 +290,7 @@ pub enum PPrec {
|
||||
Tuple,
|
||||
Typed,
|
||||
Range,
|
||||
Fn,
|
||||
Max,
|
||||
}
|
||||
|
||||
@@ -305,14 +301,14 @@ impl PPrec {
|
||||
Self::Alt => Self::Tuple,
|
||||
Self::Tuple => Self::Typed,
|
||||
Self::Typed => Self::Range,
|
||||
Self::Range => Self::Max,
|
||||
Self::Range => Self::Fn,
|
||||
Self::Fn => Self::Max,
|
||||
Self::Max => Self::Max,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum PatPs {
|
||||
Typed,
|
||||
Op(PatOp),
|
||||
}
|
||||
|
||||
@@ -320,8 +316,9 @@ fn pat_from_infix(token: &Token) -> Option<(PatPs, PPrec)> {
|
||||
Some(match token.kind {
|
||||
TKind::DotDot => (PatPs::Op(PatOp::RangeEx), PPrec::Range),
|
||||
TKind::DotDotEq => (PatPs::Op(PatOp::RangeIn), PPrec::Range),
|
||||
TKind::Colon => (PatPs::Typed, PPrec::Typed),
|
||||
TKind::Colon => (PatPs::Op(PatOp::Typed), PPrec::Typed),
|
||||
TKind::Comma => (PatPs::Op(PatOp::Tuple), PPrec::Tuple),
|
||||
TKind::Arrow => (PatPs::Op(PatOp::Fn), PPrec::Fn),
|
||||
TKind::Bar => (PatPs::Op(PatOp::Alt), PPrec::Alt),
|
||||
_ => None?,
|
||||
})
|
||||
@@ -335,6 +332,7 @@ impl<'t> Parse<'t> for Pat {
|
||||
|
||||
// Prefix
|
||||
let mut head = match tok.kind {
|
||||
TKind::Fn => return p.consume().parse(PPrec::Fn),
|
||||
TKind::True | TKind::False | TKind::Character | TKind::Integer | TKind::String => {
|
||||
Pat::Lit(p.parse(())?)
|
||||
}
|
||||
@@ -350,8 +348,8 @@ impl<'t> Parse<'t> for Pat {
|
||||
let mut path: FqPath = p.parse(())?;
|
||||
// TODO: make these postfix.
|
||||
match p.peek().map(|t| t.kind) {
|
||||
Ok(TKind::LParen) => Pat::TupStruct(path, p.parse(PPrec::Typed)?),
|
||||
Ok(TKind::LCurly) => Pat::Struct(
|
||||
Ok(TKind::LParen) => Pat::NamedTuple(path, p.parse(PPrec::Typed)?),
|
||||
Ok(TKind::LCurly) if level <= PPrec::Tuple => Pat::NamedStruct(
|
||||
path,
|
||||
p.consume()
|
||||
.opt(PPrec::Alt, TKind::RCurly)?
|
||||
@@ -406,7 +404,12 @@ impl<'t> Parse<'t> for Pat {
|
||||
{
|
||||
let kind = tok.kind;
|
||||
head = match op {
|
||||
PatPs::Typed => Pat::Typed(head.into(), p.consume().parse(())?),
|
||||
PatPs::Op(PatOp::Typed) => {
|
||||
Pat::Op(PatOp::Typed, vec![head, p.consume().parse(PPrec::Max)?])
|
||||
}
|
||||
PatPs::Op(PatOp::Fn) => {
|
||||
Pat::Op(PatOp::Fn, vec![head, p.consume().parse(PPrec::Fn.next())?])
|
||||
}
|
||||
PatPs::Op(op @ (PatOp::RangeEx | PatOp::RangeIn)) => Pat::Op(
|
||||
op,
|
||||
match p.consume().peek().map(|t| t.kind) {
|
||||
@@ -423,59 +426,59 @@ impl<'t> Parse<'t> for Pat {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Ty {
|
||||
type Prec = ();
|
||||
// impl<'t> Parse<'t> for Ty {
|
||||
// type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, level: Self::Prec) -> PResult<Self>
|
||||
where Self: Sized {
|
||||
let &Token { kind, span, .. } = p.peek()?;
|
||||
// fn parse(p: &mut Parser<'t>, level: Self::Prec) -> PResult<Self>
|
||||
// where Self: Sized {
|
||||
// let &Token { kind, span, .. } = p.peek()?;
|
||||
|
||||
// TODO: this is a kinda jank way of error reporting
|
||||
let head = match kind {
|
||||
TKind::Identifier => match p.peek()?.lexeme.str() {
|
||||
Some("_") => p.consume().then(Ty::Infer),
|
||||
_ => Ty::Named(p.parse(())?),
|
||||
},
|
||||
TKind::Amp => Ty::Ref(p.consume().parse(())?),
|
||||
TKind::AmpAmp => Ty::Ref(Box::new(Ty::Ref(p.consume().parse(())?))),
|
||||
TKind::LBrack => {
|
||||
let ty = p.consume().parse(level)?;
|
||||
match p.next()? {
|
||||
Token { kind: TKind::Semi, .. } => {
|
||||
let ty = Ty::Array(ty, p.parse(Prec::Binary.next())?);
|
||||
p.expect(TKind::RBrack)?;
|
||||
ty
|
||||
}
|
||||
Token { kind: TKind::RBrack, .. } => Ty::Slice(ty),
|
||||
tok => Err(ParseError::NotType(tok.kind, tok.span))?,
|
||||
}
|
||||
}
|
||||
TKind::Fn => {
|
||||
p.consume();
|
||||
match p.parse(())? {
|
||||
Ty::Fn(args) => Ty::Fn(args),
|
||||
other @ Ty::Tuple(_) => Ty::Fn(vec![other, Ty::Tuple(vec![])]),
|
||||
other => Ty::Fn(vec![other, Ty::Tuple(vec![])]),
|
||||
}
|
||||
}
|
||||
TKind::LParen => {
|
||||
Ty::Tuple(p.consume().list(vec![], (), TKind::Comma, TKind::RParen)?)
|
||||
}
|
||||
_ => Err(ParseError::NotType(kind, span))?,
|
||||
};
|
||||
// // TODO: this is a kinda jank way of error reporting
|
||||
// let head = match kind {
|
||||
// TKind::Identifier => match p.peek()?.lexeme.str() {
|
||||
// Some("_") => p.consume().then(Ty::Infer),
|
||||
// _ => Ty::Named(p.parse(())?),
|
||||
// },
|
||||
// TKind::Amp => Ty::Ref(p.consume().parse(())?),
|
||||
// TKind::AmpAmp => Ty::Ref(Box::new(Ty::Ref(p.consume().parse(())?))),
|
||||
// TKind::LBrack => {
|
||||
// let ty = p.consume().parse(level)?;
|
||||
// match p.next()? {
|
||||
// Token { kind: TKind::Semi, .. } => {
|
||||
// let ty = Ty::Array(ty, p.parse(Prec::Binary.next())?);
|
||||
// p.expect(TKind::RBrack)?;
|
||||
// ty
|
||||
// }
|
||||
// Token { kind: TKind::RBrack, .. } => Ty::Slice(ty),
|
||||
// tok => Err(ParseError::NotType(tok.kind, tok.span))?,
|
||||
// }
|
||||
// }
|
||||
// TKind::Fn => {
|
||||
// p.consume();
|
||||
// match p.parse(())? {
|
||||
// Ty::Fn(args) => Ty::Fn(args),
|
||||
// other @ Ty::Tuple(_) => Ty::Fn(vec![other, Ty::Tuple(vec![])]),
|
||||
// other => Ty::Fn(vec![other, Ty::Tuple(vec![])]),
|
||||
// }
|
||||
// }
|
||||
// TKind::LParen => {
|
||||
// Ty::Tuple(p.consume().list(vec![], (), TKind::Comma, TKind::RParen)?)
|
||||
// }
|
||||
// _ => Err(ParseError::NotType(kind, span))?,
|
||||
// };
|
||||
|
||||
Ok(match p.next_if(TKind::Arrow).allow_eof()? {
|
||||
Some(Ok(_)) => Ty::Fn(vec![
|
||||
match head {
|
||||
args @ Ty::Tuple(_) => args,
|
||||
arg => Ty::Tuple(vec![arg]),
|
||||
},
|
||||
p.parse(())?,
|
||||
]),
|
||||
_ => head,
|
||||
})
|
||||
}
|
||||
}
|
||||
// Ok(match p.next_if(TKind::Arrow).allow_eof()? {
|
||||
// Some(Ok(_)) => Ty::Fn(vec![
|
||||
// match head {
|
||||
// args @ Ty::Tuple(_) => args,
|
||||
// arg => Ty::Tuple(vec![arg]),
|
||||
// },
|
||||
// p.parse(())?,
|
||||
// ]),
|
||||
// _ => head,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Organizes the precedence hierarchy for syntactic elements
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
@@ -669,73 +672,57 @@ impl<'t> Parse<'t> for Typedef {
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
let tok = p.next()?;
|
||||
match tok.kind {
|
||||
TKind::Enum => Ok(Self(TypedefKind::Enum, p.parse(PPrec::Alt)?)),
|
||||
TKind::Enum => Ok(Self(TypedefKind::Enum, p.parse(PPrec::Tuple)?)),
|
||||
TKind::Struct => Ok(Self(TypedefKind::Struct, p.parse(PPrec::Tuple)?)),
|
||||
_ => Err(ParseError::NotType(tok.kind, tok.span)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Fn {
|
||||
type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
match p.consume().next_if(TKind::Identifier)? {
|
||||
Ok(Token { lexeme, .. }) => Ok(Self(
|
||||
lexeme.string(),
|
||||
p.parse(PPrec::Tuple)?,
|
||||
p.opt_if((), TKind::Arrow)?.unwrap_or(Ty::Tuple(vec![])),
|
||||
p.parse(Prec::Body.next())?,
|
||||
)),
|
||||
_ => Ok(Self(
|
||||
None,
|
||||
Pat::Op(
|
||||
PatOp::Tuple,
|
||||
p.expect(TKind::LParen)?.list(
|
||||
vec![],
|
||||
PPrec::Tuple,
|
||||
TKind::Comma,
|
||||
TKind::RParen,
|
||||
)?,
|
||||
),
|
||||
p.opt_if((), TKind::Arrow)?.unwrap_or(Ty::Tuple(vec![])),
|
||||
p.parse(Prec::Body.next())?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Bind {
|
||||
type Prec = BindKind;
|
||||
|
||||
fn parse(p: &mut Parser<'t>, level: Self::Prec) -> PResult<Self> {
|
||||
if let BindKind::Match = level {
|
||||
// |? Pat => Expr
|
||||
p.next_if(TKind::Bar)?.ok(); // and discard
|
||||
return Ok(Self(
|
||||
match level {
|
||||
BindKind::Match => {
|
||||
// |? Pat => Expr
|
||||
p.next_if(TKind::Bar)?.ok(); // and discard
|
||||
Ok(Self(
|
||||
level,
|
||||
p.parse(PPrec::Alt)?,
|
||||
vec![p.expect(TKind::FatArrow)?.parse(Prec::Body.next())?],
|
||||
))
|
||||
}
|
||||
BindKind::Mod => Ok(Self(
|
||||
level,
|
||||
p.parse(PPrec::Min)?,
|
||||
vec![p.expect(TKind::FatArrow)?.parse(Prec::Body.next())?],
|
||||
));
|
||||
}
|
||||
p.consume().parse(PPrec::Max)?,
|
||||
vec![p.parse(Prec::Body.next())?],
|
||||
)),
|
||||
BindKind::Fn => Ok(Self(
|
||||
level,
|
||||
p.consume().parse(PPrec::Fn)?,
|
||||
vec![p.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![]));
|
||||
}
|
||||
|
||||
// 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(level, pat, vec![body]));
|
||||
}
|
||||
|
||||
// = 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(level, pat, vec![body]));
|
||||
// else Expr
|
||||
Ok(Self(level, pat, vec![body, p.parse(Prec::Body.next())?]))
|
||||
}
|
||||
}
|
||||
|
||||
// else Expr
|
||||
Ok(Self(level, pat, vec![body, p.parse(Prec::Body.next())?]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,16 +740,6 @@ 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> {
|
||||
let ty = p.consume().parse(())?;
|
||||
let body = p.parse(Prec::Body.value())?;
|
||||
Ok(Mod(ty, body))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_for<'t>(p: &mut Parser<'t>, _level: ()) -> PResult<Expr> {
|
||||
// for Pat
|
||||
let pat = p.consume().parse(PPrec::Tuple)?;
|
||||
@@ -830,7 +807,7 @@ fn parse_for<'t>(p: &mut Parser<'t>, _level: ()) -> PResult<Expr> {
|
||||
.anno(fspan),
|
||||
Expr::Bind(Box::new(Bind(
|
||||
BindKind::Match,
|
||||
Pat::TupStruct(
|
||||
Pat::NamedTuple(
|
||||
"Some".into(),
|
||||
Box::new(Pat::Op(PatOp::Tuple, vec![pat])),
|
||||
),
|
||||
@@ -876,12 +853,31 @@ 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::Typedef => Expr::Struct(p.parse(())?),
|
||||
Ps::Let => Expr::Bind(p.parse(BindKind::Let)?),
|
||||
Ps::Const => Expr::Bind(p.parse(BindKind::Const)?),
|
||||
Ps::Static => Expr::Bind(p.parse(BindKind::Static)?),
|
||||
Ps::Mod => Expr::Bind(p.parse(BindKind::Mod)?),
|
||||
Ps::Fn => Expr::Bind(p.parse(BindKind::Fn)?),
|
||||
Ps::Lambda | Ps::Lambda0 => {
|
||||
p.consume();
|
||||
|
||||
let args = if op == Ps::Lambda {
|
||||
p.opt(PPrec::Tuple, TKind::Bar)?
|
||||
.unwrap_or(Pat::Op(PatOp::Tuple, vec![]))
|
||||
} else {
|
||||
Pat::Op(PatOp::Tuple, vec![])
|
||||
};
|
||||
|
||||
let rety = p.opt_if(PPrec::Max, TKind::Arrow)?.unwrap_or(Pat::Ignore);
|
||||
|
||||
Expr::Bind(Box::new(Bind(
|
||||
BindKind::Fn,
|
||||
Pat::Op(PatOp::Fn, vec![args, rety]),
|
||||
vec![p.parse(Prec::Body.next())?],
|
||||
)))
|
||||
}
|
||||
Ps::For => parse_for(p, ())?,
|
||||
Ps::Typedef => Expr::Struct(p.parse(())?),
|
||||
Ps::Mod => Expr::Mod(p.parse(())?),
|
||||
Ps::Op(Op::Match) => parse_match(p)?,
|
||||
Ps::Op(Op::Meta) => Expr::Op(
|
||||
Op::Meta,
|
||||
@@ -917,21 +913,6 @@ impl<'t> Parse<'t> for Expr {
|
||||
];
|
||||
Expr::Op(op, exprs)
|
||||
}
|
||||
Ps::Fn => Expr::Fn(p.parse(())?),
|
||||
Ps::Lambda => Expr::Fn(Box::new(Fn(
|
||||
None,
|
||||
p.consume()
|
||||
.opt(PPrec::Tuple, TKind::Bar)?
|
||||
.unwrap_or(Pat::Op(PatOp::Tuple, vec![])),
|
||||
p.opt_if((), TKind::Arrow)?.unwrap_or(Ty::Infer),
|
||||
p.parse(Prec::Body.next())?,
|
||||
))),
|
||||
Ps::Lambda0 => Expr::Fn(Box::new(Fn(
|
||||
None,
|
||||
Pat::Op(PatOp::Tuple, vec![]),
|
||||
p.consume().opt_if((), TKind::Arrow)?.unwrap_or(Ty::Infer),
|
||||
p.parse(Prec::Body.next())?,
|
||||
))),
|
||||
Ps::DoubleRef => p.consume().parse(prec.next()).map(|Anno(expr, span)| {
|
||||
Expr::Op(
|
||||
Op::Refer,
|
||||
|
||||
Reference in New Issue
Block a user