mech_syntax/
expressions.rs

1#[macro_use]
2use crate::*;
3
4#[cfg(not(feature = "no-std"))] use core::fmt;
5#[cfg(feature = "no-std")] use alloc::fmt;
6#[cfg(feature = "no-std")] use alloc::string::String;
7#[cfg(feature = "no-std")] use alloc::vec::Vec;
8use nom::{
9  IResult,
10  branch::alt,
11  sequence::tuple as nom_tuple,
12  combinator::{opt, eof},
13  multi::{many1, many_till, many0, separated_list1,separated_list0},
14  Err,
15  Err::Failure
16};
17
18use std::collections::HashMap;
19use colored::*;
20
21use crate::*;
22
23// #### Expressions
24
25// ##### Math expressions
26
27// parenthetical_term := left_parenthesis, formula, right_parenthesis ;
28pub fn parenthetical_term(input: ParseString) -> ParseResult<Factor> {
29  let msg1 = "Expects expression";
30  let msg2 = "Expects right parenthesis ')'";
31  let (input, (_, r)) = range(left_parenthesis)(input)?;
32  let (input, frmla) = label!(formula, msg1)(input)?;
33  let (input, _) = label!(right_parenthesis, msg2, r)(input)?;
34  Ok((input, Factor::Parenthetical(Box::new(frmla))))
35}
36
37// negate_factor := "-", factor ;
38pub fn negate_factor(input: ParseString) -> ParseResult<Factor> {
39  let (input, _) = dash(input)?;
40  let (input, expr) = factor(input)?;
41  Ok((input, Factor::Negate(Box::new(expr))))
42}
43
44// not_factor := "not", factor ;
45pub fn not_factor(input: ParseString) -> ParseResult<Factor> {
46  let (input, _) = not(input)?;
47  let (input, expr) = factor(input)?;
48  Ok((input, Factor::Not(Box::new(expr))))
49}
50
51// add := "+" ;
52pub fn add(input: ParseString) -> ParseResult<AddSubOp> {
53  let (input, _) = ws1e(input)?;
54  let (input, _) = tag("+")(input)?;
55  let (input, _) = ws1e(input)?;
56  Ok((input, AddSubOp::Add))
57}
58
59// subtract := "-" ;
60pub fn subtract(input: ParseString) -> ParseResult<AddSubOp> {
61  let (input, _) = ws1e(input)?;
62  let (input, _) = tag("-")(input)?;
63  let (input, _) = ws1e(input)?;
64  Ok((input, AddSubOp::Sub))
65}
66
67// multiply := "*" ;
68pub fn multiply(input: ParseString) -> ParseResult<MulDivOp> {
69  let (input, _) = ws1e(input)?;
70  let (input, _) = tag("*")(input)?;
71  let (input, _) = ws1e(input)?;
72  Ok((input, MulDivOp::Mul))
73}
74
75// divide := "/" ;
76pub fn divide(input: ParseString) -> ParseResult<MulDivOp> {
77  let (input, _) = ws1e(input)?;
78  let (input, _) = tag("/")(input)?;
79  let (input, _) = ws1e(input)?;
80  Ok((input, MulDivOp::Div))
81}
82
83// modulus := "%" ;
84pub fn modulus(input: ParseString) -> ParseResult<MulDivOp> {
85  let (input, _) = ws1e(input)?;
86  let (input, _) = tag("%")(input)?;
87  let (input, _) = ws1e(input)?;
88  Ok((input, MulDivOp::Mod))
89}
90
91// matrix_multiply := "**" ;
92pub fn matrix_multiply(input: ParseString) -> ParseResult<VecOp> {
93  let (input, _) = ws1e(input)?;
94  let (input, _) = tag("**")(input)?;
95  let (input, _) = ws1e(input)?;
96  Ok((input, VecOp::MatMul))
97}
98
99// matrix_solve := "\" ;
100pub fn matrix_solve(input: ParseString) -> ParseResult<VecOp> {
101  let (input, _) = ws1e(input)?;
102  let (input, _) = tag("\\")(input)?;
103  let (input, _) = ws1e(input)?;
104  Ok((input, VecOp::Solve))
105}
106
107// dot_product := "·" ;
108pub fn dot_product(input: ParseString) -> ParseResult<VecOp> {
109  let (input, _) = ws1e(input)?;
110  let (input, _) = tag("·")(input)?;
111  let (input, _) = ws1e(input)?;
112  Ok((input, VecOp::Dot))
113}
114
115// cross_product := "⨯" ;
116pub fn cross_product(input: ParseString) -> ParseResult<VecOp> {
117  let (input, _) = ws1e(input)?;
118  let (input, _) = tag("⨯")(input)?;
119  let (input, _) = ws1e(input)?;
120  Ok((input, VecOp::Cross))
121}
122
123// exponent := "^" ;
124pub fn exponent(input: ParseString) -> ParseResult<ExponentOp> {
125  let (input, _) = ws1e(input)?;
126  let (input, _) = tag("^")(input)?;
127  let (input, _) = ws1e(input)?;
128  Ok((input, ExponentOp::Exp))
129}
130
131// range_inclusive := "..=" ;
132pub fn range_inclusive(input: ParseString) -> ParseResult<RangeOp> {
133  let (input, _) = tag("..=")(input)?;
134  Ok((input, RangeOp::Inclusive))
135}
136
137// range_exclusive := ".." ;
138pub fn range_exclusive(input: ParseString) -> ParseResult<RangeOp> {
139  let (input, _) = tag("..")(input)?;
140  Ok((input, RangeOp::Exclusive))
141}
142
143// range_operator := range_inclusive | range_exclusive ;
144pub fn range_operator(input: ParseString) -> ParseResult<RangeOp> {
145  let (input, op) = alt((range_inclusive,range_exclusive))(input)?;
146  Ok((input, op))
147}
148
149// formula := l1, (range_operator, l1)* ;
150pub fn formula(input: ParseString) -> ParseResult<Factor> {
151  let (input, factor) = l1(input)?;
152  Ok((input, factor))
153}
154
155// add_sub_operator := add | subtract ;
156pub fn add_sub_operator(input: ParseString) -> ParseResult<FormulaOperator> {
157  let (input, op) = alt((add, subtract))(input)?;
158  Ok((input, FormulaOperator::AddSub(op)))
159}
160
161// l1 := l2, (add_sub_operator, l2)* ;
162pub fn l1(input: ParseString) -> ParseResult<Factor> {
163  let (input, lhs) = l2(input)?;
164  let (input, rhs) = many0(nom_tuple((add_sub_operator,l2)))(input)?;
165  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
166  Ok((input, factor))
167}
168
169// mul_div_operator := multiply | divide | modulus ;
170pub fn mul_div_operator(input: ParseString) -> ParseResult<FormulaOperator> {
171  let (input, op) = alt((multiply, divide, modulus))(input)?;
172  Ok((input, FormulaOperator::MulDiv(op)))
173}
174
175// matrix_operator := matrix_multiply | multiply | divide | matrix_solve ;
176pub fn matrix_operator(input: ParseString) -> ParseResult<FormulaOperator> {
177  let (input, op) = alt((matrix_multiply, matrix_solve, dot_product, cross_product))(input)?;
178  Ok((input, FormulaOperator::Vec(op)))
179}
180
181// l2 := l3, (mul_div_operator | matrix_operator, l3)* ;
182pub fn l2(input: ParseString) -> ParseResult<Factor> {
183  let (input, lhs) = l3(input)?;
184  let (input, rhs) = many0(nom_tuple((alt((mul_div_operator, matrix_operator)),l3)))(input)?;
185  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
186  Ok((input, factor))
187}
188
189// exponent_operator := exponent ;
190pub fn exponent_operator(input: ParseString) -> ParseResult<FormulaOperator> {
191  let (input, op) = exponent(input)?;
192  Ok((input, FormulaOperator::Exponent(op)))
193}
194
195// l3 := l4, (exponent_operator, l4)* ;
196pub fn l3(input: ParseString) -> ParseResult<Factor> {
197  let (input, lhs) = l4(input)?;
198  let (input, rhs) = many0(nom_tuple((exponent_operator,l4)))(input)?;
199  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
200  Ok((input, factor))
201}
202
203// logic_operator := and | or | xor ;
204pub fn logic_operator(input: ParseString) -> ParseResult<FormulaOperator> {
205  let (input, op) = alt((and, or, xor))(input)?;
206  Ok((input, FormulaOperator::Logic(op)))
207}
208
209// l4 := l5, (logic_operator, l5)* ;
210pub fn l4(input: ParseString) -> ParseResult<Factor> {
211  let (input, lhs) = l5(input)?;
212  let (input, rhs) = many0(nom_tuple((logic_operator,l5)))(input)?;
213  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
214  Ok((input, factor))
215}
216
217// l5 := factor, (comparison_operator, factor)* ;
218pub fn l5(input: ParseString) -> ParseResult<Factor> {
219  let (input, lhs) = factor(input)?;
220  let (input, rhs) = many0(nom_tuple((comparison_operator,factor)))(input)?;
221  let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
222  Ok((input, factor))
223}
224
225// comparison_operator := not_equal | equal_to | greater_than_equal | greater_than | less_than_equal | less_than ;
226pub fn comparison_operator(input: ParseString) -> ParseResult<FormulaOperator> {
227  let (input, op) = alt((not_equal, equal_to, greater_than_equal, greater_than, less_than_equal, less_than))(input)?;
228  Ok((input, FormulaOperator::Comparison(op)))
229}
230
231// factor := (parenthetical_term | structure | fsm_pipe | function_call | literal | slice | var), transpose? ;
232pub fn factor(input: ParseString) -> ParseResult<Factor> {
233  let (input, fctr) = match parenthetical_term(input.clone()) {
234    Ok((input, term)) => (input, term),
235    Err(_) => match negate_factor(input.clone()) {
236      Ok((input, neg)) => (input, neg),
237      Err(_) => match not_factor(input.clone()) {
238        Ok((input, neg)) => (input, neg),
239        Err(_) => match structure(input.clone()) {
240          Ok((input, strct)) => (input, Factor::Expression(Box::new(Expression::Structure(strct)))),
241          Err(_) => match fsm_pipe(input.clone()) {
242            Ok((input, pipe)) => (input, Factor::Expression(Box::new(Expression::FsmPipe(pipe)))),
243            Err(_) => match function_call(input.clone()) {
244              Ok((input, fxn)) => (input, Factor::Expression(Box::new(Expression::FunctionCall(fxn)))),
245              Err(_) => match literal(input.clone()) {
246                Ok((input, ltrl)) => (input, Factor::Expression(Box::new(Expression::Literal(ltrl)))),
247                Err(_) => match slice(input.clone()) {
248                  Ok((input, slc)) => (input, Factor::Expression(Box::new(Expression::Slice(slc)))),
249                  Err(_) => match var(input.clone()) {
250                    Ok((input, var)) => (input, Factor::Expression(Box::new(Expression::Var(var)))),
251                    Err(err) => { return Err(err); },
252                  },
253                },
254              },
255            },
256          },
257        },
258      },
259    },
260  };
261  let (input, transpose) = opt(transpose)(input)?;
262  let fctr = match transpose {
263    Some(_) => Factor::Transpose(Box::new(fctr)),
264    None => fctr,
265  };
266  Ok((input, fctr))
267}
268
269// statement_separator := ";" ;
270pub fn statement_separator(input: ParseString) -> ParseResult<()> {
271  let (input,_) = nom_tuple((whitespace0,semicolon,whitespace0))(input)?;
272  Ok((input, ()))
273}
274
275// ##### Comparison expressions
276
277// not_equal := "!=" | "¬=" | "≠" ;
278pub fn not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
279  let (input, _) = ws1e(input)?;
280  let (input, _) = alt((tag("!="),tag("¬="),tag("≠")))(input)?;
281  let (input, _) = ws1e(input)?;
282  Ok((input, ComparisonOp::NotEqual))
283}
284
285// equal_to := "==" ;
286pub fn equal_to(input: ParseString) -> ParseResult<ComparisonOp> {
287  let (input, _) = ws1e(input)?;
288  let (input, _) = tag("==")(input)?;
289  let (input, _) = ws1e(input)?;
290  Ok((input, ComparisonOp::Equal))
291}
292
293// greater_than := ">" ;
294pub fn greater_than(input: ParseString) -> ParseResult<ComparisonOp> {
295  let (input, _) = ws1e(input)?;
296  let (input, _) = tag(">")(input)?;
297  let (input, _) = ws1e(input)?;
298  Ok((input, ComparisonOp::GreaterThan))
299}
300
301// less_than := "<" ;
302pub fn less_than(input: ParseString) -> ParseResult<ComparisonOp> {
303  let (input, _) = ws1e(input)?;
304  let (input, _) = tag("<")(input)?;
305  let (input, _) = ws1e(input)?;
306  Ok((input, ComparisonOp::LessThan))
307}
308
309// greater_than_equal := ">=" | "≥" ;
310pub fn greater_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
311  let (input, _) = ws1e(input)?;
312  let (input, _) = alt((tag(">="),tag("≥")))(input)?;
313  let (input, _) = ws1e(input)?;
314  Ok((input, ComparisonOp::GreaterThanEqual))
315}
316
317// less_than_equal := "<=" | "≤" ;
318pub fn less_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
319  let (input, _) = ws1e(input)?;
320  let (input, _) = alt((tag("<="),tag("≤")))(input)?;
321  let (input, _) = ws1e(input)?;
322  Ok((input, ComparisonOp::LessThanEqual))
323}
324
325// ##### Logic expressions
326
327// or := "|" ;
328pub fn or(input: ParseString) -> ParseResult<LogicOp> {
329  let (input, _) = ws1e(input)?;
330  let (input, _) = tag("|")(input)?;
331  let (input, _) = ws1e(input)?;
332  Ok((input, LogicOp::Or))
333}
334
335// and := "&" ;
336pub fn and(input: ParseString) -> ParseResult<LogicOp> {
337  let (input, _) = ws1e(input)?;
338  let (input, _) = tag("&")(input)?;
339  let (input, _) = ws1e(input)?;
340  Ok((input, LogicOp::And))
341}
342
343// not := "!" | "¬" ;
344pub fn not(input: ParseString) -> ParseResult<LogicOp> {
345  let (input, _) = alt((tag("!"), tag("¬")))(input)?;
346  Ok((input, LogicOp::Not))
347}
348
349// xor := "xor" | "⊕" | "⊻" ;
350pub fn xor(input: ParseString) -> ParseResult<LogicOp> {
351  let (input, _) = ws1e(input)?;
352  let (input, _) = alt((tag("xor"), tag("⊕"), tag("⊻")))(input)?;
353  let (input, _) = ws1e(input)?;
354  Ok((input, LogicOp::Xor))
355}
356
357// ##### Other expressions
358
359// transpose := "'" ;
360pub fn transpose(input: ParseString) -> ParseResult<()> {
361  let (input, _) = tag("'")(input)?;
362  Ok((input, ()))
363}
364
365// literal := (number | string | atom | boolean | empty), kind_annotation? ;
366pub fn literal(input: ParseString) -> ParseResult<Literal> {
367  let (input, result) = match number(input.clone()) {
368    Ok((input, num)) => (input, Literal::Number(num)),
369    _ => match string(input.clone()) {
370      Ok((input, s)) => (input, Literal::String(s)),
371      _ => match atom(input.clone()) {
372        Ok((input, atm)) => (input, Literal::Atom(atm)),
373        _ => match boolean(input.clone()) {
374          Ok((input, boolean)) => (input, Literal::Boolean(boolean)),
375          _ => match empty(input.clone()) {
376            Ok((input, empty)) => (input, Literal::Empty(empty)), 
377            Err(err) => {return Err(err);}
378          }
379        }
380      }
381    }
382  };
383  let (input, result) = match opt(kind_annotation)(input.clone()) {
384    Ok((input, Some(knd))) => ((input, Literal::TypedLiteral((Box::new(result),knd)))),
385    Ok((input, None)) => (input,result),
386    Err(err) => {return Err(err);}
387  };
388  Ok((input, result))
389}
390
391// slice := identifier, subscript ;
392pub fn slice(input: ParseString) -> ParseResult<Slice> {
393  let (input, name) = identifier(input)?;
394  let (input, ixes) = subscript(input)?;
395  Ok((input, Slice{name, subscript: ixes}))
396}
397
398// slice_ref := identifier, subscript? ;
399pub fn slice_ref(input: ParseString) -> ParseResult<SliceRef> {
400  let (input, name) = identifier(input)?;
401  let (input, ixes) = opt(subscript)(input)?;
402  Ok((input, SliceRef{name, subscript: ixes}))
403}
404
405// subscript := (swizzle_subscript | dot_subscript_int | dot_subscript | bracket_subscript | brace_subscript)+ ; 
406pub fn subscript(input: ParseString) -> ParseResult<Vec<Subscript>> {
407  let (input, subscripts) = many1(alt((swizzle_subscript,dot_subscript,dot_subscript_int,bracket_subscript,brace_subscript)))(input)?;
408  Ok((input, subscripts))
409}
410
411// swizzle_subscript := ".", identifier, ",", list1(",", identifier) ;
412pub fn swizzle_subscript(input: ParseString) -> ParseResult<Subscript> {
413  let (input, _) = period(input)?;
414  let (input, first) = identifier(input)?;
415  let (input, _) = comma(input)?;
416  let (input, mut name) = separated_list1(tag(","),identifier)(input)?;
417  let mut subscripts = vec![first];
418  subscripts.append(&mut name);
419  Ok((input, Subscript::Swizzle(subscripts)))
420}
421
422// dot_subscript := ".", identifier ;
423pub fn dot_subscript(input: ParseString) -> ParseResult<Subscript> {
424  let (input, _) = period(input)?;
425  let (input, name) = identifier(input)?;
426  Ok((input, Subscript::Dot(name)))
427}
428
429// dot_subscript_int := ".", integer_literal ;
430pub fn dot_subscript_int(input: ParseString) -> ParseResult<Subscript> {
431  let (input, _) = period(input)?;
432  let (input, name) = integer_literal(input)?;
433  Ok((input, Subscript::DotInt(name)))
434}
435
436// bracket_subscript := "[", list1(",", select_all | range_subscript | formula_subscript), "]" ;
437pub fn bracket_subscript(input: ParseString) -> ParseResult<Subscript> {
438  let (input, _) = left_bracket(input)?;
439  let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
440  let (input, _) = right_bracket(input)?;
441  Ok((input, Subscript::Bracket(subscripts)))
442}
443
444// brace_subscript := "{", list1(",", select_all | formula_subscript), "}" ;
445pub fn brace_subscript(input: ParseString) -> ParseResult<Subscript> {
446  let (input, _) = left_brace(input)?;
447  let (input, subscripts) = separated_list1(list_separator,alt((select_all,formula_subscript)))(input)?;
448  let (input, _) = right_brace(input)?;
449  Ok((input, Subscript::Brace(subscripts)))
450}
451
452// select_all := ":" ;
453pub fn select_all(input: ParseString) -> ParseResult<Subscript> {
454  let (input, lhs) = colon(input)?;
455  Ok((input, Subscript::All))
456}
457
458// formula_subscript := formula ;
459pub fn formula_subscript(input: ParseString) -> ParseResult<Subscript> {
460  let (input, factor) = formula(input)?;
461  Ok((input, Subscript::Formula(factor)))
462}
463
464// range_subscript := range_expression ;
465pub fn range_subscript(input: ParseString) -> ParseResult<Subscript> {
466  let (input, rng) = range_expression(input)?;
467  Ok((input, Subscript::Range(rng)))
468}
469
470// range := formula, range_operator, formula, (range_operator, formula)? ;
471pub fn range_expression(input: ParseString) -> ParseResult<RangeExpression> {
472  let (input, start) = formula(input)?;
473  let (input, op) = range_operator(input)?;
474  let (input, x) = formula(input)?;
475  let (input, y) = opt(nom_tuple((range_operator,formula)))(input)?;
476  let range = match y {
477    Some((op2,terminal)) => RangeExpression{start, increment: Some((op,x)), operator: op2, terminal},
478    None => RangeExpression{start, increment: None, operator: op, terminal: x},
479  };
480  Ok((input, range))
481}
482
483// expression := range_expression | formula ;
484pub fn expression(input: ParseString) -> ParseResult<Expression> {
485  let (input, expr) = match range_expression(input.clone()) {
486    Ok((input, rng)) => (input, Expression::Range(Box::new(rng))),
487    Err(_) => match formula(input.clone()) {
488      Ok((input, Factor::Expression(expr))) => (input, *expr),
489      Ok((input, fctr)) => (input, Expression::Formula(fctr)),
490      Err(err) => {return Err(err);},
491    } 
492  };
493  Ok((input, expr))
494}
495
496// var := identifier, kind_annotation? ;
497pub fn var(input: ParseString) -> ParseResult<Var> {
498  let ((input, name)) = identifier(input)?;
499  let ((input, kind)) = opt(kind_annotation)(input)?;
500  Ok((input, Var{ name, kind }))
501}