Actually just three programming languages in a trenchcoat
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}