Actually just three programming languages in a trenchcoat
at string-repr-callable 48 lines 1.5 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, 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}