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
23pub 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
37pub 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
44pub 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
51pub fn add(input: ParseString) -> ParseResult<AddSubOp> {
53 let (input, _) = whitespace1(input)?;
54 let (input, _) = tag("+")(input)?;
55 let (input, _) = whitespace1(input)?;
56 Ok((input, AddSubOp::Add))
57}
58
59pub fn subtract(input: ParseString) -> ParseResult<AddSubOp> {
61 let (input, _) = whitespace1(input)?;
62 let (input, _) = tag("-")(input)?;
63 let (input, _) = whitespace1(input)?;
64 Ok((input, AddSubOp::Sub))
65}
66
67pub fn multiply(input: ParseString) -> ParseResult<MulDivOp> {
69 let (input, _) = whitespace1(input)?;
70 let (input, _) = tag("*")(input)?;
71 let (input, _) = whitespace1(input)?;
72 Ok((input, MulDivOp::Mul))
73}
74
75pub fn divide(input: ParseString) -> ParseResult<MulDivOp> {
77 let (input, _) = whitespace1(input)?;
78 let (input, _) = tag("/")(input)?;
79 let (input, _) = whitespace1(input)?;
80 Ok((input, MulDivOp::Div))
81}
82
83pub fn modulus(input: ParseString) -> ParseResult<MulDivOp> {
85 let (input, _) = whitespace1(input)?;
86 let (input, _) = tag("%")(input)?;
87 let (input, _) = whitespace1(input)?;
88 Ok((input, MulDivOp::Mod))
89}
90
91pub fn matrix_multiply(input: ParseString) -> ParseResult<VecOp> {
93 let (input, _) = whitespace1(input)?;
94 let (input, _) = tag("**")(input)?;
95 let (input, _) = whitespace1(input)?;
96 Ok((input, VecOp::MatMul))
97}
98
99pub fn matrix_solve(input: ParseString) -> ParseResult<VecOp> {
101 let (input, _) = whitespace1(input)?;
102 let (input, _) = tag("\\")(input)?;
103 let (input, _) = whitespace1(input)?;
104 Ok((input, VecOp::Solve))
105}
106
107pub fn dot_product(input: ParseString) -> ParseResult<VecOp> {
109 let (input, _) = whitespace1(input)?;
110 let (input, _) = tag("·")(input)?;
111 let (input, _) = whitespace1(input)?;
112 Ok((input, VecOp::Dot))
113}
114
115pub fn cross_product(input: ParseString) -> ParseResult<VecOp> {
117 let (input, _) = whitespace1(input)?;
118 let (input, _) = tag("⨯")(input)?;
119 let (input, _) = whitespace1(input)?;
120 Ok((input, VecOp::Cross))
121}
122
123pub fn exponent(input: ParseString) -> ParseResult<ExponentOp> {
125 let (input, _) = whitespace1(input)?;
126 let (input, _) = tag("^")(input)?;
127 let (input, _) = whitespace1(input)?;
128 Ok((input, ExponentOp::Exp))
129}
130
131pub fn range_inclusive(input: ParseString) -> ParseResult<RangeOp> {
133 let (input, _) = tag("..=")(input)?;
134 Ok((input, RangeOp::Inclusive))
135}
136
137pub fn range_exclusive(input: ParseString) -> ParseResult<RangeOp> {
139 let (input, _) = tag("..")(input)?;
140 Ok((input, RangeOp::Exclusive))
141}
142
143pub fn range_operator(input: ParseString) -> ParseResult<RangeOp> {
145 let (input, op) = alt((range_inclusive,range_exclusive))(input)?;
146 Ok((input, op))
147}
148
149pub fn formula(input: ParseString) -> ParseResult<Factor> {
151 let (input, factor) = l1(input)?;
152 Ok((input, factor))
153}
154
155pub fn add_sub_operator(input: ParseString) -> ParseResult<FormulaOperator> {
157 let (input, op) = alt((add, subtract))(input)?;
158 Ok((input, FormulaOperator::AddSub(op)))
159}
160
161pub 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
169pub 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
175pub 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
181pub 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
189pub fn exponent_operator(input: ParseString) -> ParseResult<FormulaOperator> {
191 let (input, op) = exponent(input)?;
192 Ok((input, FormulaOperator::Exponent(op)))
193}
194
195pub 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
203pub fn logic_operator(input: ParseString) -> ParseResult<FormulaOperator> {
205 let (input, op) = alt((and, or, xor))(input)?;
206 Ok((input, FormulaOperator::Logic(op)))
207}
208
209pub 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
217pub 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
225pub 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
231pub 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
269pub fn statement_separator(input: ParseString) -> ParseResult<()> {
271 let (input,_) = nom_tuple((whitespace0,semicolon,whitespace0))(input)?;
272 Ok((input, ()))
273}
274
275pub fn function_define(input: ParseString) -> ParseResult<FunctionDefine> {
277 let ((input, name)) = identifier(input)?;
278 let ((input, _)) = left_parenthesis(input)?;
279 let ((input, input_args)) = separated_list0(list_separator, function_arg)(input)?;
280 let ((input, _)) = right_parenthesis(input)?;
281 let ((input, _)) = whitespace0(input)?;
282 let ((input, _)) = equal(input)?;
283 let ((input, _)) = whitespace0(input)?;
284 let ((input, output)) = alt((function_out_args,function_out_arg))(input)?;
285 let ((input, _)) = define_operator(input)?;
286 let ((input, statements)) = separated_list1(alt((whitespace1,statement_separator)), statement)(input)?;
287 let ((input, _)) = period(input)?;
288 Ok((input,FunctionDefine{name,input: input_args,output,statements}))
289}
290
291pub fn function_out_args(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
293 let ((input, _)) = left_parenthesis(input)?;
294 let ((input, args)) = separated_list1(list_separator,function_arg)(input)?;
295 let ((input, _)) = right_parenthesis(input)?;
296 Ok((input, args))
297}
298
299pub fn function_out_arg(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
301 let ((input, arg)) = function_arg(input)?;
302 Ok((input, vec![arg]))
303}
304
305pub fn function_arg(input: ParseString) -> ParseResult<FunctionArgument> {
307 let ((input, name)) = identifier(input)?;
308 let ((input, kind)) = kind_annotation(input)?;
309 Ok((input, FunctionArgument{ name, kind }))
310}
311
312pub fn argument_list(input: ParseString) -> ParseResult<ArgumentList> {
314 let (input, _) = left_parenthesis(input)?;
315 let (input, args) = separated_list0(list_separator, alt((call_arg_with_binding,call_arg)))(input)?;
316 let (input, _) = right_parenthesis(input)?;
317 Ok((input, args))
318}
319
320pub fn function_call(input: ParseString) -> ParseResult<FunctionCall> {
322 let (input, name) = identifier(input)?;
323 let (input, args) = argument_list(input)?;
324 Ok((input, FunctionCall{name,args} ))
325}
326
327pub fn call_arg_with_binding(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
329 let (input, arg_name) = identifier(input)?;
330 let (input, _) = whitespace0(input)?;
331 let (input, _) = colon(input)?;
332 let (input, _) = whitespace0(input)?;
333 let (input, expr) = expression(input)?;
334 Ok((input, (Some(arg_name), expr)))
335}
336
337pub fn call_arg(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
339 let (input, expr) = expression(input)?;
340 Ok((input, (None, expr)))
341}
342
343pub fn var(input: ParseString) -> ParseResult<Var> {
345 let ((input, name)) = identifier(input)?;
346 let ((input, kind)) = opt(kind_annotation)(input)?;
347 Ok((input, Var{ name, kind }))
348}
349
350pub fn not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
354 let (input, _) = whitespace1(input)?;
355 let (input, _) = alt((tag("!="),tag("¬="),tag("≠")))(input)?;
356 let (input, _) = whitespace1(input)?;
357 Ok((input, ComparisonOp::NotEqual))
358}
359
360pub fn equal_to(input: ParseString) -> ParseResult<ComparisonOp> {
362 let (input, _) = whitespace1(input)?;
363 let (input, _) = tag("==")(input)?;
364 let (input, _) = whitespace1(input)?;
365 Ok((input, ComparisonOp::Equal))
366}
367
368pub fn greater_than(input: ParseString) -> ParseResult<ComparisonOp> {
370 let (input, _) = whitespace1(input)?;
371 let (input, _) = tag(">")(input)?;
372 let (input, _) = whitespace1(input)?;
373 Ok((input, ComparisonOp::GreaterThan))
374}
375
376pub fn less_than(input: ParseString) -> ParseResult<ComparisonOp> {
378 let (input, _) = whitespace1(input)?;
379 let (input, _) = tag("<")(input)?;
380 let (input, _) = whitespace1(input)?;
381 Ok((input, ComparisonOp::LessThan))
382}
383
384pub fn greater_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
386 let (input, _) = whitespace1(input)?;
387 let (input, _) = alt((tag(">="),tag("≥")))(input)?;
388 let (input, _) = whitespace1(input)?;
389 Ok((input, ComparisonOp::GreaterThanEqual))
390}
391
392pub fn less_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
394 let (input, _) = whitespace1(input)?;
395 let (input, _) = alt((tag("<="),tag("≤")))(input)?;
396 let (input, _) = whitespace1(input)?;
397 Ok((input, ComparisonOp::LessThanEqual))
398}
399
400pub fn or(input: ParseString) -> ParseResult<LogicOp> {
404 let (input, _) = whitespace1(input)?;
405 let (input, _) = tag("|")(input)?;
406 let (input, _) = whitespace1(input)?;
407 Ok((input, LogicOp::Or))
408}
409
410pub fn and(input: ParseString) -> ParseResult<LogicOp> {
412 let (input, _) = whitespace1(input)?;
413 let (input, _) = tag("&")(input)?;
414 let (input, _) = whitespace1(input)?;
415 Ok((input, LogicOp::And))
416}
417
418pub fn not(input: ParseString) -> ParseResult<LogicOp> {
420 let (input, _) = alt((tag("!"), tag("¬")))(input)?;
421 Ok((input, LogicOp::Not))
422}
423
424pub fn xor(input: ParseString) -> ParseResult<LogicOp> {
426 let (input, _) = whitespace1(input)?;
427 let (input, _) = alt((tag("xor"), tag("⊕"), tag("⊻")))(input)?;
428 let (input, _) = whitespace1(input)?;
429 Ok((input, LogicOp::Xor))
430}
431
432pub fn string(input: ParseString) -> ParseResult<MechString> {
436 let msg = "Character not allowed in string";
437 let (input, _) = quote(input)?;
438 let (input, matched) = many0(nom_tuple((is_not(quote), label!(text, msg))))(input)?;
439 let (input, _) = quote(input)?;
440 let (_, mut text): ((), Vec<_>) = matched.into_iter().unzip();
441 let mut merged = Token::merge_tokens(&mut text).unwrap();
442 merged.kind = TokenKind::String;
443 Ok((input, MechString { text: merged }))
444}
445
446pub fn transpose(input: ParseString) -> ParseResult<()> {
448 let (input, _) = tag("'")(input)?;
449 Ok((input, ()))
450}
451
452pub fn literal(input: ParseString) -> ParseResult<Literal> {
454 let (input, result) = match number(input.clone()) {
455 Ok((input, num)) => (input, Literal::Number(num)),
456 _ => match string(input.clone()) {
457 Ok((input, s)) => (input, Literal::String(s)),
458 _ => match atom(input.clone()) {
459 Ok((input, atm)) => (input, Literal::Atom(atm)),
460 _ => match boolean(input.clone()) {
461 Ok((input, boolean)) => (input, Literal::Boolean(boolean)),
462 _ => match empty(input.clone()) {
463 Ok((input, empty)) => (input, Literal::Empty(empty)),
464 Err(err) => {return Err(err);}
465 }
466 }
467 }
468 }
469 };
470 let (input, result) = match opt(kind_annotation)(input.clone()) {
471 Ok((input, Some(knd))) => ((input, Literal::TypedLiteral((Box::new(result),knd)))),
472 Ok((input, None)) => (input,result),
473 Err(err) => {return Err(err);}
474 };
475 Ok((input, result))
476}
477
478pub fn slice(input: ParseString) -> ParseResult<Slice> {
480 let (input, name) = identifier(input)?;
481 let (input, ixes) = subscript(input)?;
482 Ok((input, Slice{name, subscript: ixes}))
483}
484
485pub fn slice_ref(input: ParseString) -> ParseResult<SliceRef> {
487 let (input, name) = identifier(input)?;
488 let (input, ixes) = opt(subscript)(input)?;
489 Ok((input, SliceRef{name, subscript: ixes}))
490}
491
492pub fn subscript(input: ParseString) -> ParseResult<Vec<Subscript>> {
494 let (input, subscripts) = many1(alt((swizzle_subscript,dot_subscript,dot_subscript_int,bracket_subscript,brace_subscript)))(input)?;
495 Ok((input, subscripts))
496}
497
498pub fn swizzle_subscript(input: ParseString) -> ParseResult<Subscript> {
500 let (input, _) = period(input)?;
501 let (input, first) = identifier(input)?;
502 let (input, _) = comma(input)?;
503 let (input, mut name) = separated_list1(tag(","),identifier)(input)?;
504 let mut subscripts = vec![first];
505 subscripts.append(&mut name);
506 Ok((input, Subscript::Swizzle(subscripts)))
507}
508
509pub fn dot_subscript(input: ParseString) -> ParseResult<Subscript> {
511 let (input, _) = period(input)?;
512 let (input, name) = identifier(input)?;
513 Ok((input, Subscript::Dot(name)))
514}
515
516pub fn dot_subscript_int(input: ParseString) -> ParseResult<Subscript> {
518 let (input, _) = period(input)?;
519 let (input, name) = integer_literal(input)?;
520 Ok((input, Subscript::DotInt(name)))
521}
522
523pub fn bracket_subscript(input: ParseString) -> ParseResult<Subscript> {
525 let (input, _) = left_bracket(input)?;
526 let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
527 let (input, _) = right_bracket(input)?;
528 Ok((input, Subscript::Bracket(subscripts)))
529}
530
531pub fn brace_subscript(input: ParseString) -> ParseResult<Subscript> {
533 let (input, _) = left_brace(input)?;
534 let (input, subscripts) = separated_list1(list_separator,alt((select_all,formula_subscript)))(input)?;
535 let (input, _) = right_brace(input)?;
536 Ok((input, Subscript::Brace(subscripts)))
537}
538
539pub fn select_all(input: ParseString) -> ParseResult<Subscript> {
541 let (input, lhs) = colon(input)?;
542 Ok((input, Subscript::All))
543}
544
545pub fn formula_subscript(input: ParseString) -> ParseResult<Subscript> {
547 let (input, factor) = formula(input)?;
548 Ok((input, Subscript::Formula(factor)))
549}
550
551pub fn range_subscript(input: ParseString) -> ParseResult<Subscript> {
553 let (input, rng) = range_expression(input)?;
554 Ok((input, Subscript::Range(rng)))
555}
556
557pub fn range_expression(input: ParseString) -> ParseResult<RangeExpression> {
559 let (input, start) = formula(input)?;
560 let (input, op) = range_operator(input)?;
561 let (input, x) = formula(input)?;
562 let (input, y) = opt(nom_tuple((range_operator,formula)))(input)?;
563 let range = match y {
564 Some((op2,terminal)) => RangeExpression{start, increment: Some((op,x)), operator: op2, terminal},
565 None => RangeExpression{start, increment: None, operator: op, terminal: x},
566 };
567 Ok((input, range))
568}
569
570pub fn expression(input: ParseString) -> ParseResult<Expression> {
572 let (input, expr) = match range_expression(input.clone()) {
573 Ok((input, rng)) => (input, Expression::Range(Box::new(rng))),
574 Err(_) => match formula(input.clone()) {
575 Ok((input, Factor::Expression(expr))) => (input, *expr),
576 Ok((input, fctr)) => (input, Expression::Formula(fctr)),
577 Err(err) => {return Err(err);},
578 }
579 };
580 Ok((input, expr))
581}