Skip to main content

mech_syntax/
expressions.rs

1#[macro_use]
2use crate::*;
3use crate::structures::tuple;
4
5#[cfg(not(feature = "no-std"))] use core::fmt;
6#[cfg(feature = "no-std")] use alloc::fmt;
7#[cfg(feature = "no-std")] use alloc::string::String;
8#[cfg(feature = "no-std")] use alloc::vec::Vec;
9use nom::{
10  IResult,
11  branch::alt,
12  sequence::{tuple as nom_tuple, preceded, pair},
13  combinator::{opt, eof, cut},
14  multi::{many1, many_till, many0, separated_list1,separated_list0},
15  Err,
16  Err::Failure
17};
18
19use std::collections::HashMap;
20use colored::*;
21
22use crate::*;
23
24// Expressions
25// ============================================================================
26
27/*
28Defines how expressions are parsed using a recursive structure hat reflects 
29operator precedence. Parsing begins at the top-level (`formula`) and proceeds 
30through increasingly tightly-binding operations, down to the basic elements 
31like literals and variables.
32
33- `formula`: entry point
34- `l1`: addition and subtraction (`+`, `-`)
35- `l2`: multiplication, division, matrix operations
36- `l3`: exponentiation (`^`)
37- `l4`: logical operators (e.g., `and`, `or`)
38- `l5`: comparisons (e.g., `==`, `<`, `>`)
39- `l6`: table operations (e.g., joins)
40- `l7`: set operations (e.g., union, intersection)
41- `factor`: atomic units (literals, function calls, variables, etc.)
42*/
43
44// expression := set-comprehension | matrix-comprehension | range-expression | formula ;
45pub fn expression(input: ParseString) -> ParseResult<Expression> {
46  let (input, expr) = match set_comprehension(input.clone()) {
47    Ok((input, sc)) => (input, Expression::SetComprehension(Box::new(sc))),
48    Err(_) => match matrix_comprehension(input.clone()) {
49      Ok((input, mc)) => (input, Expression::MatrixComprehension(Box::new(mc))),
50      Err(_) => match range_expression(input.clone()) {
51      Ok((input, rng)) => (input, Expression::Range(Box::new(rng))),
52      Err(_) => match formula(input.clone()) {
53        Ok((input, Factor::Expression(expr))) => (input, *expr),
54        Ok((input, fctr)) => (input, Expression::Formula(fctr)),
55        Err(err) => {
56          return Err(err);},
57      } 
58    }
59    }
60  };
61  Ok((input, expr))
62}
63
64// formula := l1 ;
65pub fn formula(input: ParseString) -> ParseResult<Factor> {
66  let (input, factor) = l1(input)?;
67  Ok((input, factor))
68}
69
70// l1 := l2, (add-sub-operator, l2)* ;
71pub fn l1(input: ParseString) -> ParseResult<Factor> {
72  let (input, lhs) = l2(input)?;
73  let (input, rhs) = many0(pair(add_sub_operator,cut(l2)))(input)?;
74  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
75  Ok((input, factor))
76}
77
78// l2 := l3, (mul-div-operator | matrix-operator, l3)* ;
79pub fn l2(input: ParseString) -> ParseResult<Factor> {
80  let (input, lhs) = l3(input)?;
81  let (input, rhs) = many0(pair(alt((mul_div_operator, matrix_operator)),cut(l3)))(input)?;
82  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
83  Ok((input, factor))
84}
85
86// l3 := l4, (power-operator, l4)* ;
87pub fn l3(input: ParseString) -> ParseResult<Factor> {
88  let (input, lhs) = l4(input)?;
89  let (input, rhs) = many0(pair(power_operator,cut(l4)))(input)?;
90  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
91  Ok((input, factor))
92}
93
94// l4 := l5, (logic-operator, l5)* ;
95pub fn l4(input: ParseString) -> ParseResult<Factor> {
96  let (input, lhs) = l5(input)?;
97  let (input, rhs) = many0(pair(logic_operator,cut(l5)))(input)?;
98  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
99  Ok((input, factor))
100}
101
102// l5 := factor, (comparison-operator, factor)* ;
103pub fn l5(input: ParseString) -> ParseResult<Factor> {
104  let (input, lhs) = l6(input)?;
105  let (input, rhs) = many0(pair(comparison_operator,cut(l6)))(input)?;
106  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
107  Ok((input, factor))
108}
109
110// l6 := factor, (table-operator, factor)* ;
111pub fn l6(input: ParseString) -> ParseResult<Factor> {
112  let (input, lhs) = l7(input)?;
113  let (input, rhs) = many0(pair(table_operator,cut(l7)))(input)?;
114  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
115  Ok((input, factor))
116}
117
118// l7 := factor, (set-operator, factor)* ;
119pub fn l7(input: ParseString) -> ParseResult<Factor> {
120  let (input, lhs) = factor(input)?;
121  let (input, rhs) = many0(pair(set_operator,cut(factor)))(input)?;
122  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
123  Ok((input, factor))
124}
125
126// factor := parenthetical-term | negate-factor | not-factor | structure | function-call | literal | slice | var ;
127pub fn factor(input: ParseString) -> ParseResult<Factor> {
128  let parsers: Vec<(&str, Box<dyn Fn(ParseString) -> ParseResult<Factor>>)> = vec![
129    ("parenthetical_term", Box::new(|i| parenthetical_term(i))),
130    ("negate_factor", Box::new(|i| negate_factor(i))),
131    ("not_factor", Box::new(|i| not_factor(i))),
132    ("matrix_comprehension", Box::new(|i| matrix_comprehension(i).map(|(i, m)| (i, Factor::Expression(Box::new(Expression::MatrixComprehension(Box::new(m)))))))),
133    ("structure", Box::new(|i| structure(i).map(|(i, s)| (i, Factor::Expression(Box::new(Expression::Structure(s))))))),
134    ("function_call", Box::new(|i| function_call(i).map(|(i, f)| (i, Factor::Expression(Box::new(Expression::FunctionCall(f))))))),
135    ("literal", Box::new(|i| literal(i).map(|(i, l)| (i, Factor::Expression(Box::new(Expression::Literal(l))))))),
136    ("slice", Box::new(|i| slice(i).map(|(i, s)| (i, Factor::Expression(Box::new(Expression::Slice(s))))))),
137    ("var", Box::new(|i| var(i).map(|(i, v)| (i, Factor::Expression(Box::new(Expression::Var(v))))))),
138  ];
139  let (input, fctr) = alt_best(input, &parsers)?;
140  let (input, transpose) = opt(transpose)(input)?;
141  let fctr = match transpose {
142    Some(_) => Factor::Transpose(Box::new(fctr)),
143    None => fctr,
144  };
145  Ok((input, fctr))
146}
147
148// parenthetical-term := left-parenthesis, space-tab0, formula, space-tab0, right-parenthesis ;
149pub fn parenthetical_term(input: ParseString) -> ParseResult<Factor> {
150  let msg1 = "parenthetical_term: Expects expression";
151  let msg2 = "parenthetical_term: Expects right parenthesis `)`";
152  let (input, (_, r)) = range(left_parenthesis)(input)?;
153  let (input, _) = space_tab0(input)?;
154  let (input, frmla) = label!(formula, msg1)(input)?;
155  let (input, _) = space_tab0(input)?;
156  let (input, _) = label!(right_parenthesis, msg2, r)(input)?;
157  Ok((input, Factor::Parenthetical(Box::new(frmla))))
158}
159
160// var := identifier, ?kind-annotation ;
161pub fn var(input: ParseString) -> ParseResult<Var> {
162  let ((input, name)) = identifier(input)?;
163  let ((input, kind)) = opt(kind_annotation)(input)?;
164  Ok((input, Var{ name, kind }))
165}
166
167// statement-separator := ";" ;
168pub fn statement_separator(input: ParseString) -> ParseResult<()> {
169  let (input,_) = nom_tuple((whitespace0,semicolon,whitespace0))(input)?;
170  Ok((input, ()))
171}
172
173// Math Expressions
174// ----------------------------------------------------------------------------
175
176// add-sub-operator := add | subtract ;
177pub fn add_sub_operator(input: ParseString) -> ParseResult<FormulaOperator> {
178  let (input, op) = alt((add, subtract))(input)?;
179  Ok((input, FormulaOperator::AddSub(op)))
180}
181
182
183// mul-div-operator := multiply | divide | modulus ;
184pub fn mul_div_operator(input: ParseString) -> ParseResult<FormulaOperator> {
185  let (input, op) = alt((multiply, divide, modulus))(input)?;
186  Ok((input, FormulaOperator::MulDiv(op)))
187}
188
189// power-operator := power ;
190pub fn power_operator(input: ParseString) -> ParseResult<FormulaOperator> {
191  let (input, op) = power(input)?;
192  Ok((input, FormulaOperator::Power(op)))
193}
194
195// negate-factor := "-", factor ;
196pub fn negate_factor(input: ParseString) -> ParseResult<Factor> {
197  let (input, _) = dash(input)?;
198  let (input, expr) = factor(input)?;
199  Ok((input, Factor::Negate(Box::new(expr))))
200}
201
202// not-factor := not, factor ;
203pub fn not_factor(input: ParseString) -> ParseResult<Factor> {
204  let (input, _) = not(input)?;
205  let (input, expr) = factor(input)?;
206  Ok((input, Factor::Not(Box::new(expr))))
207}
208
209// add := "+" ;
210pub fn add(input: ParseString) -> ParseResult<AddSubOp> {
211  let (input, _) = ws0e(input)?;
212  let (input, _) = tag("+")(input)?;
213  let (input, _) = ws0e(input)?;
214  Ok((input, AddSubOp::Add))
215}
216
217pub fn subtract(input: ParseString) -> ParseResult<AddSubOp> {
218  let (input, _) = alt((spaced_subtract, raw_subtract))(input)?;
219  Ok((input, AddSubOp::Sub))
220}
221
222// subtract := "-" ;
223pub fn raw_subtract(input: ParseString) -> ParseResult<AddSubOp> {
224  let (input, _) = pair(is_not(comment_sigil), tag("-"))(input)?;
225  Ok((input, AddSubOp::Sub))
226}
227
228pub fn spaced_subtract(input: ParseString) -> ParseResult<AddSubOp> {
229  let (input, _) = ws1e(input)?;
230  let (input, _) = raw_subtract(input)?;
231  let (input, _) = ws1e(input)?;
232  Ok((input, AddSubOp::Sub))
233}
234
235// multiply := "*" | "×" ;
236pub fn multiply(input: ParseString) -> ParseResult<MulDivOp> {
237  let (input, _) = ws0e(input)?;
238  let (input, _) = pair(is_not(matrix_multiply),alt((tag("*"), tag("×"))))(input)?;
239  let (input, _) = ws0e(input)?;
240  Ok((input, MulDivOp::Mul))
241}
242
243// divide := "/" | "÷" ;
244pub fn divide(input: ParseString) -> ParseResult<MulDivOp> {
245  let (input, _) = ws0e(input)?;
246  let (input, _) = pair(is_not(comment_sigil),alt((tag("/"),tag("÷"))))(input)?;
247  let (input, _) = ws0e(input)?;
248  Ok((input, MulDivOp::Div))
249}
250
251// modulus := "%" ;
252pub fn modulus(input: ParseString) -> ParseResult<MulDivOp> {
253  let (input, _) = ws0e(input)?;
254  let (input, _) = tag("%")(input)?;
255  let (input, _) = ws0e(input)?;
256  Ok((input, MulDivOp::Mod))
257}
258
259// power := "^" ;
260pub fn power(input: ParseString) -> ParseResult<PowerOp> {
261  let (input, _) = ws0e(input)?;
262  let (input, _) = tag("^")(input)?;
263  let (input, _) = ws0e(input)?;
264  Ok((input, PowerOp::Pow))
265}
266
267// Matrix Operations
268// ----------------------------------------------------------------------------
269
270// matrix-operator := matrix-multiply | matrix-solve | dot-product | cross-product ;
271pub fn matrix_operator(input: ParseString) -> ParseResult<FormulaOperator> {
272  let (input, op) = alt((matrix_multiply, matrix_solve, dot_product, cross_product))(input)?;
273  Ok((input, FormulaOperator::Vec(op)))
274}
275
276// matrix-multiply := "**" ;
277pub fn matrix_multiply(input: ParseString) -> ParseResult<VecOp> {
278  let (input, _) = ws0e(input)?;
279  let (input, _) = tag("**")(input)?;
280  let (input, _) = ws0e(input)?;
281  Ok((input, VecOp::MatMul))
282}
283
284// matrix-solve := "\" ;
285pub fn matrix_solve(input: ParseString) -> ParseResult<VecOp> {
286  let (input, _) = ws0e(input)?;
287  let (input, _) = tag("\\")(input)?;
288  let (input, _) = ws0e(input)?;
289  Ok((input, VecOp::Solve))
290}
291
292// dot-product := "·" | "•" ;
293pub fn dot_product(input: ParseString) -> ParseResult<VecOp> {
294  let (input, _) = ws0e(input)?;
295  let (input, _) = alt((tag("·"),tag("•")))(input)?;
296  let (input, _) = ws0e(input)?;
297  Ok((input, VecOp::Dot))
298}
299
300// cross-product := "⨯" ;
301pub fn cross_product(input: ParseString) -> ParseResult<VecOp> {
302  let (input, _) = ws0e(input)?;
303  let (input, _) = tag("⨯")(input)?;
304  let (input, _) = ws0e(input)?;
305  Ok((input, VecOp::Cross))
306}
307
308// transpose := "'" ;
309pub fn transpose(input: ParseString) -> ParseResult<()> {
310  let (input, _) = tag("'")(input)?;
311  Ok((input, ()))
312}
313
314// Range Expressions
315// ----------------------------------------------------------------------------
316
317// range := formula, range-operator, formula, (range-operator, formula)? ;
318pub fn range_expression(input: ParseString) -> ParseResult<RangeExpression> {
319  let (input, start) = formula(input)?;
320  let (input, op) = range_operator(input)?;
321  let (input, x) = formula(input)?;
322  let (input, y) = opt(nom_tuple((range_operator,formula)))(input)?;
323  let range = match y {
324    Some((op2,terminal)) => RangeExpression{start, increment: Some((op,x)), operator: op2, terminal},
325    None => RangeExpression{start, increment: None, operator: op, terminal: x},
326  };
327  Ok((input, range))
328}
329
330// range-inclusive := "..=" ;
331pub fn range_inclusive(input: ParseString) -> ParseResult<RangeOp> {
332  let (input, _) = tag("..=")(input)?;
333  Ok((input, RangeOp::Inclusive))
334}
335
336// range-exclusive := ".." ;
337pub fn range_exclusive(input: ParseString) -> ParseResult<RangeOp> {
338  let (input, _) = tag("..")(input)?;
339  Ok((input, RangeOp::Exclusive))
340}
341
342// range-operator := range-inclusive | range-exclusive ;
343pub fn range_operator(input: ParseString) -> ParseResult<RangeOp> {
344  let (input, op) = alt((range_inclusive,range_exclusive))(input)?;
345  Ok((input, op))
346}
347
348// Comparison expressions
349// ----------------------------------------------------------------------------
350
351// comparison-operator := strict-equal | strict-not-equal | not-equal | equal-to | greater-than-equal | greater-than | less-than-equal | less-than ;
352pub fn comparison_operator(input: ParseString) -> ParseResult<FormulaOperator> {
353  let (input, op) = alt((strict_equal, strict_not_equal, not_equal, equal_to, greater_than_equal, greater_than, less_than_equal, less_than))(input)?;
354  Ok((input, FormulaOperator::Comparison(op)))
355}
356
357// not-equal := "!=" | "¬=" | "≠" ;
358pub fn not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
359  let (input, _) = ws0e(input)?;
360  let (input, _) = alt((tag("!="),tag("¬="),tag("≠")))(input)?;
361  let (input, _) = ws0e(input)?;
362  Ok((input, ComparisonOp::NotEqual))
363}
364
365// equal-to := "==" ;
366pub fn equal_to(input: ParseString) -> ParseResult<ComparisonOp> {
367  let (input, _) = ws0e(input)?;
368  let (input, _) = alt((tag("=="),tag("⩵")))(input)?;
369  let (input, _) = ws0e(input)?;
370  Ok((input, ComparisonOp::Equal))
371}
372
373// strict-not-equal := "=!=" | "=¬=" ;
374pub fn strict_not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
375  let (input, _) = ws0e(input)?;
376  let (input, _) = alt((tag("=!="),tag("=¬=")))(input)?;
377  let (input, _) = ws0e(input)?;
378  Ok((input, ComparisonOp::StrictNotEqual))
379}
380
381// strict-equal := "=:=" | "≡" ;
382pub fn strict_equal(input: ParseString) -> ParseResult<ComparisonOp> {
383  let (input, _) = ws0e(input)?;
384  let (input, _) = alt((tag("=:="),tag("≡")))(input)?;
385  let (input, _) = ws0e(input)?;
386  Ok((input, ComparisonOp::StrictEqual))
387}
388
389// greater-than := ">" ;
390pub fn greater_than(input: ParseString) -> ParseResult<ComparisonOp> {
391  let (input, _) = ws0e(input)?;
392  let (input, _) = tag(">")(input)?;
393  let (input, _) = ws0e(input)?;
394  Ok((input, ComparisonOp::GreaterThan))
395}
396
397// less_than := "<" ;
398pub fn less_than(input: ParseString) -> ParseResult<ComparisonOp> {
399  let (input, _) = ws0e(input)?;
400  let (input, _) = is_not(tag("<-"))(input)?;
401  let (input, _) = tag("<")(input)?;
402  let (input, _) = ws0e(input)?;
403  Ok((input, ComparisonOp::LessThan))
404}
405
406// greater-than-equal := ">=" | "≥" ;
407pub fn greater_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
408  let (input, _) = ws0e(input)?;
409  let (input, _) = alt((tag(">="),tag("≥")))(input)?;
410  let (input, _) = ws0e(input)?;
411  Ok((input, ComparisonOp::GreaterThanEqual))
412}
413
414// less-than-equal := "<=" | "≤" ;
415pub fn less_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
416  let (input, _) = ws0e(input)?;
417  let (input, _) = alt((tag("<="),tag("≤")))(input)?;
418  let (input, _) = ws0e(input)?;
419  Ok((input, ComparisonOp::LessThanEqual))
420}
421
422// Logic expressions
423// ----------------------------------------------------------------------------
424
425// logic-operator := and | or | xor ;
426pub fn logic_operator(input: ParseString) -> ParseResult<FormulaOperator> {
427  let (input, op) = alt((and, or, xor))(input)?;
428  Ok((input, FormulaOperator::Logic(op)))
429}
430
431// or := "|" ;
432pub fn or(input: ParseString) -> ParseResult<LogicOp> {
433  let (input, _) = ws0e(input)?;
434  let (input, _) = alt((tag("||"), tag("∨"), tag("⋁")))(input)?;
435  let (input, _) = ws0e(input)?;
436  Ok((input, LogicOp::Or))
437}
438
439// and := "&" ;
440pub fn and(input: ParseString) -> ParseResult<LogicOp> {
441  let (input, _) = ws0e(input)?;
442  let (input, _) = alt((tag("&&"), tag("∧"), tag("⋀")))(input)?;
443  let (input, _) = ws0e(input)?;
444  Ok((input, LogicOp::And))
445}
446
447// not := "!" | "¬" ;
448pub fn not(input: ParseString) -> ParseResult<LogicOp> {
449  let (input, _) = alt((tag("!"), tag("¬")))(input)?;
450  Ok((input, LogicOp::Not))
451}
452
453// xor := "xor" | "⊕" | "⊻" ;
454pub fn xor(input: ParseString) -> ParseResult<LogicOp> {
455  let (input, _) = ws0e(input)?;
456  let (input, _) = alt((tag("^^"), tag("⊕"), tag("⊻")))(input)?;
457  let (input, _) = ws0e(input)?;
458  Ok((input, LogicOp::Xor))
459}
460
461// Table Operations
462// ----------------------------------------------------------------------------
463
464// table-operator := join | left-join | right-join | full-join | left-semi-join | left-anti-join ;
465fn table_operator(input: ParseString) -> ParseResult<FormulaOperator> {
466  let (input, op) = alt((join,left_join,right_join,full_join,left_semi_join,left_anti_join))(input)?;
467  Ok((input, FormulaOperator::Table(op)))
468}
469
470// join := "⋈" ;
471fn join(input: ParseString) -> ParseResult<TableOp> {
472  let (input, _) = ws0e(input)?;
473  let (input, _) = tag("⋈")(input)?;
474  let (input, _) = ws0e(input)?;
475  Ok((input, TableOp::InnerJoin))
476}
477
478// left-join := "⟕" ;
479fn left_join(input: ParseString) -> ParseResult<TableOp> {
480  let (input, _) = ws0e(input)?;
481  let (input, _) = tag("⟕")(input)?;
482  let (input, _) = ws0e(input)?;
483  Ok((input, TableOp::LeftOuterJoin))
484}
485
486// right-join := "⟖" ;
487fn right_join(input: ParseString) -> ParseResult<TableOp> {
488  let (input, _) = ws0e(input)?;
489  let (input, _) = tag("⟖")(input)?;
490  let (input, _) = ws0e(input)?;
491  Ok((input, TableOp::RightOuterJoin))
492}
493
494// full-join := "⟗" ;
495fn full_join(input: ParseString) -> ParseResult<TableOp> {
496  let (input, _) = ws0e(input)?;
497  let (input, _) = tag("⟗")(input)?;
498  let (input, _) = ws0e(input)?;
499  Ok((input, TableOp::FullOuterJoin))
500}
501
502// left-semi-join := "⋉" ;
503fn left_semi_join(input: ParseString) -> ParseResult<TableOp> {
504  let (input, _) = ws0e(input)?;
505  let (input, _) = tag("⋉")(input)?;
506  let (input, _) = ws0e(input)?;
507  Ok((input, TableOp::LeftSemiJoin))
508}
509
510// left-anti-join := "▷" ;
511fn left_anti_join(input: ParseString) -> ParseResult<TableOp> {
512  let (input, _) = ws0e(input)?;
513  let (input, _) = tag("▷")(input)?;
514  let (input, _) = ws0e(input)?;
515  Ok((input, TableOp::LeftAntiJoin))
516}
517
518
519// Set Operations
520// ----------------------------------------------------------------------------
521
522// set-operator := union | intersection | difference | complement | subset | superset | proper-subset | proper-superset | element-of | not-element-of | symmetric-difference ;
523pub fn set_operator(input: ParseString) -> ParseResult<FormulaOperator> {
524  let (input, op) = alt((union_op,intersection,difference,complement,subset,superset,proper_subset,proper_superset,element_of,not_element_of,symmetric_difference))(input)?;
525  Ok((input, FormulaOperator::Set(op)))
526}
527
528// union := "∪" ;
529pub fn union_op(input: ParseString) -> ParseResult<SetOp> {
530  let (input, _) = ws0e(input)?;
531  let (input, _) = tag("∪")(input)?;
532  let (input, _) = ws0e(input)?;
533  Ok((input, SetOp::Union))
534}
535
536// intersection := "∩" ;
537pub fn intersection(input: ParseString) -> ParseResult<SetOp> {
538  let (input, _) = ws0e(input)?;
539  let (input, _) = tag("∩")(input)?;
540  let (input, _) = ws0e(input)?;
541  Ok((input, SetOp::Intersection))
542}
543
544// difference := "∖" ;
545pub fn difference(input: ParseString) -> ParseResult<SetOp> {
546  let (input, _) = ws0e(input)?;
547  let (input, _) = tag("∖")(input)?;
548  let (input, _) = ws0e(input)?;
549  Ok((input, SetOp::Difference))
550}
551
552// complement := "∁" ;
553pub fn complement(input: ParseString) -> ParseResult<SetOp> {
554  let (input, _) = ws0e(input)?;
555  let (input, _) = tag("∁")(input)?;
556  let (input, _) = ws0e(input)?;
557  Ok((input, SetOp::Complement))
558}
559
560// subset := "⊆" ;
561pub fn subset(input: ParseString) -> ParseResult<SetOp> { 
562  let (input, _) = ws0e(input)?;
563  let (input, _) = tag("⊆")(input)?;
564  let (input, _) = ws0e(input)?;
565  Ok((input, SetOp::Subset))
566}
567
568// superset := "⊇" ;
569pub fn superset(input: ParseString) -> ParseResult<SetOp> {
570  let (input, _) = ws0e(input)?;
571  let (input, _) = tag("⊇")(input)?;
572  let (input, _) = ws0e(input)?;
573  Ok((input, SetOp::Superset))
574}
575
576// proper-subset := "⊊" ;
577pub fn proper_subset(input: ParseString) -> ParseResult<SetOp> {
578  let (input, _) = ws0e(input)?;
579  let (input, _) = alt((tag("⊊"), tag("⊂")))(input)?;
580  let (input, _) = ws0e(input)?;
581  Ok((input, SetOp::ProperSubset))
582}
583
584// proper-superset := "⊋" ;
585pub fn proper_superset(input: ParseString) -> ParseResult<SetOp> {
586  let (input, _) = ws0e(input)?;
587  let (input, _) = alt((tag("⊋"), tag("⊃")))(input)?;
588  let (input, _) = ws0e(input)?;
589  Ok((input, SetOp::ProperSuperset))
590}
591
592// element-of := "∈" ;
593pub fn element_of(input: ParseString) -> ParseResult<SetOp> { 
594  let (input, _) = ws0e(input)?;
595  let (input, _) = tag("∈")(input)?;
596  let (input, _) = ws0e(input)?;
597  Ok((input, SetOp::ElementOf))
598}
599
600// not-element-of := "∉" ;
601pub fn not_element_of(input: ParseString) -> ParseResult<SetOp> {
602  let (input, _) = ws0e(input)?;
603  let (input, _) = tag("∉")(input)?;
604  let (input, _) = ws0e(input)?;
605  Ok((input, SetOp::NotElementOf))
606}
607
608// symmetric-difference := "Δ" ;
609pub fn symmetric_difference(input: ParseString) -> ParseResult<SetOp> {
610  let (input, _) = ws1e(input)?;
611  let (input, _) = tag("Δ")(input)?;
612  let (input, _) = ws1e(input)?;
613  Ok((input, SetOp::SymmetricDifference))
614}
615
616// Set Comprehensions
617// ----------------------------------------------------------------------------
618
619// set-comprehension := "{", formula, "|", [set-qualifier, ","], "}" ;
620pub fn set_comprehension(input: ParseString) -> ParseResult<SetComprehension> {
621  let (input, _) = left_brace(input)?;
622  let (input, _) = space_tab0(input)?;
623  let (input, expr) = expression(input)?;
624  let (input, _) = space_tab0(input)?;
625  let (input, _) = bar(input)?;
626  let (input, _) = space_tab0(input)?;
627  let (input, quals) = separated_list1(list_separator, comprehension_qualifier)(input)?;
628  let (input, _) = space_tab0(input)?;
629  let (input, _) = right_brace(input)?;
630  Ok((input, SetComprehension{ expression: expr, qualifiers: quals }))
631}
632
633// matrix-comprehension := "[", expression, "|", [matrix-qualifier, ","], "]" ;
634pub fn matrix_comprehension(input: ParseString) -> ParseResult<MatrixComprehension> {
635  let (input, _) = left_bracket(input)?;
636  let (input, _) = space_tab0(input)?;
637  let (input, expr) = expression(input)?;
638  let (input, _) = space_tab0(input)?;
639  let (input, _) = bar(input)?;
640  let (input, _) = space_tab0(input)?;
641  let (input, quals) = separated_list1(list_separator, comprehension_qualifier)(input)?;
642  let (input, _) = space_tab0(input)?;
643  let (input, _) = right_bracket(input)?;
644  Ok((input, MatrixComprehension{ expression: expr, qualifiers: quals }))
645}
646
647// set-qualifier := generator | expression | variable-define  ;
648pub fn comprehension_qualifier(input: ParseString) -> ParseResult<ComprehensionQualifier> {
649  match generator(input.clone()) {
650    Ok((input, generator)) => Ok((input, generator)),
651    Err(_) => match variable_define(input.clone()) {
652      Ok((input, var_def)) => Ok((input, ComprehensionQualifier::Let(var_def))),
653      Err(_) => {
654        let (input, expr) = expression(input)?;
655        Ok((input, ComprehensionQualifier::Filter(expr)))
656      }
657    }
658  }
659}
660
661// generator := pattern, "<-", expression ;
662pub fn generator(input: ParseString) -> ParseResult<ComprehensionQualifier> {
663  let (input, ptrn) = pattern(input)?;
664  let (input, _) = space_tab0(input)?;
665  let (input, _) = cut(tag("<-"))(input)?;
666  let (input, _) = space_tab0(input)?;
667  let (input, expr) = expression(input)?;
668  Ok((input, ComprehensionQualifier::Generator((ptrn, expr))))
669}
670
671// Subscript Operations
672// ----------------------------------------------------------------------------
673
674// subscript := (swizzle-subscript | dot-subscript-int | dot-subscript | bracket-subscript | brace-subscript)+ ; 
675pub fn subscript(input: ParseString) -> ParseResult<Vec<Subscript>> {
676  let (input, subscripts) = many1(alt((swizzle_subscript,dot_subscript,dot_subscript_int,bracket_subscript,brace_subscript)))(input)?;
677  Ok((input, subscripts))
678}
679
680// slice := identifier, subscript ;
681pub fn slice(input: ParseString) -> ParseResult<Slice> {
682  let (input, name) = identifier(input)?;
683  let (input, ixes) = subscript(input)?;
684  Ok((input, Slice{name, subscript: ixes}))
685}
686
687// slice-ref := identifier, subscript? ;
688pub fn slice_ref(input: ParseString) -> ParseResult<SliceRef> {
689  let (input, name) = identifier(input)?;
690  let (input, ixes) = opt(subscript)(input)?;
691  Ok((input, SliceRef{name, subscript: ixes}))
692}
693
694// swizzle-subscript := ".", identifier, ",", list1(",", identifier) ;
695pub fn swizzle_subscript(input: ParseString) -> ParseResult<Subscript> {
696  let (input, _) = period(input)?;
697  let (input, first) = identifier(input)?;
698  let (input, _) = comma(input)?;
699  let (input, mut name) = separated_list1(tag(","),identifier)(input)?;
700  let mut subscripts = vec![first];
701  subscripts.append(&mut name);
702  Ok((input, Subscript::Swizzle(subscripts)))
703}
704
705// dot-subscript := ".", identifier ;
706pub fn dot_subscript(input: ParseString) -> ParseResult<Subscript> {
707  let (input, _) = period(input)?;
708  let (input, name) = identifier(input)?;
709  Ok((input, Subscript::Dot(name)))
710}
711
712// dot-subscript-int := ".", integer-literal ;
713pub fn dot_subscript_int(input: ParseString) -> ParseResult<Subscript> {
714  let (input, _) = period(input)?;
715  let (input, name) = integer_literal(input)?;
716  Ok((input, Subscript::DotInt(name)))
717}
718
719// bracket-subscript := "[", list1(",", select-all | range-subscript | formula-subscript), "]" ;
720pub fn bracket_subscript(input: ParseString) -> ParseResult<Subscript> {
721  let (input, _) = left_bracket(input)?;
722  let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
723  let (input, _) = right_bracket(input)?;
724  Ok((input, Subscript::Bracket(subscripts)))
725}
726
727// brace-subscript := "{", list1(",", select-all | range-subscript | formula-subscript), "}" ;
728pub fn brace_subscript(input: ParseString) -> ParseResult<Subscript> {
729  let (input, _) = left_brace(input)?;
730  let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
731  let (input, _) = right_brace(input)?;
732  Ok((input, Subscript::Brace(subscripts)))
733}
734
735// select-all := ":" ;
736pub fn select_all(input: ParseString) -> ParseResult<Subscript> {
737  let (input, lhs) = colon(input)?;
738  Ok((input, Subscript::All))
739}
740
741// formula-subscript := formula ;
742pub fn formula_subscript(input: ParseString) -> ParseResult<Subscript> {
743  let (input, factor) = formula(input)?;
744  Ok((input, Subscript::Formula(factor)))
745}
746
747// range-subscript := range-expression ;
748pub fn range_subscript(input: ParseString) -> ParseResult<Subscript> {
749  let (input, rng) = range_expression(input)?;
750  Ok((input, Subscript::Range(rng)))
751}