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 matrix_multiply(input: ParseString) -> ParseResult<VecOp> {
85 let (input, _) = whitespace1(input)?;
86 let (input, _) = tag("**")(input)?;
87 let (input, _) = whitespace1(input)?;
88 Ok((input, VecOp::MatMul))
89}
90
91pub fn matrix_solve(input: ParseString) -> ParseResult<VecOp> {
93 let (input, _) = whitespace1(input)?;
94 let (input, _) = tag("\\")(input)?;
95 let (input, _) = whitespace1(input)?;
96 Ok((input, VecOp::Solve))
97}
98
99pub fn dot_product(input: ParseString) -> ParseResult<VecOp> {
101 let (input, _) = whitespace1(input)?;
102 let (input, _) = tag("·")(input)?;
103 let (input, _) = whitespace1(input)?;
104 Ok((input, VecOp::Dot))
105}
106
107pub fn cross_product(input: ParseString) -> ParseResult<VecOp> {
109 let (input, _) = whitespace1(input)?;
110 let (input, _) = tag("⨯")(input)?;
111 let (input, _) = whitespace1(input)?;
112 Ok((input, VecOp::Cross))
113}
114
115pub fn exponent(input: ParseString) -> ParseResult<ExponentOp> {
117 let (input, _) = whitespace1(input)?;
118 let (input, _) = tag("^")(input)?;
119 let (input, _) = whitespace1(input)?;
120 Ok((input, ExponentOp::Exp))
121}
122
123pub fn range_inclusive(input: ParseString) -> ParseResult<RangeOp> {
125 let (input, _) = tag("..=")(input)?;
126 Ok((input, RangeOp::Inclusive))
127}
128
129pub fn range_exclusive(input: ParseString) -> ParseResult<RangeOp> {
131 let (input, _) = tag("..")(input)?;
132 Ok((input, RangeOp::Exclusive))
133}
134
135pub fn range_operator(input: ParseString) -> ParseResult<RangeOp> {
137 let (input, op) = alt((range_inclusive,range_exclusive))(input)?;
138 Ok((input, op))
139}
140
141pub fn formula(input: ParseString) -> ParseResult<Factor> {
143 let (input, factor) = l1(input)?;
144 Ok((input, factor))
145}
146
147pub fn add_sub_operator(input: ParseString) -> ParseResult<FormulaOperator> {
149 let (input, op) = alt((add, subtract))(input)?;
150 Ok((input, FormulaOperator::AddSub(op)))
151}
152
153pub fn l1(input: ParseString) -> ParseResult<Factor> {
155 let (input, lhs) = l2(input)?;
156 let (input, rhs) = many0(nom_tuple((add_sub_operator,l2)))(input)?;
157 let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
158 Ok((input, factor))
159}
160
161pub fn mul_div_operator(input: ParseString) -> ParseResult<FormulaOperator> {
163 let (input, op) = alt((multiply, divide))(input)?;
164 Ok((input, FormulaOperator::MulDiv(op)))
165}
166
167pub fn matrix_operator(input: ParseString) -> ParseResult<FormulaOperator> {
169 let (input, op) = alt((matrix_multiply, matrix_solve, dot_product, cross_product))(input)?;
170 Ok((input, FormulaOperator::Vec(op)))
171}
172
173pub fn l2(input: ParseString) -> ParseResult<Factor> {
175 let (input, lhs) = l3(input)?;
176 let (input, rhs) = many0(nom_tuple((alt((mul_div_operator, matrix_operator)),l3)))(input)?;
177 let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
178 Ok((input, factor))
179}
180
181pub fn exponent_operator(input: ParseString) -> ParseResult<FormulaOperator> {
183 let (input, op) = exponent(input)?;
184 Ok((input, FormulaOperator::Exponent(op)))
185}
186
187pub fn l3(input: ParseString) -> ParseResult<Factor> {
189 let (input, lhs) = l4(input)?;
190 let (input, rhs) = many0(nom_tuple((exponent_operator,l4)))(input)?;
191 let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
192 Ok((input, factor))
193}
194
195pub fn logic_operator(input: ParseString) -> ParseResult<FormulaOperator> {
197 let (input, op) = alt((and, or, xor))(input)?;
198 Ok((input, FormulaOperator::Logic(op)))
199}
200
201pub fn l4(input: ParseString) -> ParseResult<Factor> {
203 let (input, lhs) = l5(input)?;
204 let (input, rhs) = many0(nom_tuple((logic_operator,l5)))(input)?;
205 let factor = if rhs.is_empty() { lhs } else { Factor::Term(Box::new(Term { lhs, rhs })) };
206 Ok((input, factor))
207}
208
209pub fn l5(input: ParseString) -> ParseResult<Factor> {
211 let (input, lhs) = factor(input)?;
212 let (input, rhs) = many0(nom_tuple((comparison_operator,factor)))(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 comparison_operator(input: ParseString) -> ParseResult<FormulaOperator> {
219 let (input, op) = alt((not_equal, equal_to, greater_than_equal, greater_than, less_than_equal, less_than))(input)?;
220 Ok((input, FormulaOperator::Comparison(op)))
221}
222
223pub fn factor(input: ParseString) -> ParseResult<Factor> {
225 let (input, fctr) = match parenthetical_term(input.clone()) {
226 Ok((input, term)) => (input, term),
227 Err(_) => match negate_factor(input.clone()) {
228 Ok((input, neg)) => (input, neg),
229 Err(_) => match not_factor(input.clone()) {
230 Ok((input, neg)) => (input, neg),
231 Err(_) => match structure(input.clone()) {
232 Ok((input, strct)) => (input, Factor::Expression(Box::new(Expression::Structure(strct)))),
233 Err(_) => match fsm_pipe(input.clone()) {
234 Ok((input, pipe)) => (input, Factor::Expression(Box::new(Expression::FsmPipe(pipe)))),
235 Err(_) => match function_call(input.clone()) {
236 Ok((input, fxn)) => (input, Factor::Expression(Box::new(Expression::FunctionCall(fxn)))),
237 Err(_) => match literal(input.clone()) {
238 Ok((input, ltrl)) => (input, Factor::Expression(Box::new(Expression::Literal(ltrl)))),
239 Err(_) => match slice(input.clone()) {
240 Ok((input, slc)) => (input, Factor::Expression(Box::new(Expression::Slice(slc)))),
241 Err(_) => match var(input.clone()) {
242 Ok((input, var)) => (input, Factor::Expression(Box::new(Expression::Var(var)))),
243 Err(err) => { return Err(err); },
244 },
245 },
246 },
247 },
248 },
249 },
250 },
251 },
252 };
253 let (input, transpose) = opt(transpose)(input)?;
254 let fctr = match transpose {
255 Some(_) => Factor::Transpose(Box::new(fctr)),
256 None => fctr,
257 };
258 Ok((input, fctr))
259}
260
261pub fn statement_separator(input: ParseString) -> ParseResult<()> {
263 let (input,_) = nom_tuple((whitespace0,semicolon,whitespace0))(input)?;
264 Ok((input, ()))
265}
266
267pub fn function_define(input: ParseString) -> ParseResult<FunctionDefine> {
269 let ((input, name)) = identifier(input)?;
270 let ((input, _)) = left_parenthesis(input)?;
271 let ((input, input_args)) = separated_list0(list_separator, function_arg)(input)?;
272 let ((input, _)) = right_parenthesis(input)?;
273 let ((input, _)) = whitespace0(input)?;
274 let ((input, _)) = equal(input)?;
275 let ((input, _)) = whitespace0(input)?;
276 let ((input, output)) = alt((function_out_args,function_out_arg))(input)?;
277 let ((input, _)) = define_operator(input)?;
278 let ((input, statements)) = separated_list1(alt((whitespace1,statement_separator)), statement)(input)?;
279 let ((input, _)) = period(input)?;
280 Ok((input,FunctionDefine{name,input: input_args,output,statements}))
281}
282
283pub fn function_out_args(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
285 let ((input, _)) = left_parenthesis(input)?;
286 let ((input, args)) = separated_list1(list_separator,function_arg)(input)?;
287 let ((input, _)) = right_parenthesis(input)?;
288 Ok((input, args))
289}
290
291pub fn function_out_arg(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
293 let ((input, arg)) = function_arg(input)?;
294 Ok((input, vec![arg]))
295}
296
297pub fn function_arg(input: ParseString) -> ParseResult<FunctionArgument> {
299 let ((input, name)) = identifier(input)?;
300 let ((input, kind)) = kind_annotation(input)?;
301 Ok((input, FunctionArgument{ name, kind }))
302}
303
304pub fn argument_list(input: ParseString) -> ParseResult<ArgumentList> {
306 let (input, _) = left_parenthesis(input)?;
307 let (input, args) = separated_list0(list_separator, alt((call_arg_with_binding,call_arg)))(input)?;
308 let (input, _) = right_parenthesis(input)?;
309 Ok((input, args))
310}
311
312pub fn function_call(input: ParseString) -> ParseResult<FunctionCall> {
314 let (input, name) = identifier(input)?;
315 let (input, args) = argument_list(input)?;
316 Ok((input, FunctionCall{name,args} ))
317}
318
319pub fn call_arg_with_binding(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
321 let (input, arg_name) = identifier(input)?;
322 let (input, _) = whitespace0(input)?;
323 let (input, _) = colon(input)?;
324 let (input, _) = whitespace0(input)?;
325 let (input, expr) = expression(input)?;
326 Ok((input, (Some(arg_name), expr)))
327}
328
329pub fn call_arg(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
331 let (input, expr) = expression(input)?;
332 Ok((input, (None, expr)))
333}
334
335pub fn var(input: ParseString) -> ParseResult<Var> {
337 let ((input, name)) = identifier(input)?;
338 let ((input, kind)) = opt(kind_annotation)(input)?;
339 Ok((input, Var{ name, kind }))
340}
341
342pub fn not_equal(input: ParseString) -> ParseResult<ComparisonOp> {
346 let (input, _) = whitespace1(input)?;
347 let (input, _) = alt((tag("!="),tag("¬="),tag("≠")))(input)?;
348 let (input, _) = whitespace1(input)?;
349 Ok((input, ComparisonOp::NotEqual))
350}
351
352pub fn equal_to(input: ParseString) -> ParseResult<ComparisonOp> {
354 let (input, _) = whitespace1(input)?;
355 let (input, _) = tag("==")(input)?;
356 let (input, _) = whitespace1(input)?;
357 Ok((input, ComparisonOp::Equal))
358}
359
360pub fn greater_than(input: ParseString) -> ParseResult<ComparisonOp> {
362 let (input, _) = whitespace1(input)?;
363 let (input, _) = tag(">")(input)?;
364 let (input, _) = whitespace1(input)?;
365 Ok((input, ComparisonOp::GreaterThan))
366}
367
368pub fn less_than(input: ParseString) -> ParseResult<ComparisonOp> {
370 let (input, _) = whitespace1(input)?;
371 let (input, _) = tag("<")(input)?;
372 let (input, _) = whitespace1(input)?;
373 Ok((input, ComparisonOp::LessThan))
374}
375
376pub fn greater_than_equal(input: ParseString) -> ParseResult<ComparisonOp> {
378 let (input, _) = whitespace1(input)?;
379 let (input, _) = alt((tag(">="),tag("≥")))(input)?;
380 let (input, _) = whitespace1(input)?;
381 Ok((input, ComparisonOp::GreaterThanEqual))
382}
383
384pub fn less_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::LessThanEqual))
390}
391
392pub fn or(input: ParseString) -> ParseResult<LogicOp> {
396 let (input, _) = whitespace1(input)?;
397 let (input, _) = tag("|")(input)?;
398 let (input, _) = whitespace1(input)?;
399 Ok((input, LogicOp::Or))
400}
401
402pub fn and(input: ParseString) -> ParseResult<LogicOp> {
404 let (input, _) = whitespace1(input)?;
405 let (input, _) = tag("&")(input)?;
406 let (input, _) = whitespace1(input)?;
407 Ok((input, LogicOp::And))
408}
409
410pub fn not(input: ParseString) -> ParseResult<LogicOp> {
412 let (input, _) = alt((tag("!"), tag("¬")))(input)?;
413 Ok((input, LogicOp::Not))
414}
415
416pub fn xor(input: ParseString) -> ParseResult<LogicOp> {
418 let (input, _) = whitespace1(input)?;
419 let (input, _) = alt((tag("xor"), tag("⊕"), tag("⊻")))(input)?;
420 let (input, _) = whitespace1(input)?;
421 Ok((input, LogicOp::Xor))
422}
423
424pub fn string(input: ParseString) -> ParseResult<MechString> {
428 let msg = "Character not allowed in string";
429 let (input, _) = quote(input)?;
430 let (input, matched) = many0(nom_tuple((is_not(quote), label!(text, msg))))(input)?;
431 let (input, _) = quote(input)?;
432 let (_, mut text): ((), Vec<_>) = matched.into_iter().unzip();
433 let mut merged = Token::merge_tokens(&mut text).unwrap();
434 merged.kind = TokenKind::String;
435 Ok((input, MechString { text: merged }))
436}
437
438pub fn transpose(input: ParseString) -> ParseResult<()> {
440 let (input, _) = tag("'")(input)?;
441 Ok((input, ()))
442}
443
444pub fn literal(input: ParseString) -> ParseResult<Literal> {
446 let (input, result) = match number(input.clone()) {
447 Ok((input, num)) => (input, Literal::Number(num)),
448 _ => match string(input.clone()) {
449 Ok((input, s)) => (input, Literal::String(s)),
450 _ => match atom(input.clone()) {
451 Ok((input, atm)) => (input, Literal::Atom(atm)),
452 _ => match boolean(input.clone()) {
453 Ok((input, boolean)) => (input, Literal::Boolean(boolean)),
454 _ => match empty(input.clone()) {
455 Ok((input, empty)) => (input, Literal::Empty(empty)),
456 Err(err) => {return Err(err);}
457 }
458 }
459 }
460 }
461 };
462 let (input, result) = match opt(kind_annotation)(input.clone()) {
463 Ok((input, Some(knd))) => ((input, Literal::TypedLiteral((Box::new(result),knd)))),
464 Ok((input, None)) => (input,result),
465 Err(err) => {return Err(err);}
466 };
467 Ok((input, result))
468}
469
470pub fn slice(input: ParseString) -> ParseResult<Slice> {
472 let (input, name) = identifier(input)?;
473 let (input, ixes) = subscript(input)?;
474 Ok((input, Slice{name, subscript: ixes}))
475}
476
477pub fn slice_ref(input: ParseString) -> ParseResult<SliceRef> {
479 let (input, name) = identifier(input)?;
480 let (input, ixes) = opt(subscript)(input)?;
481 Ok((input, SliceRef{name, subscript: ixes}))
482}
483
484pub fn subscript(input: ParseString) -> ParseResult<Vec<Subscript>> {
486 let (input, subscripts) = many1(alt((swizzle_subscript,dot_subscript,dot_subscript_int,bracket_subscript,brace_subscript)))(input)?;
487 Ok((input, subscripts))
488}
489
490pub fn swizzle_subscript(input: ParseString) -> ParseResult<Subscript> {
492 let (input, _) = period(input)?;
493 let (input, first) = identifier(input)?;
494 let (input, _) = comma(input)?;
495 let (input, mut name) = separated_list1(tag(","),identifier)(input)?;
496 let mut subscripts = vec![first];
497 subscripts.append(&mut name);
498 Ok((input, Subscript::Swizzle(subscripts)))
499}
500
501pub fn dot_subscript(input: ParseString) -> ParseResult<Subscript> {
503 let (input, _) = period(input)?;
504 let (input, name) = identifier(input)?;
505 Ok((input, Subscript::Dot(name)))
506}
507
508pub fn dot_subscript_int(input: ParseString) -> ParseResult<Subscript> {
510 let (input, _) = period(input)?;
511 let (input, name) = integer_literal(input)?;
512 Ok((input, Subscript::DotInt(name)))
513}
514
515pub fn bracket_subscript(input: ParseString) -> ParseResult<Subscript> {
517 let (input, _) = left_bracket(input)?;
518 let (input, subscripts) = separated_list1(list_separator,alt((select_all,range_subscript,formula_subscript)))(input)?;
519 let (input, _) = right_bracket(input)?;
520 Ok((input, Subscript::Bracket(subscripts)))
521}
522
523pub fn brace_subscript(input: ParseString) -> ParseResult<Subscript> {
525 let (input, _) = left_brace(input)?;
526 let (input, subscripts) = separated_list1(list_separator,alt((select_all,formula_subscript)))(input)?;
527 let (input, _) = right_brace(input)?;
528 Ok((input, Subscript::Brace(subscripts)))
529}
530
531pub fn select_all(input: ParseString) -> ParseResult<Subscript> {
533 let (input, lhs) = colon(input)?;
534 Ok((input, Subscript::All))
535}
536
537pub fn formula_subscript(input: ParseString) -> ParseResult<Subscript> {
539 let (input, factor) = formula(input)?;
540 Ok((input, Subscript::Formula(factor)))
541}
542
543pub fn range_subscript(input: ParseString) -> ParseResult<Subscript> {
545 let (input, rng) = range_expression(input)?;
546 Ok((input, Subscript::Range(rng)))
547}
548
549pub fn range_expression(input: ParseString) -> ParseResult<RangeExpression> {
551 let (input, start) = formula(input)?;
552 let (input, op) = range_operator(input)?;
553 let (input, x) = formula(input)?;
554 let (input, y) = opt(nom_tuple((range_operator,formula)))(input)?;
555 let range = match y {
556 Some((op2,terminal)) => RangeExpression{start, increment: Some((op,x)), operator: op2, terminal},
557 None => RangeExpression{start, increment: None, operator: op, terminal: x},
558 };
559 Ok((input, range))
560}
561
562pub fn expression(input: ParseString) -> ParseResult<Expression> {
564 let (input, expr) = match range_expression(input.clone()) {
565 Ok((input, rng)) => (input, Expression::Range(Box::new(rng))),
566 Err(_) => match formula(input.clone()) {
567 Ok((input, Factor::Expression(expr))) => (input, *expr),
568 Ok((input, fctr)) => (input, Expression::Formula(fctr)),
569 Err(err) => {return Err(err);},
570 }
571 };
572 Ok((input, expr))
573}