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