working on function parser

This commit is contained in:
LunarAkai 2025-08-10 15:06:08 +02:00
commit 3200a352d3
3 changed files with 56 additions and 34 deletions

View file

@ -42,5 +42,8 @@ pub enum Expr {
// fun helloWorld() { ... } // fun helloWorld() { ... }
FunctionExpr(Function), FunctionExpr(Function),
// ->
ReturnExpr,
Error, Error,
} }

View file

@ -145,7 +145,7 @@ pub struct Binary {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Function { pub struct Function {
pub name: String, pub name: String,
pub params: Option<Vec<(Identifier, Type)>>, pub params: Option<Vec<(String, Type)>>,
pub return_type: Option<Type>, pub return_type: Option<Type>,
pub body: Option<BlockExpression>, pub body: Option<BlockExpression>,
pub body_expr: Option<Box<Expr>>, // ' -> (return)' pub body_expr: Option<Box<Expr>>, // ' -> (return)'

View file

@ -28,10 +28,7 @@ pub fn parse(source: &str) -> Result<Vec<Expr>, Vec<Rich<'_, Token>>> {
.spanned() .spanned()
.map(|(token, span)| (token.unwrap_or(Token::Error), span.into())); .map(|(token, span)| (token.unwrap_or(Token::Error), span.into()));
let end_of_input: SimpleSpan = (0..source.len()).into(); let end_of_input: SimpleSpan = (0..source.len()).into();
let token_stream = Stream::from_iter(token_iter) let token_stream = Stream::from_iter(token_iter).map(
// Tell chumsky to split the (Token, SimpleSpan) stream into its parts so that it can handle the spans for us
// This involves giving chumsky an 'end of input' span: we just use a zero-width span at the end of the string
.map(
(0..end_of_input.into_iter().len()).into(), (0..end_of_input.into_iter().len()).into(),
|(t, s): (_, _)| (t, s), |(t, s): (_, _)| (t, s),
); );
@ -120,35 +117,57 @@ where
}) })
}); });
let type_parser = choice((
just(Token::IntType).to(Type::Integer),
just(Token::FloatType).to(Type::Float),
just(Token::BoolType).to(Type::Bool),
just(Token::StringType).to(Type::String),
));
let return_type_parser = just(Token::Colon).ignore_then(type_parser.clone()).or_not();
//---------------------------------------------------------------------------------------
// Function Parser
//---------------------------------------------------------------------------------------
let fun = just(Token::Fun) let fun = just(Token::Fun)
.ignore_then(ident.clone()) .ignore_then(ident) // function name
.then_ignore(just(Token::LParen))
//.then(param_parser().separated_by(just(Token::Comma)).or_not().map(|p| p.unwrap_or_default()))
.then_ignore(just(Token::RParen))
.then( .then(
just(Token::LBrace) ident
.then_ignore(just(Token::NewLine).or_not()) .then_ignore(just(Token::Colon))
.ignore_then(decl.clone().repeated()) .then(type_parser.clone())
.then_ignore(just(Token::RBrace)) .separated_by(just(Token::Comma))
.map(|stmts| (Some(stmts), None)) .allow_trailing()
.or(just(Token::Return) .collect::<Vec<_>>()
.ignore_then(expr.clone()) .delimited_by(just(Token::LParen), just(Token::RParen))
.map(|e| (None, Some(e)))), .or_not(),
) )
.then_ignore(just(Token::NewLine).or_not()) .then(return_type_parser.clone())
.map(|(name, (body, body_expr))| { .then_ignore(just(Token::LBrace))
.then_ignore(just(Token::NewLine).repeated())
.then(
expr.clone()
.then_ignore(just(Token::NewLine))
.repeated()
.collect::<Vec<_>>(),
)
.then_ignore(just(Token::RBrace))
.map(|(((name, params), return_ty), stmts)| {
Expr::FunctionExpr(Function { Expr::FunctionExpr(Function {
name, name: name,
params: None, params,
return_type: None, return_type: return_ty,
body: None, body: Some(stmts),
body_expr: None, body_expr: None,
}) })
}); });
var.or(fun).or(expr) var.or(fun).or(expr)
}); });
decl.repeated().collect() decl.clone()
.then_ignore(just(Token::NewLine).repeated())
.repeated()
.collect()
} }
#[cfg(test)] #[cfg(test)]
@ -232,9 +251,9 @@ mod tests {
empty_fun.clone().unwrap(), empty_fun.clone().unwrap(),
vec![Expr::FunctionExpr(Function { vec![Expr::FunctionExpr(Function {
name: String::from("helloWorld"), name: String::from("helloWorld"),
params: None, params: Some([].to_vec()),
return_type: None, return_type: None,
body: None, body: Some([].to_vec()),
body_expr: None, body_expr: None,
})] })]
); );
@ -250,9 +269,9 @@ mod tests {
empty_fun_with_new_lines.clone().unwrap(), empty_fun_with_new_lines.clone().unwrap(),
vec![Expr::FunctionExpr(Function { vec![Expr::FunctionExpr(Function {
name: String::from("emptyMulLines"), name: String::from("emptyMulLines"),
params: None, params: Some([].to_vec()),
return_type: None, return_type: None,
body: None, body: Some([].to_vec()),
body_expr: None, body_expr: None,
})] })]
); );
@ -265,13 +284,13 @@ mod tests {
", ",
); );
assert_eq!( assert_eq!(
empty_fun_with_new_lines.clone().unwrap(), fun_that_returns_int.clone().unwrap(),
vec![Expr::FunctionExpr(Function { vec![Expr::FunctionExpr(Function {
name: String::from("returnsInt"), name: String::from("returnsInt"),
params: None, params: None,
return_type: Some(Type::Integer), return_type: Some(Type::Integer),
body: None, body: Some(vec![Expr::IntLiteral(12)]),
body_expr: Some(Box::new(Expr::IntLiteral(12))), body_expr: Some(Box::new(Expr::ReturnExpr)),
})] })]
) )
} }