ast: struct
This commit is contained in:
@@ -248,7 +248,19 @@ impl<'t> Parse<'t> for Pat {
|
||||
}
|
||||
TKind::Identifier => match tok.lexeme.as_str() {
|
||||
"_" => p.consume().then(Pat::Ignore),
|
||||
_ => Pat::Name(p.take_lexeme().expect("should have Token")),
|
||||
_ => {
|
||||
let name = p.take_lexeme().expect("should have Token");
|
||||
match p.peek().map(|t| t.kind)? {
|
||||
TKind::LParen => Pat::TupStruct(name, p.parse(PPrec::Tuple)?),
|
||||
TKind::LCurly => Pat::Struct(
|
||||
name,
|
||||
p.consume()
|
||||
.opt(PPrec::Tuple, TKind::RCurly)?
|
||||
.unwrap_or_else(|| Box::new(Pat::Tuple(vec![]))),
|
||||
),
|
||||
_ => Pat::Name(name),
|
||||
}
|
||||
}
|
||||
},
|
||||
TKind::Grave => Pat::MetId(p.consume().next()?.lexeme),
|
||||
TKind::DotDot => Pat::Rest(match p.consume().peek_if(TKind::Identifier) {
|
||||
@@ -258,13 +270,13 @@ impl<'t> Parse<'t> for Pat {
|
||||
TKind::LParen => {
|
||||
Pat::Tuple(
|
||||
p.consume()
|
||||
.list(vec![], PPrec::Max, TKind::Comma, TKind::RParen)?,
|
||||
.list(vec![], PPrec::Typed, TKind::Comma, TKind::RParen)?,
|
||||
)
|
||||
}
|
||||
TKind::LBrack => {
|
||||
Pat::Slice(
|
||||
p.consume()
|
||||
.list(vec![], PPrec::Max, TKind::Comma, TKind::RBrack)?,
|
||||
.list(vec![], PPrec::Typed, TKind::Comma, TKind::RBrack)?,
|
||||
)
|
||||
}
|
||||
_ => Err(ParseError::NotPattern(tok.kind, tok.span))?,
|
||||
@@ -415,6 +427,7 @@ pub enum Ps {
|
||||
Lit, // Literal
|
||||
Let, // let Pat = Expr
|
||||
Const, // const Pat = Expr
|
||||
Struct, // struct { Pat } | struct ( Pat )
|
||||
Fn, // fn ( Pat,* ) Expr
|
||||
Lambda0, // || Expr
|
||||
Lambda, // | Pat,* | Expr
|
||||
@@ -444,6 +457,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::Loop => (Ps::Op(Op::Loop), Prec::Body),
|
||||
TKind::If => (Ps::Op(Op::If), Prec::Body),
|
||||
TKind::While => (Ps::Op(Op::While), Prec::Body),
|
||||
@@ -521,23 +535,36 @@ impl<'t> Parse<'t> for Const {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Struct {
|
||||
type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
let value = p.consume().parse(PPrec::Tuple)?;
|
||||
Ok(Self(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Parse<'t> for Fn {
|
||||
type Prec = ();
|
||||
|
||||
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||
Ok(Self(
|
||||
p.consume()
|
||||
.next_if(TKind::Identifier)
|
||||
.map(|id| id.lexeme)
|
||||
.ok(),
|
||||
Pat::Tuple(p.consume_if(TKind::LParen)?.list(
|
||||
vec![],
|
||||
PPrec::Tuple,
|
||||
TKind::Comma,
|
||||
TKind::RParen,
|
||||
)?),
|
||||
p.parse(Prec::Body.next())?,
|
||||
))
|
||||
match p.consume().next_if(TKind::Identifier) {
|
||||
Ok(Token { lexeme, .. }) => Ok(Self(
|
||||
Some(lexeme),
|
||||
p.parse(PPrec::Typed)?,
|
||||
p.parse(Prec::Body.next())?,
|
||||
)),
|
||||
_ => Ok(Self(
|
||||
None,
|
||||
Pat::Tuple(p.consume_if(TKind::LParen)?.list(
|
||||
vec![],
|
||||
PPrec::Tuple,
|
||||
TKind::Comma,
|
||||
TKind::RParen,
|
||||
)?),
|
||||
p.parse(Prec::Body.next())?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,6 +644,7 @@ 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::Struct => 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