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, Error};
10use error::{ExpectedEof, UnexpectedEoExpr, UnexpectedEof};
11use super::tokenizer::{tokenize_complete, Token};
12use std::{ops::Range, sync::Arc};
13
14#[derive(Debug, Clone, Default)]
19pub struct ParserState {
20 pub allow_then: bool,
25
26 pub allow_of: bool,
30
31 pub allow_loop_control: bool,
36
37 pub allow_return: bool,
41
42 pub expr_end_at_eol: bool,
65}
66
67#[derive(Debug, Clone)]
73pub struct Parser<'source> {
74 tokens: Arc<[Token<'source>]>,
76
77 cursor: usize,
79
80 state: ParserState,
85}
86
87impl<'source> Parser<'source> {
88 pub fn new(source: &'source str) -> Self {
90 Self {
91 tokens: tokenize_complete(source).into(),
92 cursor: 0,
93 state: ParserState::default(),
94 }
95 }
96
97 pub fn state(&self) -> &ParserState {
99 &self.state
100 }
101
102 pub fn set_cursor(&mut self, other: &Self) {
105 self.cursor = other.cursor;
106 }
107
108 pub fn error(&self, kind: impl ErrorKind + 'static) -> Error {
111 Error::new(vec![self.span()], kind)
112 }
113
114 pub fn eof_span(&self) -> Range<usize> {
116 self.tokens.last().map_or(0..0, |token| token.span.end..token.span.end)
117 }
118
119 pub fn span(&self) -> Range<usize> {
122 self.tokens
123 .get(self.cursor)
124 .map_or(self.eof_span(), |token| token.span.clone())
125 }
126
127 pub fn prev(&mut self) {
130 if self.cursor > 0 {
131 self.cursor -= 1;
132 }
133 }
134
135 pub fn prev_token(&self) -> Option<&Token<'source>> {
138 self.tokens.get(self.cursor.checked_sub(1)?)
139 }
140
141 pub fn current_token(&self) -> Option<&Token<'source>> {
144 self.tokens.get(self.cursor)
145 }
146
147 pub fn advance_past_whitespace(&mut self) {
151 while let Some(token) = self.tokens.get(self.cursor) {
152 if token.is_ignore() {
153 self.cursor += 1;
154 continue;
155 } else {
156 break;
157 }
158 }
159 }
160
161 pub fn advance_past_non_significant_whitespace(&mut self) {
211 while let Some(token) = self.tokens.get(self.cursor) {
212 if token.is_ignore() && !token.is_significant_whitespace() {
213 self.cursor += 1;
214 continue;
215 } else {
216 break;
217 }
218 }
219 }
220
221 pub fn next_token(&mut self) -> Result<Token<'source>, Error> {
225 self.advance_past_whitespace();
226 self.next_token_raw()
227 }
228
229 pub fn next_token_raw(&mut self) -> Result<Token<'source>, Error> {
233 let result = self.current_token()
234 .cloned() .ok_or_else(|| self.error(UnexpectedEof));
236 self.cursor += 1;
237 result
238 }
239
240 fn check_eol(&mut self) -> Result<(), Error> {
245 if self.state.expr_end_at_eol {
246 if let Some(token) = self.current_token() {
247 if token.is_significant_whitespace() {
248 return Err(self.error(UnexpectedEoExpr));
249 }
250 }
251 }
252
253 Ok(())
254 }
255
256 pub fn try_parse<T: Parse<'source>>(&mut self) -> ParseResult<T> {
263 self.try_parse_with_fn(T::parse)
264 }
265
266 pub fn try_parse_with_state<F, T>(&mut self, modify_state: F) -> ParseResult<T>
277 where
278 F: FnOnce(&mut ParserState),
279 T: Parse<'source>,
280 {
281 let mut state = self.state.clone();
282 modify_state(&mut state);
283
284 let mut new_parser = Self {
285 tokens: self.tokens.clone(),
286 cursor: self.cursor,
287 state,
288 };
289
290 let t = new_parser.try_parse();
291 self.set_cursor(&new_parser);
292 t
293 }
294
295 pub fn try_parse_with_fn<T, F>(&mut self, f: F) -> ParseResult<T>
303 where
304 F: FnOnce(&mut Parser<'source>) -> ParseResult<T>,
305 {
306 let start = self.cursor;
307 let out = if let Err(err) = self.check_eol() {
308 ParseResult::Unrecoverable(vec![err])
309 } else {
310 f(self)
311 };
312 out.inspect_unrecoverable(|_| self.cursor = start)
313 }
314
315 pub fn try_parse_then<T: Parse<'source>, F>(&mut self, predicate: F) -> ParseResult<T>
322 where
323 F: FnOnce(&T, &Parser) -> ParseResult<()>,
324 {
325 let start = self.cursor;
326 let mut errors = Vec::new();
327
328 let inner = || {
329 self.check_eol().map_err(|err| vec![err])?;
330 let value = T::parse(self).forward_errors(&mut errors)?;
331 predicate(&value, self).forward_errors(&mut errors)?;
332 Ok(value)
333 };
334
335 inner()
336 .map(|value| (value, errors))
337 .inspect_err(|_unrecoverable| {
338 self.cursor = start;
339 })
340 .into()
341 }
342
343 pub fn try_parse_full<T: Parse<'source>>(&mut self) -> Result<T, Vec<Error>> {
346 let mut errors = Vec::new();
347 let value = T::parse(self).forward_errors(&mut errors)?;
348
349 self.advance_past_whitespace();
351
352 if self.cursor < self.tokens.len() {
353 errors.push(self.error(ExpectedEof));
354 }
355
356 if errors.is_empty() {
357 Ok(value)
358 } else {
359 Err(errors)
360 }
361 }
362
363 pub fn try_parse_full_many<T: std::fmt::Debug + Parse<'source>>(&mut self) -> Result<Vec<T>, Vec<Error>> {
366 let mut errors = Vec::new();
367 let mut values = Vec::new();
368
369 while self.cursor < self.tokens.len() {
370 let Ok(value) = T::parse(self).forward_errors(&mut errors) else {
371 break;
372 };
373 values.push(value);
374 }
375
376 self.advance_past_whitespace();
378
379 if self.cursor < self.tokens.len() {
380 errors.push(self.error(ExpectedEof));
381 }
382
383 if errors.is_empty() {
384 Ok(values)
385 } else {
386 Err(errors)
387 }
388 }
389}
390
391pub trait Parse<'source>: Sized {
393 fn std_parse(
402 input: &mut Parser<'source>,
403 recoverable_errors: &mut Vec<Error>
404 ) -> Result<Self, Vec<Error>>;
405
406 fn parse(input: &mut Parser<'source>) -> ParseResult<Self> {
411 let mut recoverable_errors = Vec::new();
412 Self::std_parse(input, &mut recoverable_errors)
413 .map(|value| (value, recoverable_errors))
414 .into()
415 }
416}
417
418#[derive(Debug)]
420pub enum ParseResult<T> {
421 Ok(T),
423
424 Recoverable(T, Vec<Error>),
431
432 Unrecoverable(Vec<Error>),
435}
436
437impl<T> From<Result<(T, Vec<Error>), Vec<Error>>> for ParseResult<T> {
438 fn from(result: Result<(T, Vec<Error>), Vec<Error>>) -> Self {
439 match result {
440 Ok((value, errors)) => (value, errors).into(),
441 Err(unrecoverable_errors) => Self::Unrecoverable(unrecoverable_errors),
442 }
443 }
444}
445
446impl<T> From<(T, Vec<Error>)> for ParseResult<T> {
447 fn from((value, errors): (T, Vec<Error>)) -> Self {
448 if errors.is_empty() {
449 Self::Ok(value)
450 } else {
451 Self::Recoverable(value, errors)
452 }
453 }
454}
455
456impl<T> From<Vec<Error>> for ParseResult<T> {
457 fn from(errors: Vec<Error>) -> Self {
458 Self::Unrecoverable(errors)
459 }
460}
461
462impl<T> ParseResult<T> {
463 pub fn forward_errors(self, errors: &mut Vec<Error>) -> Result<T, Vec<Error>> {
473 match self {
474 Self::Ok(value) => Ok(value),
475 Self::Recoverable(value, mut errs) => {
476 errors.append(&mut errs);
477 Ok(value)
478 },
479 Self::Unrecoverable(errs) => Err(errs),
480 }
481 }
482
483 pub fn is_ok(&self) -> bool {
485 matches!(self, ParseResult::Ok(_))
486 }
487
488 pub fn inspect_unrecoverable<F>(self, f: F) -> Self
492 where
493 F: FnOnce(&Vec<Error>),
494 {
495 if let Self::Unrecoverable(errs) = &self {
496 f(errs);
497 }
498
499 self
500 }
501
502 pub fn map<U, F>(self, f: F) -> ParseResult<U>
508 where
509 F: FnOnce(T) -> U,
510 {
511 match self {
512 ParseResult::Ok(value) => ParseResult::Ok(f(value)),
513 ParseResult::Recoverable(value, errors) => ParseResult::Recoverable(f(value), errors),
514
515 ParseResult::Unrecoverable(errors) => ParseResult::Unrecoverable(errors),
518 }
519 }
520
521 pub fn or_else<F>(self, op: F) -> Self
525 where
526 F: FnOnce() -> Self,
527 {
528 match self {
529 ParseResult::Recoverable(..) | ParseResult::Unrecoverable(_) => op(),
530 ok => ok,
531 }
532 }
533}
534
535#[macro_export]
540macro_rules! return_if_ok {
541 ($result:expr) => {
542 match $result {
543 Ok(value) => return Ok(value),
544 Err(errors) => errors,
545 }
546 };
547}
548
549#[cfg(test)]
550mod tests {
551 use pretty_assertions::assert_eq;
552 use super::*;
553
554 use ast::*;
555 use token::op::{AssignOp, AssignOpKind, BinOp, BinOpKind, UnaryOp, UnaryOpKind};
556
557 #[test]
558 fn literal_int() {
559 let mut parser = Parser::new("16");
560 let expr = parser.try_parse_full::<Expr>().unwrap();
561
562 assert_eq!(expr, Expr::Literal(Literal::Integer(LitInt {
563 value: "16".to_string(),
564 span: 0..2,
565 })));
566 }
567
568 #[test]
569 fn literal_float() {
570 let mut parser = Parser::new("3.14");
571 let expr = parser.try_parse_full::<Expr>().unwrap();
572
573 assert_eq!(expr, Expr::Literal(Literal::Float(LitFloat {
574 value: "3.14".to_string(),
575 span: 0..4,
576 })));
577 }
578
579 #[test]
580 fn literal_float_2() {
581 let mut parser = Parser::new(".75");
582 let expr = parser.try_parse_full::<Expr>().unwrap();
583
584 assert_eq!(expr, Expr::Literal(Literal::Float(LitFloat {
585 value: ".75".to_string(),
586 span: 0..3,
587 })));
588 }
589
590 #[test]
591 fn wrong_float() {
592 let mut parser = Parser::new("1 .");
593 parser.try_parse_full::<Expr>().unwrap_err();
594 }
595
596 #[test]
597 fn wrong_float_2() {
598 let mut parser = Parser::new("1..");
599 parser.try_parse_full::<Expr>().unwrap_err();
600 }
601
602 #[test]
603 fn literal_radix_base_2() {
604 let mut parser = Parser::new("2'10000110000");
605 let expr = parser.try_parse_full::<Expr>().unwrap();
606
607 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
608 base: 2,
609 value: "10000110000".to_string(),
610 span: 0..13,
611 })));
612 }
613
614 #[test]
615 fn literal_radix_base_8() {
616 let mut parser = Parser::new("8'2060");
617 let expr = parser.try_parse_full::<Expr>().unwrap();
618
619 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
620 base: 8,
621 value: "2060".to_string(),
622 span: 0..6,
623 })));
624 }
625
626 #[test]
627 fn literal_radix_base_25() {
628 let mut parser = Parser::new("25'1hm");
629 let expr = parser.try_parse_full::<Expr>().unwrap();
630
631 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
632 base: 25,
633 value: "1hm".to_string(),
634 span: 0..6,
635 })));
636 }
637
638 #[test]
639 fn literal_radix_base_32() {
640 let mut parser = Parser::new("32'11g");
641 let expr = parser.try_parse_full::<Expr>().unwrap();
642
643 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
644 base: 32,
645 value: "11g".to_string(),
646 span: 0..6,
647 })));
648 }
649
650 #[test]
651 fn literal_radix_base_47() {
652 let mut parser = Parser::new("47'mC");
653 let expr = parser.try_parse_full::<Expr>().unwrap();
654
655 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
656 base: 47,
657 value: "mC".to_string(),
658 span: 0..5,
659 })));
660 }
661
662 #[test]
663 fn literal_radix_with_nonword_tokens() {
664 let mut parser = Parser::new("64'++/+//");
665 let expr = parser.try_parse_full::<Expr>().unwrap();
666
667 assert_eq!(expr, Expr::Literal(Literal::Radix(LitRadix {
668 base: 64,
669 value: "++/+//".to_string(),
670 span: 0..9,
671 })));
672 }
673
674 #[test]
675 fn literal_symbol() {
676 let mut parser = Parser::new("pi");
677 let expr = parser.try_parse_full::<Expr>().unwrap();
678
679 assert_eq!(expr, Expr::Literal(Literal::Symbol(LitSym {
680 name: "pi".to_string(),
681 span: 0..2,
682 })));
683 }
684
685 #[test]
686 fn literal_list() {
687 let mut parser = Parser::new("[1, 2,i, 4, e]");
688 let expr = parser.try_parse_full::<Expr>().unwrap();
689
690 assert_eq!(expr, Expr::Literal(Literal::List(LitList {
691 values: vec![
692 Expr::Literal(Literal::Integer(LitInt {
693 value: "1".to_string(),
694 span: 1..2,
695 })),
696 Expr::Literal(Literal::Integer(LitInt {
697 value: "2".to_string(),
698 span: 4..5,
699 })),
700 Expr::Literal(Literal::Symbol(LitSym {
701 name: "i".to_string(),
702 span: 6..7,
703 })),
704 Expr::Literal(Literal::Integer(LitInt {
705 value: "4".to_string(),
706 span: 9..10,
707 })),
708 Expr::Literal(Literal::Symbol(LitSym {
709 name: "e".to_string(),
710 span: 12..13,
711 })),
712 ],
713 span: 0..14,
714 })));
715 }
716
717 #[test]
718 fn literal_list_repeat() {
719 let mut parser = Parser::new("[1; 5]");
720 let expr = parser.try_parse_full::<Expr>().unwrap();
721
722 assert_eq!(expr, Expr::Literal(Literal::ListRepeat(LitListRepeat {
723 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
724 value: "1".to_string(),
725 span: 1..2,
726 }))),
727 count: Box::new(Expr::Literal(Literal::Integer(LitInt {
728 value: "5".to_string(),
729 span: 4..5,
730 }))),
731 span: 0..6,
732 })));
733 }
734
735 #[test]
736 fn list_indexing() {
737 let mut parser = Parser::new("(list[x + 2] + list[x + 5])[1][2]");
738 let expr = parser.try_parse_full::<Expr>().unwrap();
739
740 assert_eq!(expr, Expr::Index(Index {
741 target: Box::new(Expr::Index(Index {
742 target: Box::new(Expr::Paren(Paren {
743 expr: Box::new(Expr::Binary(Binary {
744 lhs: Box::new(Expr::Index(Index {
745 target: Box::new(Expr::Literal(Literal::Symbol(LitSym {
746 name: "list".to_string(),
747 span: 1..5,
748 }))),
749 index: Box::new(Expr::Binary(Binary {
750 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
751 name: "x".to_string(),
752 span: 6..7,
753 }))),
754 op: BinOp {
755 kind: BinOpKind::Add,
756 implicit: false,
757 span: 8..9,
758 },
759 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
760 value: "2".to_string(),
761 span: 10..11,
762 }))),
763 span: 6..11,
764 })),
765 span: 1..12,
766 bracket_span: 5..12,
767 })),
768 op: BinOp {
769 kind: BinOpKind::Add,
770 implicit: false,
771 span: 13..14,
772 },
773 rhs: Box::new(Expr::Index(Index {
774 target: Box::new(Expr::Literal(Literal::Symbol(LitSym {
775 name: "list".to_string(),
776 span: 15..19,
777 }))),
778 index: Box::new(Expr::Binary(Binary {
779 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
780 name: "x".to_string(),
781 span: 20..21,
782 }))),
783 op: BinOp {
784 kind: BinOpKind::Add,
785 implicit: false,
786 span: 22..23,
787 },
788 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
789 value: "5".to_string(),
790 span: 24..25,
791 }))),
792 span: 20..25,
793 })),
794 span: 15..26,
795 bracket_span: 19..26,
796 })),
797 span: 1..26,
798 })),
799 span: 0..27,
800 })),
801 index: Box::new(Expr::Literal(Literal::Integer(LitInt {
802 value: "1".to_string(),
803 span: 28..29,
804 }))),
805 span: 0..30,
806 bracket_span: 27..30,
807 })),
808 index: Box::new(Expr::Literal(Literal::Integer(LitInt {
809 value: "2".to_string(),
810 span: 31..32,
811 }))),
812 span: 0..33,
813 bracket_span: 30..33,
814 }));
815 }
816
817 #[test]
818 fn not_indexing() {
819 let mut parser = Parser::new("abs(4) [8, 16]");
820 assert!(parser.try_parse_full::<Expr>().is_err());
821 }
822
823 #[test]
824 fn unary_left_associativity() {
825 let mut parser = Parser::new("3!!");
826 let expr = parser.try_parse_full::<Expr>().unwrap();
827
828 assert_eq!(expr, Expr::Unary(Unary {
829 operand: Box::new(Expr::Unary(Unary {
830 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
831 value: "3".to_string(),
832 span: 0..1,
833 }))),
834 op: UnaryOp {
835 kind: UnaryOpKind::Factorial,
836 span: 1..2,
837 },
838 span: 0..2,
839 })),
840 op: UnaryOp {
841 kind: UnaryOpKind::Factorial,
842 span: 2..3,
843 },
844 span: 0..3,
845 }));
846 }
847
848 #[test]
849 fn unary_right_associativity() {
850 let mut parser = Parser::new("not not --3");
851 let expr = parser.try_parse_full::<Expr>().unwrap();
852
853 assert_eq!(expr, Expr::Unary(Unary {
854 operand: Box::new(Expr::Unary(Unary {
855 operand: Box::new(Expr::Unary(Unary {
856 operand: Box::new(Expr::Unary(Unary {
857 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
858 value: "3".to_string(),
859 span: 10..11,
860 }))),
861 op: UnaryOp {
862 kind: UnaryOpKind::Neg,
863 span: 9..10,
864 },
865 span: 9..11,
866 })),
867 op: UnaryOp {
868 kind: UnaryOpKind::Neg,
869 span: 8..9,
870 },
871 span: 8..11,
872 })),
873 op: UnaryOp {
874 kind: UnaryOpKind::Not,
875 span: 4..7,
876 },
877 span: 4..11,
878 })),
879 op: UnaryOp {
880 kind: UnaryOpKind::Not,
881 span: 0..3,
882 },
883 span: 0..11,
884 }));
885 }
886
887 #[test]
888 fn wrong_unary() {
889 let mut parser = Parser::new("!3");
890 assert!(parser.try_parse_full::<Expr>().is_err());
891 }
892
893 #[test]
894 fn unary_complicated() {
895 let mut parser = Parser::new("not 3!! + -4");
896 let expr = parser.try_parse_full::<Expr>().unwrap();
897
898 assert_eq!(expr, Expr::Binary(Binary {
899 lhs: Box::new(Expr::Unary(Unary {
900 operand: Box::new(Expr::Unary(Unary {
901 operand: Box::new(Expr::Unary(Unary {
902 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
903 value: "3".to_string(),
904 span: 4..5,
905 }))),
906 op: UnaryOp {
907 kind: UnaryOpKind::Factorial,
908 span: 5..6,
909 },
910 span: 4..6,
911 })),
912 op: UnaryOp {
913 kind: UnaryOpKind::Factorial,
914 span: 6..7,
915 },
916 span: 4..7,
917 })),
918 op: UnaryOp {
919 kind: UnaryOpKind::Not,
920 span: 0..3,
921 },
922 span: 0..7,
923 })),
924 op: BinOp {
925 kind: BinOpKind::Add,
926 implicit: false,
927 span: 8..9,
928 },
929 rhs: Box::new(Expr::Unary(Unary {
930 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
931 value: "4".to_string(),
932 span: 11..12,
933 }))),
934 op: UnaryOp {
935 kind: UnaryOpKind::Neg,
936 span: 10..11,
937 },
938 span: 10..12,
939 })),
940 span: 0..12,
941 }));
942 }
943
944 #[test]
945 fn binary_left_associativity() {
946 let mut parser = Parser::new("3 * x * 5");
947 let expr = parser.try_parse_full::<Expr>().unwrap();
948
949 assert_eq!(expr, Expr::Binary(Binary {
950 lhs: Box::new(Expr::Binary(Binary {
951 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
952 value: "3".to_string(),
953 span: 0..1,
954 }))),
955 op: BinOp {
956 kind: BinOpKind::Mul,
957 implicit: false,
958 span: 2..3,
959 },
960 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
961 name: "x".to_string(),
962 span: 4..5,
963 }))),
964 span: 0..5,
965 })),
966 op: BinOp {
967 kind: BinOpKind::Mul,
968 implicit: false,
969 span: 6..7,
970 },
971 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
972 value: "5".to_string(),
973 span: 8..9,
974 }))),
975 span: 0..9,
976 }));
977 }
978
979 #[test]
980 fn binary_left_associativity_mix_precedence() {
981 let mut parser = Parser::new("3 + 4 * a + b");
982 let expr = parser.try_parse_full::<Expr>().unwrap();
983
984 assert_eq!(expr, Expr::Binary(Binary {
985 lhs: Box::new(Expr::Binary(Binary {
986 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
987 value: "3".to_string(),
988 span: 0..1,
989 }))),
990 op: BinOp {
991 kind: BinOpKind::Add,
992 implicit: false,
993 span: 2..3,
994 },
995 rhs: Box::new(Expr::Binary(Binary {
996 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
997 value: "4".to_string(),
998 span: 4..5,
999 }))),
1000 op: BinOp {
1001 kind: BinOpKind::Mul,
1002 implicit: false,
1003 span: 6..7,
1004 },
1005 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1006 name: "a".to_string(),
1007 span: 8..9,
1008 }))),
1009 span: 4..9,
1010 })),
1011 span: 0..9,
1012 })),
1013 op: BinOp {
1014 kind: BinOpKind::Add,
1015 implicit: false,
1016 span: 10..11,
1017 },
1018 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1019 name: "b".to_string(),
1020 span: 12..13,
1021 }))),
1022 span: 0..13,
1023 }));
1024 }
1025
1026 #[test]
1027 fn binary_right_associativity() {
1028 let mut parser = Parser::new("1 ^ 2 ^ 3");
1029 let expr = parser.try_parse_full::<Expr>().unwrap();
1030
1031 assert_eq!(expr, Expr::Binary(Binary {
1032 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1033 value: "1".to_string(),
1034 span: 0..1,
1035 }))),
1036 op: BinOp {
1037 kind: BinOpKind::Exp,
1038 implicit: false,
1039 span: 2..3,
1040 },
1041 rhs: Box::new(Expr::Binary(Binary {
1042 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1043 value: "2".to_string(),
1044 span: 4..5,
1045 }))),
1046 op: BinOp {
1047 kind: BinOpKind::Exp,
1048 implicit: false,
1049 span: 6..7,
1050 },
1051 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1052 value: "3".to_string(),
1053 span: 8..9,
1054 }))),
1055 span: 4..9,
1056 })),
1057 span: 0..9,
1058 }));
1059 }
1060
1061 #[test]
1062 fn binary_complicated() {
1063 let mut parser = Parser::new("1 + 2 * 3 - 4 / 5 ^ 6");
1064 let expr = parser.try_parse_full::<Expr>().unwrap();
1065
1066 let mul = Expr::Binary(Binary {
1068 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1069 value: "2".to_string(),
1070 span: 4..5,
1071 }))),
1072 op: BinOp {
1073 kind: BinOpKind::Mul,
1074 implicit: false,
1075 span: 6..7,
1076 },
1077 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1078 value: "3".to_string(),
1079 span: 8..9,
1080 }))),
1081 span: 4..9,
1082 });
1083
1084 let add = Expr::Binary(Binary {
1086 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1087 value: "1".to_string(),
1088 span: 0..1,
1089 }))),
1090 op: BinOp {
1091 kind: BinOpKind::Add,
1092 implicit: false,
1093 span: 2..3,
1094 },
1095 rhs: Box::new(mul),
1096 span: 0..9,
1097 });
1098
1099 let exp = Expr::Binary(Binary {
1101 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1102 value: "5".to_string(),
1103 span: 16..17,
1104 }))),
1105 op: BinOp {
1106 kind: BinOpKind::Exp,
1107 implicit: false,
1108 span: 18..19,
1109 },
1110 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1111 value: "6".to_string(),
1112 span: 20..21,
1113 }))),
1114 span: 16..21,
1115 });
1116
1117 let div = Expr::Binary(Binary {
1119 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1120 value: "4".to_string(),
1121 span: 12..13,
1122 }))),
1123 op: BinOp {
1124 kind: BinOpKind::Div,
1125 implicit: false,
1126 span: 14..15,
1127 },
1128 rhs: Box::new(exp),
1129 span: 12..21,
1130 });
1131
1132 let sub = Expr::Binary(Binary {
1134 lhs: Box::new(add),
1135 op: BinOp {
1136 kind: BinOpKind::Sub,
1137 implicit: false,
1138 span: 10..11,
1139 },
1140 rhs: Box::new(div),
1141 span: 0..21,
1142 });
1143
1144 assert_eq!(expr, sub);
1145 }
1146
1147 #[test]
1148 fn binary_and_unary() {
1149 let mut parser = Parser::new("-1 ^ -2 * 3");
1150 let expr = parser.try_parse_full::<Expr>().unwrap();
1151
1152 assert_eq!(expr, Expr::Binary(Binary {
1153 lhs: Box::new(Expr::Unary(Unary {
1154 operand: Box::new(Expr::Binary(Binary {
1155 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1156 value: "1".to_string(),
1157 span: 1..2,
1158 }))),
1159 op: BinOp {
1160 kind: BinOpKind::Exp,
1161 implicit: false,
1162 span: 3..4,
1163 },
1164 rhs: Box::new(Expr::Unary(Unary {
1165 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1166 value: "2".to_string(),
1167 span: 6..7,
1168 }))),
1169 op: UnaryOp {
1170 kind: UnaryOpKind::Neg,
1171 span: 5..6,
1172 },
1173 span: 5..7,
1174 })),
1175 span: 1..7,
1176 })),
1177 op: UnaryOp {
1178 kind: UnaryOpKind::Neg,
1179 span: 0..1,
1180 },
1181 span: 0..7,
1182 })),
1183 op: BinOp {
1184 kind: BinOpKind::Mul,
1185 implicit: false,
1186 span: 8..9,
1187 },
1188 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1189 value: "3".to_string(),
1190 span: 10..11,
1191 }))),
1192 span: 0..11,
1193 }));
1194 }
1195
1196 #[test]
1197 fn complicated_binary_and_unary() {
1198 let mut parser = Parser::new("pi^2 * 17! / -4.9 + e");
1199 let expr = parser.try_parse_full::<Expr>().unwrap();
1200
1201 assert_eq!(expr, Expr::Binary(Binary {
1202 lhs: Box::new(Expr::Binary(Binary {
1203 lhs: Box::new(Expr::Binary(Binary {
1204 lhs: Box::new(Expr::Binary(Binary {
1205 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1206 name: "pi".to_string(),
1207 span: 0..2,
1208 }))),
1209 op: BinOp {
1210 kind: BinOpKind::Exp,
1211 implicit: false,
1212 span: 2..3,
1213 },
1214 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1215 value: "2".to_string(),
1216 span: 3..4,
1217 }))),
1218 span: 0..4,
1219 })),
1220 op: BinOp {
1221 kind: BinOpKind::Mul,
1222 implicit: false,
1223 span: 5..6,
1224 },
1225 rhs: Box::new(Expr::Unary(Unary {
1226 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1227 value: "17".to_string(),
1228 span: 7..9,
1229 }))),
1230 op: UnaryOp {
1231 kind: UnaryOpKind::Factorial,
1232 span: 9..10,
1233 },
1234 span: 7..10,
1235 })),
1236 span: 0..10,
1237 })),
1238 op: BinOp {
1239 kind: BinOpKind::Div,
1240 implicit: false,
1241 span: 11..12,
1242 },
1243 rhs: Box::new(Expr::Unary(Unary {
1244 operand: Box::new(Expr::Literal(Literal::Float(LitFloat {
1245 value: "4.9".to_string(),
1246 span: 14..17,
1247 }))),
1248 op: UnaryOp {
1249 kind: UnaryOpKind::Neg,
1250 span: 13..14,
1251 },
1252 span: 13..17,
1253 })),
1254 span: 0..17,
1255 })),
1256 op: BinOp {
1257 kind: BinOpKind::Add,
1258 implicit: false,
1259 span: 18..19,
1260 },
1261 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1262 name: "e".to_string(),
1263 span: 20..21,
1264 }))),
1265 span: 0..21,
1266 }));
1267 }
1268
1269 #[test]
1270 fn implicit_multiplication() {
1271 let mut parser = Parser::new("2(3 + 4)");
1272 let expr = parser.try_parse_full::<Expr>().unwrap();
1273
1274 assert_eq!(expr, Expr::Binary(Binary {
1275 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1276 value: "2".to_string(),
1277 span: 0..1,
1278 }))),
1279 op: BinOp {
1280 kind: BinOpKind::Mul,
1281 implicit: true,
1282 span: 1..1,
1283 },
1284 rhs: Box::new(Expr::Paren(Paren {
1285 expr: Box::new(Expr::Binary(Binary {
1286 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1287 value: "3".to_string(),
1288 span: 2..3,
1289 }))),
1290 op: BinOp {
1291 kind: BinOpKind::Add,
1292 implicit: false,
1293 span: 4..5,
1294 },
1295 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1296 value: "4".to_string(),
1297 span: 6..7,
1298 }))),
1299 span: 2..7,
1300 })),
1301 span: 1..8,
1302 })),
1303 span: 0..8,
1304 }));
1305 }
1306
1307 #[test]
1308 fn implicit_multiplication_2() {
1309 let mut parser = Parser::new("1 + 2x");
1310 let expr = parser.try_parse_full::<Expr>().unwrap();
1311
1312 assert_eq!(expr, Expr::Binary(Binary {
1313 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1314 value: "1".to_string(),
1315 span: 0..1,
1316 }))),
1317 op: BinOp {
1318 kind: BinOpKind::Add,
1319 implicit: false,
1320 span: 2..3,
1321 },
1322 rhs: Box::new(Expr::Binary(Binary {
1323 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1324 value: "2".to_string(),
1325 span: 4..5,
1326 }))),
1327 op: BinOp {
1328 kind: BinOpKind::Mul,
1329 implicit: true,
1330 span: 5..5,
1331 },
1332 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1333 name: "x".to_string(),
1334 span: 5..6,
1335 }))),
1336 span: 4..6,
1337 })),
1338 span: 0..6,
1339 }));
1340 }
1341
1342 #[test]
1343 fn implicit_multiplication_3() {
1344 let mut parser = Parser::new("(1 - x)(1 + x)");
1345 let expr = parser.try_parse_full::<Expr>().unwrap();
1346
1347 assert_eq!(expr, Expr::Binary(Binary {
1348 lhs: Box::new(Expr::Paren(Paren {
1349 expr: Box::new(Expr::Binary(Binary {
1350 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1351 value: "1".to_string(),
1352 span: 1..2,
1353 }))),
1354 op: BinOp {
1355 kind: BinOpKind::Sub,
1356 implicit: false,
1357 span: 3..4,
1358 },
1359 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1360 name: "x".to_string(),
1361 span: 5..6,
1362 }))),
1363 span: 1..6,
1364 })),
1365 span: 0..7,
1366 })),
1367 op: BinOp {
1368 kind: BinOpKind::Mul,
1369 implicit: true,
1370 span: 7..7,
1371 },
1372 rhs: Box::new(Expr::Paren(Paren {
1373 expr: Box::new(Expr::Binary(Binary {
1374 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1375 value: "1".to_string(),
1376 span: 8..9,
1377 }))),
1378 op: BinOp {
1379 kind: BinOpKind::Add,
1380 implicit: false,
1381 span: 10..11,
1382 },
1383 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1384 name: "x".to_string(),
1385 span: 12..13,
1386 }))),
1387 span: 8..13,
1388 })),
1389 span: 7..14,
1390 })),
1391 span: 0..14,
1392 }));
1393 }
1394
1395 #[test]
1396 fn implicit_multiplication_4() {
1397 let mut parser = Parser::new("im(2sqrt(-1))");
1398 let expr = parser.try_parse_full::<Expr>().unwrap();
1399
1400 assert_eq!(expr, Expr::Call(Call {
1401 name: LitSym {
1402 name: "im".to_string(),
1403 span: 0..2,
1404 },
1405 derivatives: 0,
1406 args: vec![Expr::Binary(Binary {
1407 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1408 value: "2".to_string(),
1409 span: 3..4,
1410 }))),
1411 op: BinOp {
1412 kind: BinOpKind::Mul,
1413 implicit: true,
1414 span: 4..4,
1415 },
1416 rhs: Box::new(Expr::Call(Call {
1417 name: LitSym {
1418 name: "sqrt".to_string(),
1419 span: 4..8,
1420 },
1421 derivatives: 0,
1422 args: vec![Expr::Unary(Unary {
1423 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1424 value: "1".to_string(),
1425 span: 10..11,
1426 }))),
1427 op: UnaryOp {
1428 kind: UnaryOpKind::Neg,
1429 span: 9..10,
1430 },
1431 span: 9..11,
1432 })],
1433 span: 4..12,
1434 paren_span: 8..12,
1435 })),
1436 span: 3..12,
1437 })],
1438 span: 0..13,
1439 paren_span: 2..13,
1440 }));
1441 }
1442
1443 #[test]
1444 fn implicit_multiplication_extra() {
1445 let mut parser = Parser::new("4x^2 + 5x + 1");
1446 let expr = parser.try_parse_full::<Expr>().unwrap();
1447
1448 assert_eq!(expr, Expr::Binary(Binary {
1449 lhs: Box::new(Expr::Binary(Binary {
1450 lhs: Box::new(Expr::Binary(Binary {
1451 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1452 value: "4".to_string(),
1453 span: 0..1,
1454 }))),
1455 op: BinOp {
1456 kind: BinOpKind::Mul,
1457 implicit: true,
1458 span: 1..1,
1459 },
1460 rhs: Box::new(Expr::Binary(Binary {
1461 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1462 name: "x".to_string(),
1463 span: 1..2,
1464 }))),
1465 op: BinOp {
1466 kind: BinOpKind::Exp,
1467 implicit: false,
1468 span: 2..3,
1469 },
1470 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1471 value: "2".to_string(),
1472 span: 3..4,
1473 }))),
1474 span: 1..4,
1475 })),
1476 span: 0..4,
1477 })),
1478 op: BinOp {
1479 kind: BinOpKind::Add,
1480 implicit: false,
1481 span: 5..6,
1482 },
1483 rhs: Box::new(Expr::Binary(Binary {
1484 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1485 value: "5".to_string(),
1486 span: 7..8,
1487 }))),
1488 op: BinOp {
1489 kind: BinOpKind::Mul,
1490 implicit: true,
1491 span: 8..8,
1492 },
1493 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1494 name: "x".to_string(),
1495 span: 8..9,
1496 }))),
1497 span: 7..9,
1498 })),
1499 span: 0..9,
1500 })),
1501 op: BinOp {
1502 kind: BinOpKind::Add,
1503 implicit: false,
1504 span: 10..11,
1505 },
1506 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1507 value: "1".to_string(),
1508 span: 12..13,
1509 }))),
1510 span: 0..13,
1511 }));
1512 }
1513
1514 #[test]
1515 fn implicit_multiplication_extra_2() {
1516 let mut parser = Parser::new("3^42.9i");
1517 let expr = parser.try_parse_full::<Expr>().unwrap();
1518
1519 assert_eq!(expr, Expr::Binary(Binary {
1520 lhs: Box::new(Expr::Binary(Binary {
1521 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1522 value: "3".to_string(),
1523 span: 0..1,
1524 }))),
1525 op: BinOp {
1526 kind: BinOpKind::Exp,
1527 implicit: false,
1528 span: 1..2,
1529 },
1530 rhs: Box::new(Expr::Literal(Literal::Float(LitFloat {
1531 value: "42.9".to_string(),
1532 span: 2..6,
1533 }))),
1534 span: 0..6,
1535 })),
1536 op: BinOp {
1537 kind: BinOpKind::Mul,
1538 implicit: true,
1539 span: 6..6,
1540 },
1541 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1542 name: "i".to_string(),
1543 span: 6..7,
1544 }))),
1545 span: 0..7,
1546 }));
1547 }
1548
1549 #[test]
1550 fn implicit_multiplication_nonsensical() {
1551 let mut parser = Parser::new("2!! 3!!");
1552 let expr = parser.try_parse_full::<Expr>().unwrap();
1553
1554 assert_eq!(expr, Expr::Binary(Binary {
1555 lhs: Box::new(Expr::Unary(Unary {
1556 operand: Box::new(Expr::Unary(Unary {
1557 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1558 value: "2".to_string(),
1559 span: 0..1,
1560 }))),
1561 op: UnaryOp {
1562 kind: UnaryOpKind::Factorial,
1563 span: 1..2,
1564 },
1565 span: 0..2,
1566 })),
1567 op: UnaryOp {
1568 kind: UnaryOpKind::Factorial,
1569 span: 2..3,
1570 },
1571 span: 0..3,
1572 })),
1573 op: BinOp {
1574 kind: BinOpKind::Mul,
1575 implicit: true,
1576 span: 3..4,
1577 },
1578 rhs: Box::new(Expr::Unary(Unary {
1579 operand: Box::new(Expr::Unary(Unary {
1580 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1581 value: "3".to_string(),
1582 span: 4..5,
1583 }))),
1584 op: UnaryOp {
1585 kind: UnaryOpKind::Factorial,
1586 span: 5..6,
1587 },
1588 span: 4..6,
1589 })),
1590 op: UnaryOp {
1591 kind: UnaryOpKind::Factorial,
1592 span: 6..7,
1593 },
1594 span: 4..7,
1595 })),
1596 span: 0..7,
1597 }));
1598 }
1599
1600 #[test]
1601 fn implicit_multiplication_ambiguous() {
1602 let mut parser = Parser::new("1 / 2a");
1603 let expr = parser.try_parse_full::<Expr>().unwrap();
1604
1605 assert_eq!(expr, Expr::Binary(Binary {
1606 lhs: Box::new(Expr::Binary(Binary {
1607 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1608 value: "1".to_string(),
1609 span: 0..1,
1610 }))),
1611 op: BinOp {
1612 kind: BinOpKind::Div,
1613 implicit: false,
1614 span: 2..3,
1615 },
1616 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1617 value: "2".to_string(),
1618 span: 4..5,
1619 }))),
1620 span: 0..5,
1621 })),
1622 op: BinOp {
1623 kind: BinOpKind::Mul,
1624 implicit: true,
1625 span: 5..5,
1626 },
1627 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1628 name: "a".to_string(),
1629 span: 5..6,
1630 }))),
1631 span: 0..6,
1632 }));
1633 }
1634
1635 #[test]
1636 fn implicit_multiplication_terms_with_power() {
1637 let mut parser = Parser::new("-16x y + 2x^2y");
1638 let expr = parser.try_parse_full::<Expr>().unwrap();
1639
1640 let lhs = Expr::Binary(Binary {
1642 lhs: Box::new(Expr::Binary(Binary {
1643 lhs: Box::new(Expr::Unary(Unary {
1644 operand: Box::new(Expr::Literal(Literal::Integer(LitInt {
1645 value: "16".to_string(),
1646 span: 1..3,
1647 }))),
1648 op: UnaryOp {
1649 kind: UnaryOpKind::Neg,
1650 span: 0..1,
1651 },
1652 span: 0..3,
1653 })),
1654 op: BinOp {
1655 kind: BinOpKind::Mul,
1656 implicit: true,
1657 span: 3..3,
1658 },
1659 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1660 name: "x".to_string(),
1661 span: 3..4,
1662 }))),
1663 span: 0..4,
1664 })),
1665 op: BinOp {
1666 kind: BinOpKind::Mul,
1667 implicit: true,
1668 span: 4..5,
1669 },
1670 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1671 name: "y".to_string(),
1672 span: 5..6,
1673 }))),
1674 span: 0..6,
1675 });
1676
1677 let rhs = Expr::Binary(Binary {
1679 lhs: Box::new(Expr::Binary(Binary {
1680 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1681 value: "2".to_string(),
1682 span: 9..10,
1683 }))),
1684 op: BinOp {
1685 kind: BinOpKind::Mul,
1686 implicit: true,
1687 span: 10..10,
1688 },
1689 rhs: Box::new(Expr::Binary(Binary {
1690 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1691 name: "x".to_string(),
1692 span: 10..11,
1693 }))),
1694 op: BinOp {
1695 kind: BinOpKind::Exp,
1696 implicit: false,
1697 span: 11..12,
1698 },
1699 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1700 value: "2".to_string(),
1701 span: 12..13,
1702 }))),
1703 span: 10..13,
1704 })),
1705 span: 9..13,
1706 })),
1707 op: BinOp {
1708 kind: BinOpKind::Mul,
1709 implicit: true,
1710 span: 13..13,
1711 },
1712 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1713 name: "y".to_string(),
1714 span: 13..14,
1715 }))),
1716 span: 9..14,
1717 });
1718
1719 let add = Expr::Binary(Binary {
1721 lhs: Box::new(lhs),
1722 op: BinOp {
1723 kind: BinOpKind::Add,
1724 implicit: false,
1725 span: 7..8,
1726 },
1727 rhs: Box::new(rhs),
1728 span: 0..14,
1729 });
1730
1731 assert_eq!(expr, add);
1732 }
1733
1734 #[test]
1735 fn parenthesized() {
1736 let mut parser = Parser::new("(1 + 2) * __");
1737 let expr = parser.try_parse_full::<Expr>().unwrap();
1738
1739 assert_eq!(expr, Expr::Binary(Binary {
1740 lhs: Box::new(Expr::Paren(Paren {
1741 expr: Box::new(Expr::Binary(Binary {
1742 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1743 value: "1".to_string(),
1744 span: 1..2,
1745 }))),
1746 op: BinOp {
1747 kind: BinOpKind::Add,
1748 implicit: false,
1749 span: 3..4,
1750 },
1751 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1752 value: "2".to_string(),
1753 span: 5..6,
1754 }))),
1755 span: 1..6,
1756 })),
1757 span: 0..7,
1758 })),
1759 op: BinOp {
1760 kind: BinOpKind::Mul,
1761 implicit: false,
1762 span: 8..9,
1763 },
1764 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1765 name: "__".to_string(),
1766 span: 10..12,
1767 }))),
1768 span: 0..12,
1769 }));
1770 }
1771
1772 #[test]
1773 fn parenthesized_complicated() {
1774 let mut parser = Parser::new("(3 * 9 + 4.0 / 11.9 % (6 - 3))");
1775 let expr = parser.try_parse_full::<Expr>().unwrap();
1776
1777 assert_eq!(expr, Expr::Paren(Paren {
1778 expr: Box::new(Expr::Binary(Binary {
1779 lhs: Box::new(Expr::Binary(Binary {
1780 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1781 value: "3".to_string(),
1782 span: 1..2,
1783 }))),
1784 op: BinOp {
1785 kind: BinOpKind::Mul,
1786 implicit: false,
1787 span: 3..4,
1788 },
1789 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1790 value: "9".to_string(),
1791 span: 5..6,
1792 }))),
1793 span: 1..6,
1794 })),
1795 op: BinOp {
1796 kind: BinOpKind::Add,
1797 implicit: false,
1798 span: 7..8,
1799 },
1800 rhs: Box::new(Expr::Binary(Binary {
1801 lhs: Box::new(Expr::Binary(Binary {
1802 lhs: Box::new(Expr::Literal(Literal::Float(LitFloat {
1803 value: "4.0".to_string(),
1804 span: 9..12,
1805 }))),
1806 op: BinOp {
1807 kind: BinOpKind::Div,
1808 implicit: false,
1809 span: 13..14,
1810 },
1811 rhs: Box::new(Expr::Literal(Literal::Float(LitFloat {
1812 value: "11.9".to_string(),
1813 span: 15..19,
1814 }))),
1815 span: 9..19,
1816 })),
1817 op: BinOp {
1818 kind: BinOpKind::Mod,
1819 implicit: false,
1820 span: 20..21,
1821 },
1822 rhs: Box::new(Expr::Paren(Paren {
1823 expr: Box::new(Expr::Binary(Binary {
1824 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1825 value: "6".to_string(),
1826 span: 23..24,
1827 }))),
1828 op: BinOp {
1829 kind: BinOpKind::Sub,
1830 implicit: false,
1831 span: 25..26,
1832 },
1833 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
1834 value: "3".to_string(),
1835 span: 27..28,
1836 }))),
1837 span: 23..28,
1838 })),
1839 span: 22..29,
1840 })),
1841 span: 9..29,
1842 })),
1843 span: 1..29,
1844 })),
1845 span: 0..30,
1846 }));
1847 }
1848
1849 #[test]
1850 fn block_code() {
1851 let mut parser = Parser::new("{ x = 5; y = 6; x + y }");
1852 let expr = parser.try_parse_full::<Expr>().unwrap();
1853
1854 assert_eq!(expr, Expr::Block(Block {
1855 stmts: vec![
1856 Stmt {
1857 expr: Expr::Assign(Assign {
1858 target: AssignTarget::Symbol(LitSym {
1859 name: "x".to_string(),
1860 span: 2..3,
1861 }),
1862 op: AssignOp {
1863 kind: AssignOpKind::Assign,
1864 span: 4..5,
1865 },
1866 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1867 value: "5".to_string(),
1868 span: 6..7,
1869 }))),
1870 span: 2..7,
1871 }),
1872 semicolon: Some(7..8),
1873 span: 2..8,
1874 },
1875 Stmt {
1876 expr: Expr::Assign(Assign {
1877 target: AssignTarget::Symbol(LitSym {
1878 name: "y".to_string(),
1879 span: 9..10,
1880 }),
1881 op: AssignOp {
1882 kind: AssignOpKind::Assign,
1883 span: 11..12,
1884 },
1885 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1886 value: "6".to_string(),
1887 span: 13..14,
1888 }))),
1889 span: 9..14,
1890 }),
1891 semicolon: Some(14..15),
1892 span: 9..15,
1893 },
1894 Stmt {
1895 expr: Expr::Binary(Binary {
1896 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1897 name: "x".to_string(),
1898 span: 16..17,
1899 }))),
1900 op: BinOp {
1901 kind: BinOpKind::Add,
1902 implicit: false,
1903 span: 18..19,
1904 },
1905 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1906 name: "y".to_string(),
1907 span: 20..21,
1908 }))),
1909 span: 16..21,
1910 }),
1911 semicolon: None,
1912 span: 16..21,
1913 },
1914 ],
1915 span: 0..23,
1916 }));
1917 }
1918
1919 #[test]
1920 fn if_block() {
1921 let mut parser = Parser::new("if d { abs''(d) } else { f = 1; f }");
1922 let expr = parser.try_parse_full::<Expr>().unwrap();
1923
1924 assert_eq!(expr, Expr::If(If {
1925 condition: Box::new(Expr::Literal(Literal::Symbol(LitSym {
1926 name: "d".to_string(),
1927 span: 3..4,
1928 }))),
1929 then_expr: Box::new(Expr::Block(Block {
1930 stmts: vec![
1931 Stmt {
1932 expr: Expr::Call(Call {
1933 name: LitSym {
1934 name: "abs".to_string(),
1935 span: 7..10,
1936 },
1937 derivatives: 2,
1938 args: vec![
1939 Expr::Literal(Literal::Symbol(LitSym {
1940 name: "d".to_string(),
1941 span: 13..14,
1942 })),
1943 ],
1944 span: 7..15,
1945 paren_span: 12..15,
1946 }),
1947 semicolon: None,
1948 span: 7..15,
1949 },
1950 ],
1951 span: 5..17,
1952 })),
1953 else_expr: Some(Box::new(Expr::Block(Block {
1954 stmts: vec![
1955 Stmt {
1956 expr: Expr::Assign(Assign {
1957 target: AssignTarget::Symbol(LitSym {
1958 name: "f".to_string(),
1959 span: 25..26,
1960 }),
1961 op: AssignOp {
1962 kind: AssignOpKind::Assign,
1963 span: 27..28,
1964 },
1965 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
1966 value: "1".to_string(),
1967 span: 29..30,
1968 }))),
1969 span: 25..30,
1970 }),
1971 semicolon: Some(30..31),
1972 span: 25..31,
1973 },
1974 Stmt {
1975 expr: Expr::Literal(Literal::Symbol(LitSym {
1976 name: "f".to_string(),
1977 span: 32..33,
1978 })),
1979 semicolon: None,
1980 span: 32..33,
1981 },
1982 ],
1983 span: 23..35,
1984 }))),
1985 span: 0..35,
1986 if_span: 0..2,
1987 else_span: Some(18..22),
1988 }));
1989 }
1990
1991 #[test]
1992 fn assign_to_var() {
1993 let mut parser = Parser::new("fx += 1 / pi");
1994 let expr = parser.try_parse_full::<Expr>().unwrap();
1995
1996 assert_eq!(expr, Expr::Assign(Assign {
1997 target: AssignTarget::Symbol(LitSym {
1998 name: "fx".to_string(),
1999 span: 0..2,
2000 }),
2001 op: AssignOp {
2002 kind: AssignOpKind::Add,
2003 span: 3..5,
2004 },
2005 value: Box::new(Expr::Binary(Binary {
2006 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2007 value: "1".to_string(),
2008 span: 6..7,
2009 }))),
2010 op: BinOp {
2011 kind: BinOpKind::Div,
2012 implicit: false,
2013 span: 8..9,
2014 },
2015 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2016 name: "pi".to_string(),
2017 span: 10..12,
2018 }))),
2019 span: 6..12,
2020 })),
2021 span: 0..12,
2022 }));
2023 }
2024
2025 #[test]
2026 fn assign_to_function() {
2027 let mut parser = Parser::new("f(x) = x^2 + 5x");
2028 let expr = parser.try_parse_full::<Expr>().unwrap();
2029
2030 assert_eq!(expr, Expr::Assign(Assign {
2031 target: AssignTarget::Func(FuncHeader {
2032 name: LitSym {
2033 name: "f".to_string(),
2034 span: 0..1,
2035 },
2036 params: vec![
2037 Param::Symbol(LitSym {
2038 name: "x".to_string(),
2039 span: 2..3,
2040 }),
2041 ],
2042 span: 0..4,
2043 }),
2044 op: AssignOp {
2045 kind: AssignOpKind::Assign,
2046 span: 5..6,
2047 },
2048 value: Box::new(Expr::Binary(Binary {
2049 lhs: Box::new(Expr::Binary(Binary {
2050 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2051 name: "x".to_string(),
2052 span: 7..8,
2053 }))),
2054 op: BinOp {
2055 kind: BinOpKind::Exp,
2056 implicit: false,
2057 span: 8..9,
2058 },
2059 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2060 value: "2".to_string(),
2061 span: 9..10,
2062 }))),
2063 span: 7..10,
2064 })),
2065 op: BinOp {
2066 kind: BinOpKind::Add,
2067 implicit: false,
2068 span: 11..12,
2069 },
2070 rhs: Box::new(Expr::Binary(Binary {
2071 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2072 value: "5".to_string(),
2073 span: 13..14,
2074 }))),
2075 op: BinOp {
2076 kind: BinOpKind::Mul,
2077 implicit: true,
2078 span: 14..14,
2079 },
2080 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2081 name: "x".to_string(),
2082 span: 14..15,
2083 }))),
2084 span: 13..15,
2085 })),
2086 span: 7..15,
2087 })),
2088 span: 0..15,
2089 }));
2090 }
2091
2092 #[test]
2093 fn bad_assign_to_function() {
2094 let mut parser = Parser::new("g(x) += 2");
2096 let expr = parser.try_parse_full::<Expr>();
2097 assert!(expr.is_err());
2098 }
2099
2100 #[test]
2101 fn bad_assign_to_function_default_params() {
2102 let mut parser = Parser::new("g(x = 1, y) += 2");
2104 let expr = parser.try_parse_full::<Expr>();
2105 assert!(expr.is_err());
2106 }
2107
2108 #[test]
2109 fn assign_to_complicated_function() {
2110 let mut parser = Parser::new("discrim(a = 1, b = 5, c = 6) = return b^2 - 4a * c");
2111 let expr = parser.try_parse_full::<Expr>().unwrap();
2112
2113 assert_eq!(expr, Expr::Assign(Assign {
2114 target: AssignTarget::Func(FuncHeader {
2115 name: LitSym {
2116 name: "discrim".to_string(),
2117 span: 0..7,
2118 },
2119 params: vec![
2120 Param::Default(
2121 LitSym {
2122 name: "a".to_string(),
2123 span: 8..9,
2124 },
2125 Expr::Literal(Literal::Integer(LitInt {
2126 value: "1".to_string(),
2127 span: 12..13,
2128 })),
2129 ),
2130 Param::Default(
2131 LitSym {
2132 name: "b".to_string(),
2133 span: 15..16,
2134 },
2135 Expr::Literal(Literal::Integer(LitInt {
2136 value: "5".to_string(),
2137 span: 19..20,
2138 })),
2139 ),
2140 Param::Default(
2141 LitSym {
2142 name: "c".to_string(),
2143 span: 22..23,
2144 },
2145 Expr::Literal(Literal::Integer(LitInt {
2146 value: "6".to_string(),
2147 span: 26..27,
2148 })),
2149 ),
2150 ],
2151 span: 0..28,
2152 }),
2153 op: AssignOp {
2154 kind: AssignOpKind::Assign,
2155 span: 29..30,
2156 },
2157 value: Box::new(Expr::Return(Return {
2158 value: Some(Box::new(Expr::Binary(Binary {
2159 lhs: Box::new(Expr::Binary(Binary {
2160 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2161 name: "b".to_string(),
2162 span: 38..39,
2163 }))),
2164 op: BinOp {
2165 kind: BinOpKind::Exp,
2166 implicit: false,
2167 span: 39..40,
2168 },
2169 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2170 value: "2".to_string(),
2171 span: 40..41,
2172 }))),
2173 span: 38..41,
2174 })),
2175 op: BinOp {
2176 kind: BinOpKind::Sub,
2177 implicit: false,
2178 span: 42..43,
2179 },
2180 rhs: Box::new(Expr::Binary(Binary {
2181 lhs: Box::new(Expr::Binary(Binary {
2182 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2183 value: "4".to_string(),
2184 span: 44..45,
2185 }))),
2186 op: BinOp {
2187 kind: BinOpKind::Mul,
2188 implicit: true,
2189 span: 45..45,
2190 },
2191 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2192 name: "a".to_string(),
2193 span: 45..46,
2194 }))),
2195 span: 44..46,
2196 })),
2197 op: BinOp {
2198 kind: BinOpKind::Mul,
2199 implicit: false,
2200 span: 47..48,
2201 },
2202 rhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2203 name: "c".to_string(),
2204 span: 49..50,
2205 }))),
2206 span: 44..50,
2207 })),
2208 span: 38..50,
2209 }))),
2210 span: 31..50,
2211 return_span: 31..37,
2212 })),
2213 span: 0..50,
2214 }));
2215 }
2216
2217 #[test]
2218 fn assign_function_to_list() {
2219 let mut parser = Parser::new("arr[0] = f() = pi");
2220 let expr = parser.try_parse_full::<Expr>().unwrap();
2221
2222 assert_eq!(expr, Expr::Assign(Assign {
2223 target: AssignTarget::Index(Index {
2224 target: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2225 name: "arr".to_string(),
2226 span: 0..3,
2227 }))),
2228 index: Box::new(Expr::Literal(Literal::Integer(LitInt {
2229 value: "0".to_string(),
2230 span: 4..5,
2231 }))),
2232 span: 0..6,
2233 bracket_span: 3..6,
2234 }),
2235 op: AssignOp {
2236 kind: AssignOpKind::Assign,
2237 span: 7..8,
2238 },
2239 value: Box::new(Expr::Assign(Assign {
2240 target: AssignTarget::Func(FuncHeader {
2241 name: LitSym {
2242 name: "f".to_string(),
2243 span: 9..10,
2244 },
2245 params: vec![],
2246 span: 9..12,
2247 }),
2248 op: AssignOp {
2249 kind: AssignOpKind::Assign,
2250 span: 13..14,
2251 },
2252 value: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2253 name: "pi".to_string(),
2254 span: 15..17,
2255 }))),
2256 span: 9..17,
2257 })),
2258 span: 0..17,
2259 }));
2260 }
2261
2262 #[test]
2263 fn range_no_float() {
2264 let mut parser = Parser::new("1..2");
2265 let expr = parser.try_parse_full::<Expr>().unwrap();
2266
2267 assert_eq!(expr, Expr::Range(ast::Range {
2268 start: Box::new(Expr::Literal(Literal::Integer(LitInt {
2269 value: "1".to_string(),
2270 span: 0..1,
2271 }))),
2272 end: Box::new(Expr::Literal(Literal::Integer(LitInt {
2273 value: "2".to_string(),
2274 span: 3..4,
2275 }))),
2276 kind: RangeKind::HalfOpen,
2277 span: 0..4,
2278 }));
2279 }
2280
2281 #[test]
2282 fn range_precedence() {
2283 let mut parser = Parser::new("3 * 4 + 1 ..= 26 + 2");
2284 let expr = parser.try_parse_full::<Expr>().unwrap();
2285
2286 assert_eq!(expr, Expr::Range(ast::Range {
2287 start: Box::new(Expr::Binary(Binary {
2288 lhs: Box::new(Expr::Binary(Binary {
2289 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2290 value: "3".to_string(),
2291 span: 0..1,
2292 }))),
2293 op: BinOp {
2294 kind: BinOpKind::Mul,
2295 implicit: false,
2296 span: 2..3,
2297 },
2298 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2299 value: "4".to_string(),
2300 span: 4..5,
2301 }))),
2302 span: 0..5,
2303 })),
2304 op: BinOp {
2305 kind: BinOpKind::Add,
2306 implicit: false,
2307 span: 6..7,
2308 },
2309 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2310 value: "1".to_string(),
2311 span: 8..9,
2312 }))),
2313 span: 0..9,
2314 })),
2315 end: Box::new(Expr::Binary(Binary {
2316 lhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2317 value: "26".to_string(),
2318 span: 14..16,
2319 }))),
2320 op: BinOp {
2321 kind: BinOpKind::Add,
2322 implicit: false,
2323 span: 17..18,
2324 },
2325 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2326 value: "2".to_string(),
2327 span: 19..20,
2328 }))),
2329 span: 14..20,
2330 })),
2331 kind: RangeKind::Closed,
2332 span: 0..20,
2333 }));
2334 }
2335
2336 #[test]
2337 fn function_call() {
2338 let mut parser = Parser::new("f(x)");
2339 let expr = parser.try_parse_full::<Expr>().unwrap();
2340
2341 assert_eq!(expr, Expr::Call(Call {
2342 name: LitSym {
2343 name: "f".to_string(),
2344 span: 0..1,
2345 },
2346 derivatives: 0,
2347 args: vec![
2348 Expr::Literal(Literal::Symbol(LitSym {
2349 name: "x".to_string(),
2350 span: 2..3,
2351 })),
2352 ],
2353 span: 0..4,
2354 paren_span: 1..4,
2355 }));
2356 }
2357
2358 #[test]
2359 fn function_call_whitespace() {
2360 let mut parser = Parser::new("ncr ' ' ' '' ' ( 8 , 5 )");
2361 let expr = parser.try_parse_full::<Expr>().unwrap();
2362
2363 assert_eq!(expr, Expr::Call(Call {
2364 name: LitSym {
2365 name: "ncr".to_string(),
2366 span: 0..3,
2367 },
2368 derivatives: 6,
2369 args: vec![
2370 Expr::Literal(Literal::Integer(LitInt {
2371 value: "8".to_string(),
2372 span: 18..19,
2373 })),
2374 Expr::Literal(Literal::Integer(LitInt {
2375 value: "5".to_string(),
2376 span: 22..23,
2377 })),
2378 ],
2379 span: 0..25,
2380 paren_span: 16..25,
2381 }));
2382 }
2383
2384 #[test]
2385 fn blank_function_header() {
2386 let mut parser = Parser::new("f() = 5");
2387 let expr = parser.try_parse_full::<Expr>().unwrap();
2388
2389 assert_eq!(expr, Expr::Assign(Assign {
2390 target: AssignTarget::Func(FuncHeader {
2391 name: LitSym {
2392 name: "f".to_string(),
2393 span: 0..1,
2394 },
2395 params: vec![],
2396 span: 0..3,
2397 }),
2398 op: AssignOp {
2399 kind: AssignOpKind::Assign,
2400 span: 4..5,
2401 },
2402 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
2403 value: "5".to_string(),
2404 span: 6..7,
2405 }))),
2406 span: 0..7,
2407 }));
2408 }
2409
2410 #[test]
2411 fn catastrophic_backtracking() {
2412 let source = format!("{})", "a(".repeat(6000));
2415 let mut parser = Parser::new(&source);
2416 assert!(parser.try_parse_full::<Expr>().is_err());
2417 }
2418
2419 #[test]
2420 fn oneline_while_loop() {
2421 let mut parser = Parser::new("while x < 5 then x += 1");
2422 let expr = parser.try_parse_full::<Expr>().unwrap();
2423
2424 assert_eq!(expr, Expr::While(While {
2425 condition: Box::new(Expr::Binary(Binary {
2426 lhs: Box::new(Expr::Literal(Literal::Symbol(LitSym {
2427 name: "x".to_string(),
2428 span: 6..7,
2429 }))),
2430 op: BinOp {
2431 kind: BinOpKind::Less,
2432 implicit: false,
2433 span: 8..9,
2434 },
2435 rhs: Box::new(Expr::Literal(Literal::Integer(LitInt {
2436 value: "5".to_string(),
2437 span: 10..11,
2438 }))),
2439 span: 6..11,
2440 })),
2441 body: Box::new(Expr::Then(Then {
2442 expr: Box::new(Expr::Assign(Assign {
2443 target: AssignTarget::Symbol(LitSym {
2444 name: "x".to_string(),
2445 span: 17..18,
2446 }),
2447 op: AssignOp {
2448 kind: AssignOpKind::Add,
2449 span: 19..21,
2450 },
2451 value: Box::new(Expr::Literal(Literal::Integer(LitInt {
2452 value: "1".to_string(),
2453 span: 22..23,
2454 }))),
2455 span: 17..23,
2456 })),
2457 span: 12..23,
2458 then_span: 12..16,
2459 })),
2460 span: 0..23,
2461 while_span: 0..5,
2462 }));
2463 }
2464
2465 #[test]
2466 fn index_into_function() {
2467 let mut parser = Parser::new("abs()[0]");
2468 let expr = parser.try_parse_full::<Expr>().unwrap();
2469
2470 assert_eq!(expr, Expr::Index(Index {
2471 target: Box::new(Expr::Call(Call {
2472 name: LitSym {
2473 name: "abs".to_string(),
2474 span: 0..3,
2475 },
2476 derivatives: 0,
2477 args: vec![],
2478 span: 0..5,
2479 paren_span: 3..5,
2480 })),
2481 index: Box::new(Expr::Literal(Literal::Integer(LitInt {
2482 value: "0".to_string(),
2483 span: 6..7,
2484 }))),
2485 span: 0..8,
2486 bracket_span: 5..8,
2487 }));
2488 }
2489
2490 #[test]
2491 fn source_code() {
2492 let mut parser = Parser::new("x = 5;
2493iseven(n) = n % 2 == 0;
2494if iseven(x) {
2495 x^2 + 5x + 6
2496} else if (bool(x) && false) {
2497 exp(x)
2498} else {
2499 log(x, 2)
2500}");
2501 assert!(parser.try_parse_full_many::<Stmt>().is_ok());
2502 }
2503}