datex_core/ast/
function.rs1use crate::ast::lexer::Token;
2use crate::ast::r#type::r#type;
3use crate::ast::utils::whitespace;
4use crate::ast::{DatexExpression, DatexParserTrait, TypeExpression};
5use chumsky::prelude::*;
6
7fn return_type<'a>() -> impl DatexParserTrait<'a, Option<TypeExpression>> {
8 just(Token::Arrow)
9 .padded_by(whitespace())
10 .ignore_then(r#type().padded_by(whitespace()))
11 .map(|ty| ty)
12 .or_not()
13}
14
15fn body<'a>(
16 statements: impl DatexParserTrait<'a>,
17) -> impl DatexParserTrait<'a> {
18 statements
19 .clone()
20 .delimited_by(just(Token::LeftParen), just(Token::RightParen))
21}
22
23fn parameter<'a>() -> impl DatexParserTrait<'a, (String, TypeExpression)> {
24 select! { Token::Identifier(name) => name }
25 .then(
26 just(Token::Colon)
27 .padded_by(whitespace())
28 .ignore_then(r#type().padded_by(whitespace())),
29 )
30 .map(|(name, ty)| (name, ty))
31}
32
33fn parameters<'a>() -> impl DatexParserTrait<'a, Vec<(String, TypeExpression)>>
34{
35 parameter()
36 .padded_by(whitespace())
37 .separated_by(just(Token::Comma).padded_by(whitespace()))
38 .collect()
39 .padded_by(whitespace())
40 .delimited_by(just(Token::LeftParen), just(Token::RightParen))
41 .padded_by(whitespace())
42}
43
44pub fn function<'a>(
45 statements: impl DatexParserTrait<'a>,
46) -> impl DatexParserTrait<'a> {
47 just(Token::Function)
50 .padded_by(whitespace())
51 .ignore_then(select! { Token::Identifier(name) => name })
52 .then(parameters())
53 .then(return_type())
54 .then(body(statements))
55 .map(|(((name, params), return_type), body)| {
56 DatexExpression::FunctionDeclaration {
57 name,
58 parameters: params,
59 return_type,
60 body: Box::new(body),
61 }
62 })
63}