Actually just three programming languages in a trenchcoat
at string-repr-callable 55 lines 1.8 kB view raw
1use super::*; 2use crate::{Parser, Spanned}; 3use source_span::Span; 4use trilogy_scanner::{Token, TokenType::*}; 5 6/// An element unification (`in`) query. 7/// 8/// ```trilogy 9/// pattern in expression 10/// ``` 11#[derive(Clone, Debug, PrettyPrintSExpr)] 12pub struct ElementUnification { 13 pub pattern: Pattern, 14 pub r#in: Token, 15 pub expression: Expression, 16 span: Span, 17} 18 19impl Spanned for ElementUnification { 20 fn span(&self) -> Span { 21 self.span 22 } 23} 24 25impl ElementUnification { 26 pub(crate) fn parse(parser: &mut Parser, pattern: Pattern) -> SyntaxResult<Self> { 27 let r#in = parser.expect(KwIn).unwrap(); 28 let expression = Expression::parse_parameter_list(parser)?.map_err(|patt| { 29 let error = SyntaxError::new( 30 patt.span(), 31 "expected an expression after `in`, but found a pattern", 32 ); 33 parser.error(error.clone()); 34 error 35 })?; 36 Ok(Self { 37 span: pattern.span().union(expression.span()), 38 pattern, 39 r#in, 40 expression, 41 }) 42 } 43} 44 45#[cfg(test)] 46mod test { 47 use super::*; 48 49 test_parse!(element_keyword: "x in []" => Query::parse => "(Query::Element (ElementUnification _ _ _))"); 50 test_parse!(element_pattern: "5 in [5]" => Query::parse => "(Query::Element (ElementUnification _ _ _))"); 51 test_parse!(element_identifier: "x in xs" => Query::parse => "(Query::Element (ElementUnification _ _ _))"); 52 test_parse!(element_collection: "[..a] in [[], [1]]" => Query::parse => "(Query::Element (ElementUnification _ _ _))"); 53 test_parse_error!(element_no_expr: "a b in 123" => Query::parse); 54 test_parse_error!(element_invalid_expr: "a in {}" => Query::parse); 55}