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