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