doughlang: enums, ref patterns, ref types
This commit is contained in:
@@ -279,6 +279,7 @@ enum PatPs {
|
||||
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::Comma => (PatPs::Op(PatOp::Tuple), PPrec::Tuple),
|
||||
TKind::Bar => (PatPs::Op(PatOp::Alt), PPrec::Alt),
|
||||
@@ -297,6 +298,11 @@ impl<'t> Parse<'t> for Pat {
|
||||
Pat::Lit(p.parse(())?)
|
||||
}
|
||||
TKind::Bar => p.consume().parse(level)?,
|
||||
TKind::Amp => Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?]),
|
||||
TKind::AmpAmp => Pat::Op(
|
||||
PatOp::Ref,
|
||||
vec![Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?])],
|
||||
),
|
||||
TKind::Identifier => match tok.lexeme.str() {
|
||||
Some("_") => p.consume().then(Pat::Ignore),
|
||||
_ => {
|
||||
@@ -335,6 +341,13 @@ impl<'t> Parse<'t> for Pat {
|
||||
_ => vec![],
|
||||
},
|
||||
),
|
||||
TKind::DotDotEq => Pat::Op(
|
||||
PatOp::RangeIn,
|
||||
match p.consume().peek()?.kind {
|
||||
TKind::Grave | TKind::Integer | TKind::Character => vec![p.parse(level)?],
|
||||
_ => vec![],
|
||||
},
|
||||
),
|
||||
TKind::LParen => Pat::Op(
|
||||
PatOp::Tuple,
|
||||
p.consume()
|
||||
@@ -384,6 +397,8 @@ impl<'t> Parse<'t> for Ty {
|
||||
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()? {
|
||||
@@ -494,7 +509,7 @@ pub enum Ps {
|
||||
Lit, // Literal
|
||||
Let, // let Pat = Expr
|
||||
Const, // const Pat = Expr
|
||||
Struct, // struct { Pat } | struct ( Pat )
|
||||
Typedef, // struct { Pat } | struct ( Pat )
|
||||
For, // for Pat in Expr Expr else Expr
|
||||
Fn, // fn ( Pat,* ) Expr
|
||||
Lambda0, // || Expr
|
||||
@@ -528,7 +543,7 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
TKind::Module => (Ps::Mod, Prec::Body),
|
||||
TKind::Let => (Ps::Let, Prec::Tuple),
|
||||
TKind::Const => (Ps::Const, Prec::Body),
|
||||
TKind::Struct => (Ps::Struct, Prec::Body),
|
||||
TKind::Struct | TKind::Enum => (Ps::Typedef, Prec::Body),
|
||||
TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
|
||||
TKind::If => (Ps::Op(Op::If), Prec::Body),
|
||||
TKind::While => (Ps::Op(Op::While), Prec::Body),
|
||||
@@ -560,7 +575,7 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
fn from_infix(token: &Token) -> PResult<(Ps, Prec)> {
|
||||
Ok(match token.kind {
|
||||
TKind::Semi => (Ps::Op(Op::Do), Prec::Do), // the inspiration
|
||||
TKind::As => (Ps::Op(Op::As), Prec::Body),
|
||||
TKind::As => (Ps::Op(Op::As), Prec::Max),
|
||||
TKind::Comma => (Ps::Op(Op::Tuple), Prec::Tuple),
|
||||
TKind::Dot => (Ps::Op(Op::Dot), Prec::Project),
|
||||
TKind::AmpAmp => (Ps::Op(Op::LogAnd), Prec::LogAnd),
|
||||
@@ -606,12 +621,16 @@ impl<'t> Parse<'t> for Const {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Struct {
|
||||
impl<'t> Parse<'t> for Typedef {
|
||||
type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
let value = p.consume().parse(PPrec::Min)?;
|
||||
Ok(Self(value))
|
||||
let tok = p.next()?;
|
||||
match tok.kind {
|
||||
TKind::Enum => Ok(Self(TypedefKind::Enum, p.parse(PPrec::Alt)?)),
|
||||
TKind::Struct => Ok(Self(TypedefKind::Struct, p.parse(PPrec::Tuple)?)),
|
||||
_ => Err(ParseError::NotType(tok.kind, tok.span)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,7 +856,7 @@ impl<'t> Parse<'t> for Expr {
|
||||
Ps::Let => Expr::Let(p.parse(())?),
|
||||
Ps::For => parse_for(p, ())?,
|
||||
Ps::Const => Expr::Const(p.parse(())?),
|
||||
Ps::Struct => Expr::Struct(p.parse(())?),
|
||||
Ps::Typedef => Expr::Struct(p.parse(())?),
|
||||
Ps::Match => Expr::Match(p.parse(())?),
|
||||
Ps::Mod => Expr::Mod(p.parse(())?),
|
||||
Ps::Op(Op::Block) => Expr::Op(
|
||||
|
||||
Reference in New Issue
Block a user