Actually just three programming languages in a trenchcoat
at main 66 lines 2.3 kB view raw
1use super::*; 2use crate::{Parser, Spanned}; 3use source_span::Span; 4use trilogy_scanner::{Token, TokenType::*}; 5 6/// An array comprehension expression. 7/// 8/// ```trilogy 9/// [x for query(x)] 10/// ``` 11#[derive(Clone, Debug)] 12pub struct ArrayComprehension { 13 pub open_bracket: Token, 14 pub expression: Expression, 15 pub r#for: Token, 16 pub query: Query, 17 pub close_bracket: Token, 18 pub span: Span, 19} 20 21impl Spanned for ArrayComprehension { 22 fn span(&self) -> Span { 23 self.span 24 } 25} 26 27impl ArrayComprehension { 28 pub(crate) fn parse_rest( 29 parser: &mut Parser, 30 open_bracket: Token, 31 expression: Expression, 32 ) -> SyntaxResult<Self> { 33 let r#for = parser 34 .expect(KwFor) 35 .map_err(|token| parser.expected(token, "expected `for` in array comprehension"))?; 36 let query = Query::parse(parser)?; 37 let close_bracket = parser 38 .expect(CBrack) 39 .map_err(|token| parser.expected(token, "expected `]` to end array comprehension"))?; 40 let span = open_bracket.span.union(close_bracket.span); 41 Ok(Self { 42 open_bracket, 43 expression, 44 r#for, 45 query, 46 close_bracket, 47 span, 48 }) 49 } 50} 51 52#[cfg(test)] 53mod test { 54 use super::*; 55 56 test_parse!(arraycomp_simple: "[x for x in array]" => Expression::parse => Expression::ArrayComprehension(ArrayComprehension { .. })); 57 test_parse!(arraycomp_complex: "[x:y for lookup(x) and another(y)]" => Expression::parse => Expression::ArrayComprehension(ArrayComprehension { .. })); 58 test_parse!(array_comp_seq: "[{x; y} for lookup(x, y)]" => Expression::parse => Expression::ArrayComprehension(ArrayComprehension { .. })); 59 60 test_parse_error!(arraycomp_no_commas: "[x, y for lookup(x, y)]" => Expression::parse => "only one element may precede the `for` keyword in a comprehension"); 61 test_parse_error!(arraycomp_no_end: "[x for x in array" => Expression::parse => "expected `]` to end array comprehension"); 62 test_parse_error!(arraycomp_no_expression: "[for y]" => Expression::parse); 63 64 test_parse_error!(arraycomp_invalid_query: "[x for y]" => Expression::parse); 65 test_parse_error!(arraycomp_invalid_expr: "[() for x in y]" => Expression::parse); 66}