use super::*; pub struct Func { args: Vec, name: Option, ret: Option, body: Expr, span: Span, } impl Node for Func { fn parse(ctx: &mut ParseCtx) -> Result { let mut name = None; if let Token::Ident(ident) = ctx.expect_peek()? { // yucky let ident = ident.to_string(); ctx.next(); let ident = ctx.ident(ident); name = Some(ident); } ctx.expect(Token::OpenParen)?; let args = ctx.list(Token::Comma, Token::CloseParen)?; let mut ret = None; if ctx.next_if(Token::Arrow) { ret = Some(ctx.parse()?); } let body = Expr::body(ctx)?; Ok(Self { args, ret, body, name, span: ctx.span(), }) } fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { write!(f, "fn")?; if let Some(name) = &self.name { write!(f, " {name}")?; } write!(f, "(")?; if let Some((last, rest)) = self.args.split_last() { for arg in rest { write!(f, "{}, ", arg.dsp(ctx))?; } write!(f, "{}", last.dsp(ctx))?; } write!(f, ") ")?; if let Some(ret) = &self.ret { write!(f, "-> {} ", ret.dsp(ctx))?; } self.body.fmt_body(f, ctx)?; Ok(()) } } impl Func { pub fn ends_with_block(&self) -> bool { self.body.ends_with_block() } }