1pub mod ast;
2pub mod error;
3pub mod fmt;
4pub mod garbage;
5pub mod iter;
6pub mod keyword;
7pub mod token;
8
9use cas_error::ErrorKind;
10use error::{Error, kind};
11use super::tokenizer::{tokenize_complete, Token};
12use std::{ops::Range, sync::Arc};
13
14#[derive(Debug, Clone, Default)]
19pub struct ParserState {
20 pub allow_loop_control: bool,
23}
24
25#[derive(Debug, Clone)]
31pub struct Parser<'source> {
32 tokens: Arc<[Token<'source>]>,
34
35 cursor: usize,
37
38 state: ParserState,
43}
44
45impl<'source> Parser<'source> {
46 pub fn new(source: &'source str) -> Self {
48 Self {
49 tokens: tokenize_complete(source).into(),
50 cursor: 0,
51 state: ParserState::default(),
52 }
53 }
54
55 pub fn state(&self) -> &ParserState {
57 &self.state
58 }
59
60 pub fn set_cursor(&mut self, other: &Self) {
63 self.cursor = other.cursor;
64 }
65
66 pub fn error(&self, kind: impl ErrorKind + 'static) -> Error {
69 Error::new(vec![self.span()], kind)
70 }
71
72 pub fn eof_span(&self) -> Range<usize> {
74 self.tokens.last().map_or(0..0, |token| token.span.end..token.span.end)
75 }
76
77 pub fn span(&self) -> Range<usize> {
80 self.tokens
81 .get(self.cursor)
82 .map_or(self.eof_span(), |token| token.span.clone())
83 }
84
85 pub fn prev(&mut self) {
88 if self.cursor > 0 {
89 self.cursor -= 1;
90 }
91 }
92
93 pub fn prev_token(&self) -> Option<&Token<'source>> {
96 self.tokens.get(self.cursor.checked_sub(1)?)
97 }
98
99 pub fn current_token(&self) -> Option<&Token<'source>> {
102 self.tokens.get(self.cursor)
103 }
104
105 pub fn advance_past_whitespace(&mut self) {
109 while let Some(token) = self.tokens.get(self.cursor) {
110 if token.is_ignore() {
111 self.cursor += 1;
112 continue;
113 } else {
114 break;
115 }
116 }
117 }
118
119 pub fn advance_past_non_significant_whitespace(&mut self) {
168 while let Some(token) = self.tokens.get(self.cursor) {
169 if token.is_ignore() && !token.is_significant_whitespace() {
170 self.cursor += 1;
171 continue;
172 } else {
173 break;
174 }
175 }
176 }
177
178 pub fn next_token(&mut self) -> Result<Token<'source>, Error> {
182 self.advance_past_whitespace();
183 self.next_token_raw()
184 }
185
186 pub fn next_token_raw(&mut self) -> Result<Token<'source>, Error> {
190 let result = self.current_token()
191 .cloned() .ok_or_else(|| self.error(kind::UnexpectedEof));
193 self.cursor += 1;
194 result
195 }
196
197 pub fn try_parse<T: Parse<'source>>(&mut self) -> ParseResult<T> {
204 self.try_parse_with_fn(T::parse)
205 }
206
207 pub fn try_parse_with_state<F, T>(&mut self, modify_state: F) -> ParseResult<T>
218 where
219 F: FnOnce(&mut ParserState),
220 T: Parse<'source>,
221 {
222 let mut state = self.state.clone();
223 modify_state(&mut state);
224
225 let mut new_parser = Self {
226 tokens: self.tokens.clone(),
227 cursor: self.cursor,
228 state,
229 };
230
231 let t = new_parser.try_parse();
232 self.set_cursor(&new_parser);
233 t
234 }
235
236 pub fn try_parse_with_fn<T, F>(&mut self, f: F) -> ParseResult<T>
244 where
245 F: FnOnce(&mut Parser<'source>) -> ParseResult<T>,
246 {
247 let start = self.cursor;
248 f(self).inspect_unrecoverable(|_| self.cursor = start)
249 }
250
251 pub fn try_parse_then<T: Parse<'source>, F>(&mut self, predicate: F) -> ParseResult<T>
258 where
259 F: FnOnce(&T, &Parser) -> ParseResult<()>,
260 {
261 let start = self.cursor;
262 let mut errors = Vec::new();
263
264 let inner = || {
265 let value = T::parse(self).forward_errors(&mut errors)?;
266 predicate(&value, self).forward_errors(&mut errors)?;
267 Ok(value)
268 };
269
270 inner()
271 .map(|value| (value, errors))
272 .map_err(|unrecoverable: Vec<Error>| {
273 self.cursor = start;
274 unrecoverable
275 })
276 .into()
277 }
278
279 pub fn try_parse_full<T: Parse<'source>>(&mut self) -> Result<T, Vec<Error>> {
282 let mut errors = Vec::new();
283 let value = T::parse(self).forward_errors(&mut errors)?;
284
285 self.advance_past_whitespace();
287
288 if self.cursor < self.tokens.len() {
289 errors.push(self.error(kind::ExpectedEof));
290 }
291
292 if errors.is_empty() {
293 Ok(value)
294 } else {
295 Err(errors)
296 }
297 }
298
299 pub fn try_parse_full_many<T: std::fmt::Debug + Parse<'source>>(&mut self) -> Result<Vec<T>, Vec<Error>> {
302 let mut errors = Vec::new();
303 let mut values = Vec::new();
304
305 while self.cursor < self.tokens.len() {
306 let Ok(value) = T::parse(self).forward_errors(&mut errors) else {
307 break;
308 };
309 values.push(value);
310 }
311
312 self.advance_past_whitespace();
314
315 if self.cursor < self.tokens.len() {
316 errors.push(self.error(kind::ExpectedEof));
317 }
318
319 if errors.is_empty() {
320 Ok(values)
321 } else {
322 Err(errors)
323 }
324 }
325}
326
327pub trait Parse<'source>: Sized {
329 fn std_parse(
338 input: &mut Parser<'source>,
339 recoverable_errors: &mut Vec<Error>
340 ) -> Result<Self, Vec<Error>>;
341
342 fn parse(input: &mut Parser<'source>) -> ParseResult<Self> {
347 let mut recoverable_errors = Vec::new();
348 Self::std_parse(input, &mut recoverable_errors)
349 .map(|value| (value, recoverable_errors))
350 .into()
351 }
352}
353
354#[derive(Debug)]
356pub enum ParseResult<T> {
357 Ok(T),
359
360 Recoverable(T, Vec<Error>),
367
368 Unrecoverable(Vec<Error>),
371}
372
373impl<T> From<Result<(T, Vec<Error>), Vec<Error>>> for ParseResult<T> {
374 fn from(result: Result<(T, Vec<Error>), Vec<Error>>) -> Self {
375 match result {
376 Ok((value, errors)) => (value, errors).into(),
377 Err(unrecoverable_errors) => Self::Unrecoverable(unrecoverable_errors),
378 }
379 }
380}
381
382impl<T> From<(T, Vec<Error>)> for ParseResult<T> {
383 fn from((value, errors): (T, Vec<Error>)) -> Self {
384 if errors.is_empty() {
385 Self::Ok(value)
386 } else {
387 Self::Recoverable(value, errors)
388 }
389 }
390}
391
392impl<T> From<Vec<Error>> for ParseResult<T> {
393 fn from(errors: Vec<Error>) -> Self {
394 Self::Unrecoverable(errors)
395 }
396}
397
398impl<T> ParseResult<T> {
399 pub fn forward_errors(self, errors: &mut Vec<Error>) -> Result<T, Vec<Error>> {
409 match self {
410 Self::Ok(value) => Ok(value),
411 Self::Recoverable(value, mut errs) => {
412 errors.append(&mut errs);
413 Ok(value)
414 },
415 Self::Unrecoverable(errs) => Err(errs),
416 }
417 }
418
419 pub fn is_ok(&self) -> bool {
421 matches!(self, ParseResult::Ok(_))
422 }
423
424 pub fn inspect_unrecoverable<F>(self, f: F) -> Self
428 where
429 F: FnOnce(&Vec<Error>),
430 {
431 if let Self::Unrecoverable(errs) = &self {
432 f(errs);
433 }
434
435 self
436 }
437
438 pub fn map<U, F>(self, f: F) -> ParseResult<U>
444 where
445 F: FnOnce(T) -> U,
446 {
447 match self {
448 ParseResult::Ok(value) => ParseResult::Ok(f(value)),
449 ParseResult::Recoverable(value, errors) => ParseResult::Recoverable(f(value), errors),
450
451 ParseResult::Unrecoverable(errors) => ParseResult::Unrecoverable(errors),
454 }
455 }
456
457 pub fn or_else<F>(self, op: F) -> Self
461 where
462 F: FnOnce() -> Self,
463 {
464 match self {
465 ParseResult::Recoverable(..) | ParseResult::Unrecoverable(_) => op(),
466 ok => ok,
467 }
468 }
469}
470
471#[macro_export]
476macro_rules! return_if_ok {
477 ($result:expr) => {
478 match $result {
479 Ok(value) => return Ok(value),
480 Err(errors) => errors,
481 }
482 };
483}
484
485#[cfg(test)]
486mod tests {
487 use pretty_assertions::assert_eq;
488 use super::*;
489
490 use ast::*;
491 use token::op::{AssignOp, AssignOpKind, BinOp, BinOpKind, UnaryOp, UnaryOpKind};
492
493 #[test]
494 fn literal_int() {
495 let mut parser = Parser::new("16");
496 let expr = parser.try_parse_full::<Expr>().unwrap();
497
498 assert_eq!(expr, Expr::Literal(Literal::Integer(LitInt {
499 value: "16".to_string(),
500 span: 0..2,
501 })));
502 }
503
504 #[test]
505 fn literal_float() {
506 let mut parser = Parser::new("3.14");
507 let expr = parser.try_parse_full::<Expr>().unwrap();
508
509 assert_eq!(expr, Expr::Literal(Literal::Float(LitFloat {
510 value: "3.14".to_string(),
511 span: 0..4,
512 })));
513 }
514
515 #[test]
516 fn literal_float_2() {
517 let mut parser = Parser::new(".75");
518 let expr = parser.try_parse_full::<Expr>().unwrap();
519
520 assert_eq!(expr, Expr::Literal(Literal::Float(LitFloat {
521 value: ".75".to_string(),
522 span: 0..3,
523 })));
524 }
525
526 #[test]
527 fn literal_radix_base_2() {
528 let mut parser = Parser::new("2'10000110000");
529 let expr = parser.try_parse_full::<Expr>().unwrap();
530
531 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
532 base: 2,
533 value: "10000110000".to_string(),
534 span: 0..13,
535 })));
536 }
537
538 #[test]
539 fn literal_radix_base_8() {
540 let mut parser = Parser::new("8'2060");
541 let expr = parser.try_parse_full::<Expr>().unwrap();
542
543 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
544 base: 8,
545 value: "2060".to_string(),
546 span: 0..6,
547 })));
548 }
549
550 #[test]
551 fn literal_radix_base_25() {
552 let mut parser = Parser::new("25'1hm");
553 let expr = parser.try_parse_full::<Expr>().unwrap();
554
555 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
556 base: 25,
557 value: "1hm".to_string(),
558 span: 0..6,
559 })));
560 }
561
562 #[test]
563 fn literal_radix_base_32() {
564 let mut parser = Parser::new("32'11g");
565 let expr = parser.try_parse_full::<Expr>().unwrap();
566
567 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
568 base: 32,
569 value: "11g".to_string(),
570 span: 0..6,
571 })));
572 }
573
574 #[test]
575 fn literal_radix_base_47() {
576 let mut parser = Parser::new("47'mC");
577 let expr = parser.try_parse_full::<Expr>().unwrap();
578
579 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
580 base: 47,
581 value: "mC".to_string(),
582 span: 0..5,
583 })));
584 }
585
586 #[test]
587 fn literal_radix_with_nonword_tokens() {
588 let mut parser = Parser::new("64'++/+//");
589 let expr = parser.try_parse_full::<Expr>().unwrap();
590
591 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
592 base: 64,
593 value: "++/+//".to_string(),
594 span: 0..9,
595 })));
596 }
597
598 #[test]
599 fn literal_symbol() {
600 let mut parser = Parser::new("pi");
601 let expr = parser.try_parse_full::<Expr>().unwrap();
602
603 assert_eq!(expr, Expr::Literal(Literal::Symbol(LitSym {
604 name: "pi".to_string(),
605 span: 0..2,
606 })));
607 }
608
609 #[test]
610 fn unary_left_associativity() {
611 let mut parser = Parser::new("3!!");
612 let expr = parser.try_parse_full::<Expr>().unwrap();
613
614 assert_eq!(expr, Expr::Unary(Unary {
615 operand: Box::new(Expr::Unary(Unary {
616 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
617 value: "3".to_string(),
618 span: 0..1,
619 }))),
620 op: UnaryOp {
621 kind: UnaryOpKind::Factorial,
622 span: 1..2,
623 },
624 span: 0..2,
625 })),
626 op: UnaryOp {
627 kind: UnaryOpKind::Factorial,
628 span: 2..3,
629 },
630 span: 0..3,
631 }));
632 }
633
634 #[test]
635 fn unary_right_associativity() {
636 let mut parser = Parser::new("not not --3");
637 let expr = parser.try_parse_full::<Expr>().unwrap();
638
639 assert_eq!(expr, Expr::Unary(Unary {
640 operand: Box::new(Expr::Unary(Unary {
641 operand: Box::new(Expr::Unary(Unary {
642 operand: Box::new(Expr::Unary(Unary {
643 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
644 value: "3".to_string(),
645 span: 10..11,
646 }))),
647 op: UnaryOp {
648 kind: UnaryOpKind::Neg,
649 span: 9..10,
650 },
651 span: 9..11,
652 })),
653 op: UnaryOp {
654 kind: UnaryOpKind::Neg,
655 span: 8..9,
656 },
657 span: 8..11,
658 })),
659 op: UnaryOp {
660 kind: UnaryOpKind::Not,
661 span: 4..7,
662 },
663 span: 4..11,
664 })),
665 op: UnaryOp {
666 kind: UnaryOpKind::Not,
667 span: 0..3,
668 },
669 span: 0..11,
670 }));
671 }
672
673 #[test]
674 fn wrong_unary() {
675 let mut parser = Parser::new("!3");
676 assert!(parser.try_parse_full::<Expr>().is_err());
677 }
678
679 #[test]
680 fn unary_complicated() {
681 let mut parser = Parser::new("not 3!! + -4");
682 let expr = parser.try_parse_full::<Expr>().unwrap();
683
684 assert_eq!(expr, Expr::Binary(Binary {
685 lhs: Box::new(Expr::Unary(Unary {
686 operand: Box::new(Expr::Unary(Unary {
687 operand: Box::new(Expr::Unary(Unary {
688 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
689 value: "3".to_string(),
690 span: 4..5,
691 }))),
692 op: UnaryOp {
693 kind: UnaryOpKind::Factorial,
694 span: 5..6,
695 },
696 span: 4..6,
697 })),
698 op: UnaryOp {
699 kind: UnaryOpKind::Factorial,
700 span: 6..7,
701 },
702 span: 4..7,
703 })),
704 op: UnaryOp {
705 kind: UnaryOpKind::Not,
706 span: 0..3,
707 },
708 span: 0..7,
709 })),
710 op: BinOp {
711 kind: BinOpKind::Add,
712 implicit: false,
713 span: 8..9,
714 },
715 rhs: Box::new(Expr::Unary(Unary {
716 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
717 value: "4".to_string(),
718 span: 11..12,
719 }))),
720 op: UnaryOp {
721 kind: UnaryOpKind::Neg,
722 span: 10..11,
723 },
724 span: 10..12,
725 })),
726 span: 0..12,
727 }));
728 }
729
730 #[test]
731 fn binary_left_associativity() {
732 let mut parser = Parser::new("3 * x * 5");
733 let expr = parser.try_parse_full::<Expr>().unwrap();
734
735 assert_eq!(expr, Expr::Binary(Binary {
736 lhs: Box::new(Expr::Binary(Binary {
737 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
738 value: "3".to_string(),
739 span: 0..1,
740 }))),
741 op: BinOp {
742 kind: BinOpKind::Mul,
743 implicit: false,
744 span: 2..3,
745 },
746 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
747 name: "x".to_string(),
748 span: 4..5,
749 }))),
750 span: 0..5,
751 })),
752 op: BinOp {
753 kind: BinOpKind::Mul,
754 implicit: false,
755 span: 6..7,
756 },
757 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
758 value: "5".to_string(),
759 span: 8..9,
760 }))),
761 span: 0..9,
762 }));
763 }
764
765 #[test]
766 fn binary_left_associativity_mix_precedence() {
767 let mut parser = Parser::new("3 + 4 * a + b");
768 let expr = parser.try_parse_full::<Expr>().unwrap();
769
770 assert_eq!(expr, Expr::Binary(Binary {
771 lhs: Box::new(Expr::Binary(Binary {
772 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
773 value: "3".to_string(),
774 span: 0..1,
775 }))),
776 op: BinOp {
777 kind: BinOpKind::Add,
778 implicit: false,
779 span: 2..3,
780 },
781 rhs: Box::new(Expr::Binary(Binary {
782 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
783 value: "4".to_string(),
784 span: 4..5,
785 }))),
786 op: BinOp {
787 kind: BinOpKind::Mul,
788 implicit: false,
789 span: 6..7,
790 },
791 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
792 name: "a".to_string(),
793 span: 8..9,
794 }))),
795 span: 4..9,
796 })),
797 span: 0..9,
798 })),
799 op: BinOp {
800 kind: BinOpKind::Add,
801 implicit: false,
802 span: 10..11,
803 },
804 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
805 name: "b".to_string(),
806 span: 12..13,
807 }))),
808 span: 0..13,
809 }));
810 }
811
812 #[test]
813 fn binary_right_associativity() {
814 let mut parser = Parser::new("1 ^ 2 ^ 3");
815 let expr = parser.try_parse_full::<Expr>().unwrap();
816
817 assert_eq!(expr, Expr::Binary(Binary {
818 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
819 value: "1".to_string(),
820 span: 0..1,
821 }))),
822 op: BinOp {
823 kind: BinOpKind::Exp,
824 implicit: false,
825 span: 2..3,
826 },
827 rhs: Box::new(Expr::Binary(Binary {
828 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
829 value: "2".to_string(),
830 span: 4..5,
831 }))),
832 op: BinOp {
833 kind: BinOpKind::Exp,
834 implicit: false,
835 span: 6..7,
836 },
837 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
838 value: "3".to_string(),
839 span: 8..9,
840 }))),
841 span: 4..9,
842 })),
843 span: 0..9,
844 }));
845 }
846
847 #[test]
848 fn binary_complicated() {
849 let mut parser = Parser::new("1 + 2 * 3 - 4 / 5 ^ 6");
850 let expr = parser.try_parse_full::<Expr>().unwrap();
851
852 let mul = Expr::Binary(Binary {
854 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
855 value: "2".to_string(),
856 span: 4..5,
857 }))),
858 op: BinOp {
859 kind: BinOpKind::Mul,
860 implicit: false,
861 span: 6..7,
862 },
863 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
864 value: "3".to_string(),
865 span: 8..9,
866 }))),
867 span: 4..9,
868 });
869
870 let add = Expr::Binary(Binary {
872 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
873 value: "1".to_string(),
874 span: 0..1,
875 }))),
876 op: BinOp {
877 kind: BinOpKind::Add,
878 implicit: false,
879 span: 2..3,
880 },
881 rhs: Box::new(mul),
882 span: 0..9,
883 });
884
885 let exp = Expr::Binary(Binary {
887 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
888 value: "5".to_string(),
889 span: 16..17,
890 }))),
891 op: BinOp {
892 kind: BinOpKind::Exp,
893 implicit: false,
894 span: 18..19,
895 },
896 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
897 value: "6".to_string(),
898 span: 20..21,
899 }))),
900 span: 16..21,
901 });
902
903 let div = Expr::Binary(Binary {
905 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
906 value: "4".to_string(),
907 span: 12..13,
908 }))),
909 op: BinOp {
910 kind: BinOpKind::Div,
911 implicit: false,
912 span: 14..15,
913 },
914 rhs: Box::new(exp),
915 span: 12..21,
916 });
917
918 let sub = Expr::Binary(Binary {
920 lhs: Box::new(add),
921 op: BinOp {
922 kind: BinOpKind::Sub,
923 implicit: false,
924 span: 10..11,
925 },
926 rhs: Box::new(div),
927 span: 0..21,
928 });
929
930 assert_eq!(expr, sub);
931 }
932
933 #[test]
934 fn binary_and_unary() {
935 let mut parser = Parser::new("-1 ^ -2 * 3");
936 let expr = parser.try_parse_full::<Expr>().unwrap();
937
938 assert_eq!(expr, Expr::Binary(Binary {
939 lhs: Box::new(Expr::Unary(Unary {
940 operand: Box::new(Expr::Binary(Binary {
941 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
942 value: "1".to_string(),
943 span: 1..2,
944 }))),
945 op: BinOp {
946 kind: BinOpKind::Exp,
947 implicit: false,
948 span: 3..4,
949 },
950 rhs: Box::new(Expr::Unary(Unary {
951 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
952 value: "2".to_string(),
953 span: 6..7,
954 }))),
955 op: UnaryOp {
956 kind: UnaryOpKind::Neg,
957 span: 5..6,
958 },
959 span: 5..7,
960 })),
961 span: 1..7,
962 })),
963 op: UnaryOp {
964 kind: UnaryOpKind::Neg,
965 span: 0..1,
966 },
967 span: 0..7,
968 })),
969 op: BinOp {
970 kind: BinOpKind::Mul,
971 implicit: false,
972 span: 8..9,
973 },
974 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
975 value: "3".to_string(),
976 span: 10..11,
977 }))),
978 span: 0..11,
979 }));
980 }
981
982 #[test]
983 fn complicated_binary_and_unary() {
984 let mut parser = Parser::new("pi^2 * 17! / -4.9 + e");
985 let expr = parser.try_parse_full::<Expr>().unwrap();
986
987 assert_eq!(expr, Expr::Binary(Binary {
988 lhs: Box::new(Expr::Binary(Binary {
989 lhs: Box::new(Expr::Binary(Binary {
990 lhs: Box::new(Expr::Binary(Binary {
991 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
992 name: "pi".to_string(),
993 span: 0..2,
994 }))),
995 op: BinOp {
996 kind: BinOpKind::Exp,
997 implicit: false,
998 span: 2..3,
999 },
1000 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1001 value: "2".to_string(),
1002 span: 3..4,
1003 }))),
1004 span: 0..4,
1005 })),
1006 op: BinOp {
1007 kind: BinOpKind::Mul,
1008 implicit: false,
1009 span: 5..6,
1010 },
1011 rhs: Box::new(Expr::Unary(Unary {
1012 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1013 value: "17".to_string(),
1014 span: 7..9,
1015 }))),
1016 op: UnaryOp {
1017 kind: UnaryOpKind::Factorial,
1018 span: 9..10,
1019 },
1020 span: 7..10,
1021 })),
1022 span: 0..10,
1023 })),
1024 op: BinOp {
1025 kind: BinOpKind::Div,
1026 implicit: false,
1027 span: 11..12,
1028 },
1029 rhs: Box::new(Expr::Unary(Unary {
1030 operand: Box::new(Expr::Literal(Literal::Float(LitFloat {
1031 value: "4.9".to_string(),
1032 span: 14..17,
1033 }))),
1034 op: UnaryOp {
1035 kind: UnaryOpKind::Neg,
1036 span: 13..14,
1037 },
1038 span: 13..17,
1039 })),
1040 span: 0..17,
1041 })),
1042 op: BinOp {
1043 kind: BinOpKind::Add,
1044 implicit: false,
1045 span: 18..19,
1046 },
1047 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1048 name: "e".to_string(),
1049 span: 20..21,
1050 }))),
1051 span: 0..21,
1052 }));
1053 }
1054
1055 #[test]
1056 fn implicit_multiplication() {
1057 let mut parser = Parser::new("2(3 + 4)");
1058 let expr = parser.try_parse_full::<Expr>().unwrap();
1059
1060 assert_eq!(expr, Expr::Binary(Binary {
1061 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1062 value: "2".to_string(),
1063 span: 0..1,
1064 }))),
1065 op: BinOp {
1066 kind: BinOpKind::Mul,
1067 implicit: true,
1068 span: 1..1,
1069 },
1070 rhs: Box::new(Expr::Paren(Paren {
1071 expr: Box::new(Expr::Binary(Binary {
1072 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1073 value: "3".to_string(),
1074 span: 2..3,
1075 }))),
1076 op: BinOp {
1077 kind: BinOpKind::Add,
1078 implicit: false,
1079 span: 4..5,
1080 },
1081 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1082 value: "4".to_string(),
1083 span: 6..7,
1084 }))),
1085 span: 2..7,
1086 })),
1087 span: 1..8,
1088 })),
1089 span: 0..8,
1090 }));
1091 }
1092
1093 #[test]
1094 fn implicit_multiplication_2() {
1095 let mut parser = Parser::new("1 + 2x");
1096 let expr = parser.try_parse_full::<Expr>().unwrap();
1097
1098 assert_eq!(expr, Expr::Binary(Binary {
1099 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1100 value: "1".to_string(),
1101 span: 0..1,
1102 }))),
1103 op: BinOp {
1104 kind: BinOpKind::Add,
1105 implicit: false,
1106 span: 2..3,
1107 },
1108 rhs: Box::new(Expr::Binary(Binary {
1109 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1110 value: "2".to_string(),
1111 span: 4..5,
1112 }))),
1113 op: BinOp {
1114 kind: BinOpKind::Mul,
1115 implicit: true,
1116 span: 5..5,
1117 },
1118 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1119 name: "x".to_string(),
1120 span: 5..6,
1121 }))),
1122 span: 4..6,
1123 })),
1124 span: 0..6,
1125 }));
1126 }
1127
1128 #[test]
1129 fn implicit_multiplication_3() {
1130 let mut parser = Parser::new("(1 - x)(1 + x)");
1131 let expr = parser.try_parse_full::<Expr>().unwrap();
1132
1133 assert_eq!(expr, Expr::Binary(Binary {
1134 lhs: Box::new(Expr::Paren(Paren {
1135 expr: Box::new(Expr::Binary(Binary {
1136 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1137 value: "1".to_string(),
1138 span: 1..2,
1139 }))),
1140 op: BinOp {
1141 kind: BinOpKind::Sub,
1142 implicit: false,
1143 span: 3..4,
1144 },
1145 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1146 name: "x".to_string(),
1147 span: 5..6,
1148 }))),
1149 span: 1..6,
1150 })),
1151 span: 0..7,
1152 })),
1153 op: BinOp {
1154 kind: BinOpKind::Mul,
1155 implicit: true,
1156 span: 7..7,
1157 },
1158 rhs: Box::new(Expr::Paren(Paren {
1159 expr: Box::new(Expr::Binary(Binary {
1160 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1161 value: "1".to_string(),
1162 span: 8..9,
1163 }))),
1164 op: BinOp {
1165 kind: BinOpKind::Add,
1166 implicit: false,
1167 span: 10..11,
1168 },
1169 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1170 name: "x".to_string(),
1171 span: 12..13,
1172 }))),
1173 span: 8..13,
1174 })),
1175 span: 7..14,
1176 })),
1177 span: 0..14,
1178 }));
1179 }
1180
1181 #[test]
1182 fn implicit_multiplication_extra() {
1183 let mut parser = Parser::new("4x^2 + 5x + 1");
1184 let expr = parser.try_parse_full::<Expr>().unwrap();
1185
1186 assert_eq!(expr, Expr::Binary(Binary {
1187 lhs: Box::new(Expr::Binary(Binary {
1188 lhs: Box::new(Expr::Binary(Binary {
1189 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1190 value: "4".to_string(),
1191 span: 0..1,
1192 }))),
1193 op: BinOp {
1194 kind: BinOpKind::Mul,
1195 implicit: true,
1196 span: 1..1,
1197 },
1198 rhs: Box::new(Expr::Binary(Binary {
1199 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1200 name: "x".to_string(),
1201 span: 1..2,
1202 }))),
1203 op: BinOp {
1204 kind: BinOpKind::Exp,
1205 implicit: false,
1206 span: 2..3,
1207 },
1208 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1209 value: "2".to_string(),
1210 span: 3..4,
1211 }))),
1212 span: 1..4,
1213 })),
1214 span: 0..4,
1215 })),
1216 op: BinOp {
1217 kind: BinOpKind::Add,
1218 implicit: false,
1219 span: 5..6,
1220 },
1221 rhs: Box::new(Expr::Binary(Binary {
1222 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1223 value: "5".to_string(),
1224 span: 7..8,
1225 }))),
1226 op: BinOp {
1227 kind: BinOpKind::Mul,
1228 implicit: true,
1229 span: 8..8,
1230 },
1231 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1232 name: "x".to_string(),
1233 span: 8..9,
1234 }))),
1235 span: 7..9,
1236 })),
1237 span: 0..9,
1238 })),
1239 op: BinOp {
1240 kind: BinOpKind::Add,
1241 implicit: false,
1242 span: 10..11,
1243 },
1244 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1245 value: "1".to_string(),
1246 span: 12..13,
1247 }))),
1248 span: 0..13,
1249 }));
1250 }
1251
1252 #[test]
1253 fn implicit_multiplication_extra_2() {
1254 let mut parser = Parser::new("3^42.9i");
1255 let expr = parser.try_parse_full::<Expr>().unwrap();
1256
1257 assert_eq!(expr, Expr::Binary(Binary {
1258 lhs: Box::new(Expr::Binary(Binary {
1259 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1260 value: "3".to_string(),
1261 span: 0..1,
1262 }))),
1263 op: BinOp {
1264 kind: BinOpKind::Exp,
1265 implicit: false,
1266 span: 1..2,
1267 },
1268 rhs: Box::new(Expr::Literal(Literal::Float(LitFloat {
1269 value: "42.9".to_string(),
1270 span: 2..6,
1271 }))),
1272 span: 0..6,
1273 })),
1274 op: BinOp {
1275 kind: BinOpKind::Mul,
1276 implicit: true,
1277 span: 6..6,
1278 },
1279 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1280 name: "i".to_string(),
1281 span: 6..7,
1282 }))),
1283 span: 0..7,
1284 }));
1285 }
1286
1287 #[test]
1288 fn implicit_multiplication_nonsensical() {
1289 let mut parser = Parser::new("2!! 3!!");
1290 let expr = parser.try_parse_full::<Expr>().unwrap();
1291
1292 assert_eq!(expr, Expr::Binary(Binary {
1293 lhs: Box::new(Expr::Unary(Unary {
1294 operand: Box::new(Expr::Unary(Unary {
1295 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1296 value: "2".to_string(),
1297 span: 0..1,
1298 }))),
1299 op: UnaryOp {
1300 kind: UnaryOpKind::Factorial,
1301 span: 1..2,
1302 },
1303 span: 0..2,
1304 })),
1305 op: UnaryOp {
1306 kind: UnaryOpKind::Factorial,
1307 span: 2..3,
1308 },
1309 span: 0..3,
1310 })),
1311 op: BinOp {
1312 kind: BinOpKind::Mul,
1313 implicit: true,
1314 span: 3..4,
1315 },
1316 rhs: Box::new(Expr::Unary(Unary {
1317 operand: Box::new(Expr::Unary(Unary {
1318 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1319 value: "3".to_string(),
1320 span: 4..5,
1321 }))),
1322 op: UnaryOp {
1323 kind: UnaryOpKind::Factorial,
1324 span: 5..6,
1325 },
1326 span: 4..6,
1327 })),
1328 op: UnaryOp {
1329 kind: UnaryOpKind::Factorial,
1330 span: 6..7,
1331 },
1332 span: 4..7,
1333 })),
1334 span: 0..7,
1335 }));
1336 }
1337
1338 #[test]
1339 fn implicit_multiplication_ambiguous() {
1340 let mut parser = Parser::new("1 / 2a");
1341 let expr = parser.try_parse_full::<Expr>().unwrap();
1342
1343 assert_eq!(expr, Expr::Binary(Binary {
1344 lhs: Box::new(Expr::Binary(Binary {
1345 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1346 value: "1".to_string(),
1347 span: 0..1,
1348 }))),
1349 op: BinOp {
1350 kind: BinOpKind::Div,
1351 implicit: false,
1352 span: 2..3,
1353 },
1354 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1355 value: "2".to_string(),
1356 span: 4..5,
1357 }))),
1358 span: 0..5,
1359 })),
1360 op: BinOp {
1361 kind: BinOpKind::Mul,
1362 implicit: true,
1363 span: 5..5,
1364 },
1365 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1366 name: "a".to_string(),
1367 span: 5..6,
1368 }))),
1369 span: 0..6,
1370 }));
1371 }
1372
1373 #[test]
1374 fn implicit_multiplication_terms_with_power() {
1375 let mut parser = Parser::new("-16x y + 2x^2y");
1376 let expr = parser.try_parse_full::<Expr>().unwrap();
1377
1378 let lhs = Expr::Binary(Binary {
1380 lhs: Box::new(Expr::Binary(Binary {
1381 lhs: Box::new(Expr::Unary(Unary {
1382 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1383 value: "16".to_string(),
1384 span: 1..3,
1385 }))),
1386 op: UnaryOp {
1387 kind: UnaryOpKind::Neg,
1388 span: 0..1,
1389 },
1390 span: 0..3,
1391 })),
1392 op: BinOp {
1393 kind: BinOpKind::Mul,
1394 implicit: true,
1395 span: 3..3,
1396 },
1397 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1398 name: "x".to_string(),
1399 span: 3..4,
1400 }))),
1401 span: 0..4,
1402 })),
1403 op: BinOp {
1404 kind: BinOpKind::Mul,
1405 implicit: true,
1406 span: 4..5,
1407 },
1408 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1409 name: "y".to_string(),
1410 span: 5..6,
1411 }))),
1412 span: 0..6,
1413 });
1414
1415 let rhs = Expr::Binary(Binary {
1417 lhs: Box::new(Expr::Binary(Binary {
1418 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1419 value: "2".to_string(),
1420 span: 9..10,
1421 }))),
1422 op: BinOp {
1423 kind: BinOpKind::Mul,
1424 implicit: true,
1425 span: 10..10,
1426 },
1427 rhs: Box::new(Expr::Binary(Binary {
1428 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1429 name: "x".to_string(),
1430 span: 10..11,
1431 }))),
1432 op: BinOp {
1433 kind: BinOpKind::Exp,
1434 implicit: false,
1435 span: 11..12,
1436 },
1437 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1438 value: "2".to_string(),
1439 span: 12..13,
1440 }))),
1441 span: 10..13,
1442 })),
1443 span: 9..13,
1444 })),
1445 op: BinOp {
1446 kind: BinOpKind::Mul,
1447 implicit: true,
1448 span: 13..13,
1449 },
1450 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1451 name: "y".to_string(),
1452 span: 13..14,
1453 }))),
1454 span: 9..14,
1455 });
1456
1457 let add = Expr::Binary(Binary {
1459 lhs: Box::new(lhs),
1460 op: BinOp {
1461 kind: BinOpKind::Add,
1462 implicit: false,
1463 span: 7..8,
1464 },
1465 rhs: Box::new(rhs),
1466 span: 0..14,
1467 });
1468
1469 assert_eq!(expr, add);
1470 }
1471
1472 #[test]
1473 fn parenthesized() {
1474 let mut parser = Parser::new("(1 + 2) * __");
1475 let expr = parser.try_parse_full::<Expr>().unwrap();
1476
1477 assert_eq!(expr, Expr::Binary(Binary {
1478 lhs: Box::new(Expr::Paren(Paren {
1479 expr: Box::new(Expr::Binary(Binary {
1480 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1481 value: "1".to_string(),
1482 span: 1..2,
1483 }))),
1484 op: BinOp {
1485 kind: BinOpKind::Add,
1486 implicit: false,
1487 span: 3..4,
1488 },
1489 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1490 value: "2".to_string(),
1491 span: 5..6,
1492 }))),
1493 span: 1..6,
1494 })),
1495 span: 0..7,
1496 })),
1497 op: BinOp {
1498 kind: BinOpKind::Mul,
1499 implicit: false,
1500 span: 8..9,
1501 },
1502 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1503 name: "__".to_string(),
1504 span: 10..12,
1505 }))),
1506 span: 0..12,
1507 }));
1508 }
1509
1510 #[test]
1511 fn parenthesized_complicated() {
1512 let mut parser = Parser::new("(3 * 9 + 4.0 / 11.9 % (6 - 3))");
1513 let expr = parser.try_parse_full::<Expr>().unwrap();
1514
1515 assert_eq!(expr, Expr::Paren(Paren {
1516 expr: Box::new(Expr::Binary(Binary {
1517 lhs: Box::new(Expr::Binary(Binary {
1518 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1519 value: "3".to_string(),
1520 span: 1..2,
1521 }))),
1522 op: BinOp {
1523 kind: BinOpKind::Mul,
1524 implicit: false,
1525 span: 3..4,
1526 },
1527 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1528 value: "9".to_string(),
1529 span: 5..6,
1530 }))),
1531 span: 1..6,
1532 })),
1533 op: BinOp {
1534 kind: BinOpKind::Add,
1535 implicit: false,
1536 span: 7..8,
1537 },
1538 rhs: Box::new(Expr::Binary(Binary {
1539 lhs: Box::new(Expr::Binary(Binary {
1540 lhs: Box::new(Expr::Literal(Literal::Float(LitFloat {
1541 value: "4.0".to_string(),
1542 span: 9..12,
1543 }))),
1544 op: BinOp {
1545 kind: BinOpKind::Div,
1546 implicit: false,
1547 span: 13..14,
1548 },
1549 rhs: Box::new(Expr::Literal(Literal::Float(LitFloat {
1550 value: "11.9".to_string(),
1551 span: 15..19,
1552 }))),
1553 span: 9..19,
1554 })),
1555 op: BinOp {
1556 kind: BinOpKind::Mod,
1557 implicit: false,
1558 span: 20..21,
1559 },
1560 rhs: Box::new(Expr::Paren(Paren {
1561 expr: Box::new(Expr::Binary(Binary {
1562 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1563 value: "6".to_string(),
1564 span: 23..24,
1565 }))),
1566 op: BinOp {
1567 kind: BinOpKind::Sub,
1568 implicit: false,
1569 span: 25..26,
1570 },
1571 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1572 value: "3".to_string(),
1573 span: 27..28,
1574 }))),
1575 span: 23..28,
1576 })),
1577 span: 22..29,
1578 })),
1579 span: 9..29,
1580 })),
1581 span: 1..29,
1582 })),
1583 span: 0..30,
1584 }));
1585 }
1586
1587 #[test]
1588 fn block_code() {
1589 let mut parser = Parser::new("{ x = 5; y = 6; x + y }");
1590 let expr = parser.try_parse_full::<Expr>().unwrap();
1591
1592 assert_eq!(expr, Expr::Block(Block {
1593 stmts: vec![
1594 Stmt {
1595 expr: Expr::Assign(Assign {
1596 target: AssignTarget::Symbol(LitSym {
1597 name: "x".to_string(),
1598 span: 2..3,
1599 }),
1600 op: AssignOp {
1601 kind: AssignOpKind::Assign,
1602 span: 4..5,
1603 },
1604 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1605 value: "5".to_string(),
1606 span: 6..7,
1607 }))),
1608 span: 2..7,
1609 }),
1610 semicolon: Some(7..8),
1611 span: 2..8,
1612 },
1613 Stmt {
1614 expr: Expr::Assign(Assign {
1615 target: AssignTarget::Symbol(LitSym {
1616 name: "y".to_string(),
1617 span: 9..10,
1618 }),
1619 op: AssignOp {
1620 kind: AssignOpKind::Assign,
1621 span: 11..12,
1622 },
1623 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1624 value: "6".to_string(),
1625 span: 13..14,
1626 }))),
1627 span: 9..14,
1628 }),
1629 semicolon: Some(14..15),
1630 span: 9..15,
1631 },
1632 Stmt {
1633 expr: Expr::Binary(Binary {
1634 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1635 name: "x".to_string(),
1636 span: 16..17,
1637 }))),
1638 op: BinOp {
1639 kind: BinOpKind::Add,
1640 implicit: false,
1641 span: 18..19,
1642 },
1643 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1644 name: "y".to_string(),
1645 span: 20..21,
1646 }))),
1647 span: 16..21,
1648 }),
1649 semicolon: None,
1650 span: 16..21,
1651 },
1652 ],
1653 span: 0..23,
1654 }));
1655 }
1656
1657 #[test]
1658 fn if_block() {
1659 let mut parser = Parser::new("if d then { abs''(d) } else { f = 1; f }");
1660 let expr = parser.try_parse_full::<Expr>().unwrap();
1661
1662 assert_eq!(expr, Expr::If(If {
1663 condition: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1664 name: "d".to_string(),
1665 span: 3..4,
1666 }))),
1667 then_expr: Box::new(Expr::Block(Block {
1668 stmts: vec![
1669 Stmt {
1670 expr: Expr::Call(Call {
1671 name: LitSym {
1672 name: "abs".to_string(),
1673 span: 12..15,
1674 },
1675 derivatives: 2,
1676 args: vec![
1677 Expr::Literal(Literal::Symbol(LitSym {
1678 name: "d".to_string(),
1679 span: 18..19,
1680 })),
1681 ],
1682 span: 12..20,
1683 paren_span: 17..20,
1684 }),
1685 semicolon: None,
1686 span: 12..20,
1687 },
1688 ],
1689 span: 10..22,
1690 })),
1691 else_expr: Some(Box::new(Expr::Block(Block {
1692 stmts: vec![
1693 Stmt {
1694 expr: Expr::Assign(Assign {
1695 target: AssignTarget::Symbol(LitSym {
1696 name: "f".to_string(),
1697 span: 30..31,
1698 }),
1699 op: AssignOp {
1700 kind: AssignOpKind::Assign,
1701 span: 32..33,
1702 },
1703 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1704 value: "1".to_string(),
1705 span: 34..35,
1706 }))),
1707 span: 30..35,
1708 }),
1709 semicolon: Some(35..36),
1710 span: 30..36,
1711 },
1712 Stmt {
1713 expr: Expr::Literal(Literal::Symbol(LitSym {
1714 name: "f".to_string(),
1715 span: 37..38,
1716 })),
1717 semicolon: None,
1718 span: 37..38,
1719 },
1720 ],
1721 span: 28..40,
1722 }))),
1723 span: 0..40,
1724 if_span: 0..2,
1725 then_span: 5..9,
1726 else_span: Some(23..27),
1727 }));
1728 }
1729
1730 #[test]
1731 fn assign_to_var() {
1732 let mut parser = Parser::new("fx += 1 / pi");
1733 let expr = parser.try_parse_full::<Expr>().unwrap();
1734
1735 assert_eq!(expr, Expr::Assign(Assign {
1736 target: AssignTarget::Symbol(LitSym {
1737 name: "fx".to_string(),
1738 span: 0..2,
1739 }),
1740 op: AssignOp {
1741 kind: AssignOpKind::Add,
1742 span: 3..5,
1743 },
1744 value: Box::new(Expr::Binary(Binary {
1745 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1746 value: "1".to_string(),
1747 span: 6..7,
1748 }))),
1749 op: BinOp {
1750 kind: BinOpKind::Div,
1751 implicit: false,
1752 span: 8..9,
1753 },
1754 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1755 name: "pi".to_string(),
1756 span: 10..12,
1757 }))),
1758 span: 6..12,
1759 })),
1760 span: 0..12,
1761 }));
1762 }
1763
1764 #[test]
1765 fn assign_to_function() {
1766 let mut parser = Parser::new("f(x) = x^2 + 5x");
1767 let expr = parser.try_parse_full::<Expr>().unwrap();
1768
1769 assert_eq!(expr, Expr::Assign(Assign {
1770 target: AssignTarget::Func(FuncHeader {
1771 name: LitSym {
1772 name: "f".to_string(),
1773 span: 0..1,
1774 },
1775 params: vec![
1776 Param::Symbol(LitSym {
1777 name: "x".to_string(),
1778 span: 2..3,
1779 }),
1780 ],
1781 span: 0..4,
1782 }),
1783 op: AssignOp {
1784 kind: AssignOpKind::Assign,
1785 span: 5..6,
1786 },
1787 value: Box::new(Expr::Binary(Binary {
1788 lhs: Box::new(Expr::Binary(Binary {
1789 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1790 name: "x".to_string(),
1791 span: 7..8,
1792 }))),
1793 op: BinOp {
1794 kind: BinOpKind::Exp,
1795 implicit: false,
1796 span: 8..9,
1797 },
1798 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1799 value: "2".to_string(),
1800 span: 9..10,
1801 }))),
1802 span: 7..10,
1803 })),
1804 op: BinOp {
1805 kind: BinOpKind::Add,
1806 implicit: false,
1807 span: 11..12,
1808 },
1809 rhs: Box::new(Expr::Binary(Binary {
1810 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1811 value: "5".to_string(),
1812 span: 13..14,
1813 }))),
1814 op: BinOp {
1815 kind: BinOpKind::Mul,
1816 implicit: true,
1817 span: 14..14,
1818 },
1819 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1820 name: "x".to_string(),
1821 span: 14..15,
1822 }))),
1823 span: 13..15,
1824 })),
1825 span: 7..15,
1826 })),
1827 span: 0..15,
1828 }));
1829 }
1830
1831 #[test]
1832 fn assign_to_complicated_function() {
1833 let mut parser = Parser::new("discrim(a = 1, b = 5, c) = b^2 - 4a * c");
1834 let expr = parser.try_parse_full::<Expr>().unwrap();
1835
1836 assert_eq!(expr, Expr::Assign(Assign {
1837 target: AssignTarget::Func(FuncHeader {
1838 name: LitSym {
1839 name: "discrim".to_string(),
1840 span: 0..7,
1841 },
1842 params: vec![
1843 Param::Default(
1844 LitSym {
1845 name: "a".to_string(),
1846 span: 8..9,
1847 },
1848 Expr::Literal(Literal::Integer(LitInt {
1849 value: "1".to_string(),
1850 span: 12..13,
1851 })),
1852 ),
1853 Param::Default(
1854 LitSym {
1855 name: "b".to_string(),
1856 span: 15..16,
1857 },
1858 Expr::Literal(Literal::Integer(LitInt {
1859 value: "5".to_string(),
1860 span: 19..20,
1861 })),
1862 ),
1863 Param::Symbol(
1864 LitSym {
1865 name: "c".to_string(),
1866 span: 22..23,
1867 },
1868 ),
1869 ],
1870 span: 0..24,
1871 }),
1872 op: AssignOp {
1873 kind: AssignOpKind::Assign,
1874 span: 25..26,
1875 },
1876 value: Box::new(Expr::Binary(Binary {
1877 lhs: Box::new(Expr::Binary(Binary {
1878 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1879 name: "b".to_string(),
1880 span: 27..28,
1881 }))),
1882 op: BinOp {
1883 kind: BinOpKind::Exp,
1884 implicit: false,
1885 span: 28..29,
1886 },
1887 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1888 value: "2".to_string(),
1889 span: 29..30,
1890 }))),
1891 span: 27..30,
1892 })),
1893 op: BinOp {
1894 kind: BinOpKind::Sub,
1895 implicit: false,
1896 span: 31..32,
1897 },
1898 rhs: Box::new(Expr::Binary(Binary {
1899 lhs: Box::new(Expr::Binary(Binary {
1900 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1901 value: "4".to_string(),
1902 span: 33..34,
1903 }))),
1904 op: BinOp {
1905 kind: BinOpKind::Mul,
1906 implicit: true,
1907 span: 34..34,
1908 },
1909 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1910 name: "a".to_string(),
1911 span: 34..35,
1912 }))),
1913 span: 33..35,
1914 })),
1915 op: BinOp {
1916 kind: BinOpKind::Mul,
1917 implicit: false,
1918 span: 36..37,
1919 },
1920 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1921 name: "c".to_string(),
1922 span: 38..39,
1923 }))),
1924 span: 33..39,
1925 })),
1926 span: 27..39,
1927 })),
1928 span: 0..39,
1929 }));
1930 }
1931
1932 #[test]
1933 fn function_call() {
1934 let mut parser = Parser::new("f(x)");
1935 let expr = parser.try_parse_full::<Expr>().unwrap();
1936
1937 assert_eq!(expr, Expr::Call(Call {
1938 name: LitSym {
1939 name: "f".to_string(),
1940 span: 0..1,
1941 },
1942 derivatives: 0,
1943 args: vec![
1944 Expr::Literal(Literal::Symbol(LitSym {
1945 name: "x".to_string(),
1946 span: 2..3,
1947 })),
1948 ],
1949 span: 0..4,
1950 paren_span: 1..4,
1951 }));
1952 }
1953
1954 #[test]
1955 fn function_call_whitespace() {
1956 let mut parser = Parser::new("ncr ' ' ' '' ' ( 8 , 5 )");
1957 let expr = parser.try_parse_full::<Expr>().unwrap();
1958
1959 assert_eq!(expr, Expr::Call(Call {
1960 name: LitSym {
1961 name: "ncr".to_string(),
1962 span: 0..3,
1963 },
1964 derivatives: 6,
1965 args: vec![
1966 Expr::Literal(Literal::Integer(LitInt {
1967 value: "8".to_string(),
1968 span: 18..19,
1969 })),
1970 Expr::Literal(Literal::Integer(LitInt {
1971 value: "5".to_string(),
1972 span: 22..23,
1973 })),
1974 ],
1975 span: 0..25,
1976 paren_span: 16..25,
1977 }));
1978 }
1979
1980 #[test]
1981 fn blank_function_header() {
1982 let mut parser = Parser::new("f() = 5");
1983 let expr = parser.try_parse_full::<Expr>().unwrap();
1984
1985 assert_eq!(expr, Expr::Assign(Assign {
1986 target: AssignTarget::Func(FuncHeader {
1987 name: LitSym {
1988 name: "f".to_string(),
1989 span: 0..1,
1990 },
1991 params: vec![],
1992 span: 0..3,
1993 }),
1994 op: AssignOp {
1995 kind: AssignOpKind::Assign,
1996 span: 4..5,
1997 },
1998 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1999 value: "5".to_string(),
2000 span: 6..7,
2001 }))),
2002 span: 0..7,
2003 }));
2004 }
2005
2006 #[test]
2007 fn catastrophic_backtracking() {
2008 let mut parser = Parser::new("a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a()");
2010 assert!(parser.try_parse_full::<Expr>().is_err());
2011 }
2012
2013 #[test]
2014 fn oneline_while_loop() {
2015 let mut parser = Parser::new("while x < 5 then x += 1");
2016 let expr = parser.try_parse_full::<Expr>().unwrap();
2017
2018 assert_eq!(expr, Expr::While(While {
2019 condition: Box::new(Expr::Binary(Binary {
2020 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2021 name: "x".to_string(),
2022 span: 6..7,
2023 }))),
2024 op: BinOp {
2025 kind: BinOpKind::Less,
2026 implicit: false,
2027 span: 8..9,
2028 },
2029 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2030 value: "5".to_string(),
2031 span: 10..11,
2032 }))),
2033 span: 6..11,
2034 })),
2035 body: Box::new(Expr::Assign(Assign {
2036 target: AssignTarget::Symbol(LitSym {
2037 name: "x".to_string(),
2038 span: 17..18,
2039 }),
2040 op: AssignOp {
2041 kind: AssignOpKind::Add,
2042 span: 19..21,
2043 },
2044 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
2045 value: "1".to_string(),
2046 span: 22..23,
2047 }))),
2048 span: 17..23,
2049 })),
2050 span: 0..23,
2051 while_span: 0..5,
2052 then_span: 12..16,
2053 }));
2054 }
2055
2056 #[test]
2057 fn source_code() {
2058 let mut parser = Parser::new("x = 5;
2059iseven(n) = n % 2 == 0;
2060if iseven(x) then {
2061 x^2 + 5x + 6
2062} else if (bool(x) && false) then {
2063 exp(x)
2064} else {
2065 log(x, 2)
2066}");
2067 assert!(parser.try_parse_full_many::<Stmt>().is_ok());
2068 }
2069}