Actually just three programming languages in a trenchcoat
1use super::*;
2use crate::{Parser, Spanned, token_pattern::TokenPattern};
3use source_span::Span;
4use trilogy_scanner::{Token, TokenType};
5
6#[derive(Clone, Debug, PrettyPrintSExpr)]
7pub struct FunctionHead {
8 pub func: Token,
9 pub name: Identifier,
10 pub parameters: Vec<Pattern>,
11 span: Span,
12}
13
14impl Spanned for FunctionHead {
15 fn span(&self) -> Span {
16 self.span
17 }
18}
19
20impl FunctionHead {
21 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> {
22 let func = parser.expect(TokenType::KwFunc).unwrap();
23 let name = Identifier::parse(parser)?;
24 let mut parameters = vec![];
25 loop {
26 parameters.push(Pattern::parse(parser)?);
27 if Pattern::PREFIX.matches(parser.peek()) {
28 continue;
29 }
30 return Ok(Self {
31 span: func.span.union(parameters.last().unwrap().span()),
32 func,
33 name,
34 parameters,
35 });
36 }
37 }
38}
39
40#[cfg(test)]
41mod test {
42 use super::*;
43
44 test_parse!(funchead_one_param: "func hello x" => FunctionHead::parse => "(FunctionHead _ _ [_])");
45 test_parse!(funchead_multi_param: "func hello x y z" => FunctionHead::parse => "(FunctionHead _ _ [_ _ _])");
46 test_parse!(funchead_pattern_param: "func find f x:xs" => FunctionHead::parse => "(FunctionHead _ _ [_ _])");
47 test_parse_error!(funchead_invalid_param: "func unadd (x + y)" => FunctionHead::parse);
48}