Actually just three programming languages in a trenchcoat
1use super::*;
2use crate::{Parser, Spanned};
3use source_span::Span;
4use trilogy_scanner::TokenType;
5
6#[derive(Clone, Debug)]
7pub struct FunctionDefinition {
8 pub head: FunctionHead,
9 pub body: Expression,
10 pub span: Span,
11}
12
13impl Spanned for FunctionDefinition {
14 fn span(&self) -> Span {
15 self.span
16 }
17}
18
19impl FunctionDefinition {
20 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> {
21 let head = FunctionHead::parse(parser)?;
22 parser
23 .expect(TokenType::OpEq)
24 .map_err(|token| parser.expected(token, "expected `=` in function definition"))?;
25 let body = Expression::parse(parser)?;
26 Ok(FunctionDefinition {
27 span: head.span().union(body.span()),
28 head,
29 body,
30 })
31 }
32}
33
34#[cfg(test)]
35mod test {
36 use super::*;
37
38 test_parse!(func_one_param: "func hello x = x" => FunctionDefinition::parse => FunctionDefinition { .. });
39 test_parse!(func_multi_param: "func hello x y z = x + y + z" => FunctionDefinition::parse => FunctionDefinition { .. });
40 test_parse!(func_pattern_param: "func find f x:xs = if f x then x else find f xs" => FunctionDefinition::parse => FunctionDefinition { .. });
41 test_parse_error!(func_no_params: "func three = 3" => FunctionDefinition::parse);
42 test_parse_error!(func_invalid_body: "func hello x = let y = 5" => FunctionDefinition::parse);
43 test_parse_error!(func_missing_body: "func hello x" => FunctionDefinition::parse => "expected `=` in function definition");
44}