1use crate::compat::{Rc, String, Vec, format, ToString};
18use crate::interpreter::Interpreter;
19use crate::tokenizer::{Token, TokenKind, tokenize};
20use crate::value::{RuntimeError, Value};
21use num_bigint::BigInt;
22#[cfg(feature = "complex_numbers")]
23use num_complex::Complex64;
24use num_rational::BigRational;
25
26#[derive(Debug)]
31pub enum ParseError {
32 UnexpectedToken(String), UnexpectedEndOfInput, MismatchedBrackets, InvalidPipeNotation, InvalidNumber(String), }
38
39impl crate::compat::fmt::Display for ParseError {
42 fn fmt(&self, f: &mut crate::compat::fmt::Formatter<'_>) -> crate::compat::fmt::Result {
43 match self {
44 ParseError::UnexpectedToken(msg) => write!(f, "{}", msg),
45 ParseError::UnexpectedEndOfInput => write!(f, "Unexpected end of input"),
46 ParseError::MismatchedBrackets => write!(f, "Mismatched brackets"),
47 ParseError::InvalidPipeNotation => write!(f, "Invalid pipe notation"),
48 ParseError::InvalidNumber(msg) => write!(f, "{}", msg),
49 }
50 }
51}
52
53impl From<ParseError> for RuntimeError {
57 fn from(err: ParseError) -> Self {
58 RuntimeError::TypeError(format!("Parse error: {:?}", err))
59 }
60}
61
62pub fn parse(input: &str, interp: &mut Interpreter) -> Result<Vec<Value>, ParseError> {
66 let tokens = tokenize(input)
70 .map_err(|e| ParseError::UnexpectedToken(format!("Tokenize error: {}", e)))?;
71
72 let mut index = 0;
76
77 let mut results = Vec::new();
81
82 while index < tokens.len() {
86 let value = parse_value(&tokens, &mut index, interp)?;
90 results.push(value);
91 }
92
93 Ok(results)
97}
98
99fn parse_value(
105 tokens: &[Token],
106 index: &mut usize,
107 interp: &mut Interpreter,
108) -> Result<Value, ParseError> {
109 match tokens.get(*index) {
113 Some(token) if matches!(token.kind, TokenKind::Number(_)) => {
117 if let TokenKind::Number(n) = token.kind {
118 *index += 1; Ok(Value::Number(n))
120 } else {
121 unreachable!()
122 }
123 }
124
125 Some(token) if matches!(token.kind, TokenKind::Integer(_)) => {
126 if let TokenKind::Integer(s) = &token.kind {
127 *index += 1;
128 if let Ok(i32_val) = s.parse::<i32>() {
131 Ok(Value::Int32(i32_val))
132 } else {
133 match s.parse::<BigInt>() {
134 Ok(i) => Ok(Value::Integer(i)),
135 Err(_) => Err(ParseError::InvalidNumber(format!("Invalid integer: {}", s))),
136 }
137 }
138 } else {
139 unreachable!()
140 }
141 }
142
143 Some(token) if matches!(token.kind, TokenKind::BigInt(_)) => {
144 if let TokenKind::BigInt(s) = &token.kind {
145 *index += 1;
146 match s.parse::<BigInt>() {
147 Ok(i) => Ok(Value::Integer(i)),
148 Err(_) => Err(ParseError::InvalidNumber(format!("Invalid BigInt: {}", s))),
149 }
150 } else {
151 unreachable!()
152 }
153 }
154
155 Some(token) if matches!(token.kind, TokenKind::Rational(_, _)) => {
156 if let TokenKind::Rational(numer, denom) = &token.kind {
157 *index += 1;
158 match (numer.parse::<i64>(), denom.parse::<i64>()) {
159 (Ok(n), Ok(d)) if d != 0 => {
160 let rational = Value::Rational(BigRational::new(BigInt::from(n), BigInt::from(d)));
161 Ok(rational.demote())
162 }
163 _ => Err(ParseError::InvalidNumber(format!("Invalid rational: {}/{}", numer, denom))),
164 }
165 } else {
166 unreachable!()
167 }
168 }
169
170 #[cfg(feature = "complex_numbers")]
171 Some(token) if matches!(token.kind, TokenKind::GaussianInt(_, _)) => {
172 if let TokenKind::GaussianInt(re, im) = &token.kind {
173 *index += 1;
174 match (re.parse::<i64>(), im.parse::<i64>()) {
175 (Ok(r), Ok(i)) => Ok(Value::GaussianInt(BigInt::from(r), BigInt::from(i))),
176 _ => Err(ParseError::InvalidNumber(format!("Invalid Gaussian integer: {}+{}i", re, im))),
177 }
178 } else {
179 unreachable!()
180 }
181 }
182
183 #[cfg(feature = "complex_numbers")]
184 Some(token) if matches!(token.kind, TokenKind::Complex(_, _)) => {
185 if let TokenKind::Complex(re, im) = &token.kind {
186 *index += 1;
187 match (re.parse::<f64>(), im.parse::<f64>()) {
188 (Ok(r), Ok(i)) => Ok(Value::Complex(Complex64::new(r, i))),
189 _ => Err(ParseError::InvalidNumber(format!("Invalid complex: {}+{}i", re, im))),
190 }
191 } else {
192 unreachable!()
193 }
194 }
195
196 Some(token) if matches!(token.kind, TokenKind::Atom(_)) => {
197 if let TokenKind::Atom(atom_text) = &token.kind {
198 *index += 1;
199
200 let interned_atom = interp.intern_atom(atom_text);
205 Ok(Value::Atom(interned_atom))
206 } else {
207 unreachable!()
208 }
209 }
210
211 Some(token) if matches!(token.kind, TokenKind::String(_)) => {
212 if let TokenKind::String(string_text) = &token.kind {
213 *index += 1;
214 let string_rc: Rc<str> = string_text.clone().into();
218 Ok(Value::String(string_rc))
219 } else {
220 unreachable!()
221 }
222 }
223
224 Some(token) if matches!(token.kind, TokenKind::Boolean(_)) => {
225 if let TokenKind::Boolean(b) = token.kind {
226 *index += 1;
227 Ok(Value::Boolean(b))
230 } else {
231 unreachable!()
232 }
233 }
234
235 Some(token) if matches!(token.kind, TokenKind::Null) => {
236 *index += 1;
237 Ok(Value::Null)
240 }
241
242 Some(token) if matches!(token.kind, TokenKind::LeftBracket) => {
243 parse_list(tokens, index, interp)
246 }
247
248 Some(token) if matches!(token.kind, TokenKind::ArrayLeftBracket) => {
249 parse_array(tokens, index, interp)
250 }
251
252 Some(token) if matches!(token.kind, TokenKind::Quote) => {
253 *index += 1; match tokens.get(*index) {
259 Some(token) if matches!(token.kind, TokenKind::Atom(_)) => {
260 if let TokenKind::Atom(atom_text) = &token.kind {
261 *index += 1; let interned_atom = interp.intern_atom(atom_text);
267 Ok(Value::QuotedAtom(interned_atom))
268 } else {
269 unreachable!()
270 }
271 }
272 Some(token) if matches!(token.kind, TokenKind::LeftBracket) => {
273 Err(ParseError::UnexpectedToken(
276 "Lists cannot be quoted - they are data by default".to_string(),
277 ))
278 }
279 Some(token) if matches!(token.kind, TokenKind::String(_)) => {
280 Err(ParseError::UnexpectedToken(
282 "Strings cannot be quoted - they are data by default".to_string(),
283 ))
284 }
285 Some(token) if matches!(token.kind, TokenKind::Number(_)) => {
286 Err(ParseError::UnexpectedToken(
288 "Numbers cannot be quoted - they are data by default".to_string(),
289 ))
290 }
291 Some(token) if matches!(token.kind, TokenKind::Integer(_)) => {
292 Err(ParseError::UnexpectedToken(
293 "Numbers cannot be quoted - they are data by default".to_string(),
294 ))
295 }
296 Some(token) if matches!(token.kind, TokenKind::BigInt(_)) => {
297 Err(ParseError::UnexpectedToken(
298 "Numbers cannot be quoted - they are data by default".to_string(),
299 ))
300 }
301 Some(token) if matches!(token.kind, TokenKind::Rational(_, _)) => {
302 Err(ParseError::UnexpectedToken(
303 "Numbers cannot be quoted - they are data by default".to_string(),
304 ))
305 }
306 #[cfg(feature = "complex_numbers")]
307 Some(token) if matches!(token.kind, TokenKind::GaussianInt(_, _)) => {
308 Err(ParseError::UnexpectedToken(
309 "Numbers cannot be quoted - they are data by default".to_string(),
310 ))
311 }
312 #[cfg(feature = "complex_numbers")]
313 Some(token) if matches!(token.kind, TokenKind::Complex(_, _)) => {
314 Err(ParseError::UnexpectedToken(
315 "Numbers cannot be quoted - they are data by default".to_string(),
316 ))
317 }
318 Some(token) if matches!(token.kind, TokenKind::Boolean(_)) => {
319 Err(ParseError::UnexpectedToken(
321 "Booleans cannot be quoted - they are data by default".to_string(),
322 ))
323 }
324 Some(token) if matches!(token.kind, TokenKind::Null) => {
325 Err(ParseError::UnexpectedToken(
327 "Null cannot be quoted - it is data by default".to_string(),
328 ))
329 }
330 _ => {
331 Err(ParseError::UnexpectedEndOfInput)
333 }
334 }
335 }
336
337 Some(token) if matches!(token.kind, TokenKind::Pipe) => {
338 Err(ParseError::InvalidPipeNotation)
341 }
342
343 Some(token) if matches!(token.kind, TokenKind::RightBracket) => {
344 Err(ParseError::MismatchedBrackets)
347 }
348
349 None => Err(ParseError::UnexpectedEndOfInput),
352
353 Some(_) => Err(ParseError::UnexpectedToken("Unexpected token".to_string())),
355 }
356}
357
358fn parse_list(
364 tokens: &[Token],
365 index: &mut usize,
366 interp: &mut Interpreter,
367) -> Result<Value, ParseError> {
368 debug_assert!(
372 matches!(tokens.get(*index), Some(token) if matches!(token.kind, TokenKind::LeftBracket))
373 );
374
375 *index += 1; let mut elements = Vec::new();
380
381 loop {
384 match tokens.get(*index) {
385 Some(token) if matches!(token.kind, TokenKind::RightBracket) => {
386 *index += 1; break; }
389
390 Some(token) if matches!(token.kind, TokenKind::Pipe) => {
391 if elements.is_empty() {
394 return Err(ParseError::InvalidPipeNotation);
395 }
396
397 *index += 1; let tail = parse_value(tokens, index, interp)?;
401
402 match tokens.get(*index) {
405 Some(token) if matches!(token.kind, TokenKind::RightBracket) => {
406 *index += 1; let cons_cell = elements
412 .into_iter()
413 .rev() .fold(tail, |acc, elem| {
415 Value::Pair(Rc::new(elem), Rc::new(acc))
419 });
420
421 return Ok(cons_cell);
422 }
423 _ => return Err(ParseError::MismatchedBrackets),
424 }
425 }
426
427 None => {
428 return Err(ParseError::UnexpectedEndOfInput);
431 }
432
433 _ => {
434 let element = parse_value(tokens, index, interp)?;
437 elements.push(element);
438 }
439 }
440 }
441
442 let list = elements
446 .into_iter()
447 .rev() .fold(Value::Nil, |acc, elem| {
449 Value::Pair(Rc::new(elem), Rc::new(acc))
453 });
454
455 Ok(list)
456}
457
458fn parse_array(
459 tokens: &[Token],
460 index: &mut usize,
461 interp: &mut Interpreter,
462) -> Result<Value, ParseError> {
463 debug_assert!(
464 matches!(tokens.get(*index), Some(token) if matches!(token.kind, TokenKind::ArrayLeftBracket))
465 );
466
467 *index += 1; let mut elements = Vec::new();
470
471 loop {
472 match tokens.get(*index) {
473 Some(token) if matches!(token.kind, TokenKind::RightBracket) => {
474 *index += 1;
475 break;
476 }
477 Some(token) if matches!(token.kind, TokenKind::Pipe) => {
478 return Err(ParseError::UnexpectedToken(
479 "Arrays do not support pipe notation".to_string(),
480 ));
481 }
482 None => {
483 return Err(ParseError::UnexpectedEndOfInput);
484 }
485 _ => {
486 let element = parse_value(tokens, index, interp)?;
487 elements.push(element);
488 }
489 }
490 }
491
492 Ok(interp.make_array(elements))
493}
494
495#[cfg(test)]
499mod tests {
500 use super::*; impl ParseError {
504 fn message(&self) -> String {
505 match self {
506 ParseError::UnexpectedToken(msg) => msg.clone(),
507 ParseError::UnexpectedEndOfInput => "Unexpected end of input".to_string(),
508 ParseError::MismatchedBrackets => "Mismatched brackets".to_string(),
509 ParseError::InvalidPipeNotation => "Invalid pipe notation".to_string(),
510 ParseError::InvalidNumber(msg) => msg.clone(),
511 }
512 }
513 }
514 use super::ParseError; #[test]
519 fn test_parse_numbers() {
520 let mut interp = Interpreter::new();
523
524 let result = parse("42", &mut interp).unwrap();
527
528 assert_eq!(result.len(), 1);
531
532 assert!(matches!(&result[0], Value::Int32(42)));
536
537 let result = parse("1 2.5 -3", &mut interp).unwrap();
539 assert_eq!(result.len(), 3);
540
541 assert!(matches!(&result[0], Value::Int32(1)));
543 assert!(matches!(&result[1], Value::Number(n) if *n == 2.5));
544 assert!(matches!(&result[2], Value::Int32(-3)));
545 }
546
547 #[test]
548 fn test_parse_atoms() {
549 let mut interp = Interpreter::new();
550
551 let result = parse("hello world +", &mut interp).unwrap();
552 assert_eq!(result.len(), 3);
553
554 let expected_atoms = ["hello", "world", "+"];
557 for (i, expected) in expected_atoms.iter().enumerate() {
558 match &result[i] {
559 Value::Atom(atom) => {
560 assert_eq!(&**atom, *expected);
563 }
564 _ => panic!("Expected atom at position {}", i),
565 }
566 }
567
568 let result2 = parse("hello", &mut interp).unwrap();
571 if let (Value::Atom(atom1), Value::Atom(atom2)) = (&result[0], &result2[0]) {
572 assert!(Rc::ptr_eq(atom1, atom2)); }
574 }
575
576 #[test]
577 fn test_parse_strings() {
578 let mut interp = Interpreter::new();
579
580 let result = parse("\"hello world\" \"\"", &mut interp).unwrap();
581 assert_eq!(result.len(), 2);
582
583 match &result[0] {
584 Value::String(s) => assert_eq!(&**s, "hello world"),
585 _ => panic!("Expected string"),
586 }
587
588 match &result[1] {
589 Value::String(s) => assert_eq!(&**s, ""), _ => panic!("Expected empty string"),
591 }
592
593 let result2 = parse("\"hello world\"", &mut interp).unwrap();
596 if let (Value::String(s1), Value::String(s2)) = (&result[0], &result2[0]) {
597 assert_eq!(s1, s2); assert!(!Rc::ptr_eq(s1, s2)); }
600 }
601
602 #[test]
603 fn test_parse_empty_list() {
604 let mut interp = Interpreter::new();
605
606 let result = parse("[]", &mut interp).unwrap();
607 assert_eq!(result.len(), 1);
608
609 match &result[0] {
611 Value::Nil => (), _ => panic!("Expected empty list (Nil)"),
613 }
614 }
615
616 #[test]
617 fn test_parse_simple_list() {
618 let mut interp = Interpreter::new();
619
620 let result = parse("[1 2 3]", &mut interp).unwrap();
621 assert_eq!(result.len(), 1);
622
623 match &result[0] {
626 Value::Pair(car1, cdr1) => {
627 assert!(matches!(**car1, Value::Int32(1)));
629
630 match cdr1.as_ref() {
631 Value::Pair(car2, cdr2) => {
633 assert!(matches!(**car2, Value::Int32(2)));
635
636 match cdr2.as_ref() {
637 Value::Pair(car3, cdr3) => {
638 assert!(matches!(**car3, Value::Int32(3)));
640 assert!(matches!(**cdr3, Value::Nil));
642 }
643 _ => panic!("Expected third pair"),
644 }
645 }
646 _ => panic!("Expected second pair"),
647 }
648 }
649 _ => panic!("Expected list pair"),
650 }
651 }
652
653 #[test]
654 fn test_parse_array_literal() {
655 let mut interp = Interpreter::new();
656
657 let result = parse("#[1 2 3]", &mut interp).unwrap();
658 assert_eq!(result.len(), 1);
659
660 match &result[0] {
661 Value::Array(array_rc) => {
662 let array = array_rc.borrow();
663 assert_eq!(array.len(), 3);
664 assert!(matches!(array[0], Value::Int32(1)));
665 assert!(matches!(array[1], Value::Int32(2)));
666 assert!(matches!(array[2], Value::Int32(3)));
667 }
668 _ => panic!("Expected array value"),
669 }
670 }
671
672 #[test]
673 fn test_parse_array_disallows_pipe() {
674 let mut interp = Interpreter::new();
675
676 let result = parse("#[1 | 2]", &mut interp);
677 assert!(matches!(
678 result,
679 Err(ParseError::UnexpectedToken(msg)) if msg.contains("Arrays do not support pipe notation")
680 ));
681 }
682
683 #[test]
684 fn test_parse_pipe_notation() {
685 let mut interp = Interpreter::new();
686
687 let result = parse("[1 | 2]", &mut interp).unwrap();
689 assert_eq!(result.len(), 1);
690
691 match &result[0] {
692 Value::Pair(car, cdr) => {
693 assert!(matches!(**car, Value::Int32(1)));
694 assert!(matches!(**cdr, Value::Int32(2)));
695 }
696 _ => panic!("Expected pair"),
697 }
698
699 let result = parse("[1 2 | 3]", &mut interp).unwrap();
701 match &result[0] {
702 Value::Pair(car1, cdr1) => {
703 assert!(matches!(**car1, Value::Int32(1)));
704 match cdr1.as_ref() {
705 Value::Pair(car2, cdr2) => {
706 assert!(matches!(**car2, Value::Int32(2)));
707 assert!(matches!(**cdr2, Value::Int32(3)));
708 }
709 _ => panic!("Expected nested pair"),
710 }
711 }
712 _ => panic!("Expected pair"),
713 }
714 }
715
716 #[test]
717 fn test_parse_quoted_values() {
718 let mut interp = Interpreter::new();
719
720 let result = parse("'hello", &mut interp).unwrap();
721 assert_eq!(result.len(), 1);
722
723 match &result[0] {
726 Value::QuotedAtom(atom) => {
727 assert_eq!(&**atom, "hello");
728 }
729 _ => panic!("Expected QuotedAtom"),
730 }
731 }
732
733 #[test]
734 fn test_parse_nested_lists() {
735 let mut interp = Interpreter::new();
736
737 let result = parse("[[1 2] [3]]", &mut interp).unwrap();
738 assert_eq!(result.len(), 1);
739
740 match &result[0] {
743 Value::Pair(first_list, cdr) => {
744 match first_list.as_ref() {
746 Value::Pair(one, rest1) => {
747 assert!(matches!(**one, Value::Int32(1)));
748 match rest1.as_ref() {
749 Value::Pair(two, rest2) => {
750 assert!(matches!(**two, Value::Int32(2)));
751 assert!(matches!(**rest2, Value::Nil));
752 }
753 _ => panic!("Expected [1 2] structure"),
754 }
755 }
756 _ => panic!("Expected first list"),
757 }
758
759 match cdr.as_ref() {
761 Value::Pair(second_list, final_cdr) => {
762 match second_list.as_ref() {
764 Value::Pair(three, rest3) => {
765 assert!(matches!(**three, Value::Int32(3)));
766 assert!(matches!(**rest3, Value::Nil));
767 }
768 _ => panic!("Expected [3] structure"),
769 }
770 assert!(matches!(**final_cdr, Value::Nil));
771 }
772 _ => panic!("Expected second list pair"),
773 }
774 }
775 _ => panic!("Expected outer list"),
776 }
777 }
778
779 #[test]
780 fn test_parse_errors() {
781 let mut interp = Interpreter::new();
782
783 assert!(parse("[1 2", &mut interp).is_err());
788 assert!(parse("1 2]", &mut interp).is_err());
789
790 assert!(parse("[|]", &mut interp).is_err());
792 assert!(parse("[1 | 2 3]", &mut interp).is_err()); assert!(parse("1 | 2", &mut interp).is_err());
796 }
797
798 #[test]
799 fn test_parse_with_comments() {
800 let mut interp = Interpreter::new();
801
802 let result = parse("42 \\ this is a comment\n37", &mut interp).unwrap();
805 assert_eq!(result.len(), 2);
806
807 match (&result[0], &result[1]) {
808 (Value::Int32(42), Value::Int32(37)) => {
809 }
811 _ => panic!("Expected two Int32 values: 42 and 37"),
812 }
813 }
814
815 #[test]
816 fn test_parse_quoted_atoms_only() {
817 let mut interp = Interpreter::new();
818
819 let result = parse("'hello", &mut interp).unwrap();
821 assert_eq!(result.len(), 1);
822
823 match &result[0] {
825 Value::QuotedAtom(atom) => {
826 assert_eq!(&**atom, "hello");
827 }
828 _ => panic!("Expected QuotedAtom"),
829 }
830
831 let result = parse("'+ '- '*", &mut interp).unwrap();
833 assert_eq!(result.len(), 3);
834
835 for (i, op) in ["+", "-", "*"].iter().enumerate() {
836 match &result[i] {
837 Value::QuotedAtom(atom) => {
838 assert_eq!(&**atom, *op);
839 }
840 _ => panic!("Expected QuotedAtom at {}", i),
841 }
842 }
843 }
844
845 #[test]
846 fn test_parse_reject_quoted_non_atoms() {
847 let mut interp = Interpreter::new();
848
849 assert!(parse("'[1 2 3]", &mut interp).is_err());
854 assert!(parse("'[]", &mut interp).is_err());
855 assert!(parse("'[[nested]]", &mut interp).is_err());
856
857 assert!(parse("'\"hello\"", &mut interp).is_err());
859 assert!(parse("'\"\"", &mut interp).is_err());
860
861 assert!(parse("'3.14", &mut interp).is_err());
863 assert!(parse("'-17.5", &mut interp).is_err());
864 assert!(parse("'1e5", &mut interp).is_err());
865
866 let result = parse("'[1 2]", &mut interp);
868 assert!(result.is_err());
869 let error_msg = format!("{:?}", result.unwrap_err());
870 assert!(error_msg.contains("Lists cannot be quoted"));
871
872 let result = parse("'\"string\"", &mut interp);
873 assert!(result.is_err());
874 let error_msg = format!("{:?}", result.unwrap_err());
875 assert!(error_msg.contains("Strings cannot be quoted"));
876
877 let result = parse("'3.14", &mut interp);
878 assert!(result.is_err());
879 let error_msg = format!("{:?}", result.unwrap_err());
880 assert!(error_msg.contains("Numbers cannot be quoted"));
881 }
882
883 #[test]
884 fn test_parse_mixed_types_in_list() {
885 let mut interp = Interpreter::new();
886
887 let result = parse("[42 hello \"world\" [nested]]", &mut interp).unwrap();
888 assert_eq!(result.len(), 1);
889
890 match &result[0] {
893 Value::Pair(first, rest1) => {
894 assert!(matches!(first.as_ref(), Value::Int32(42)));
895
896 match rest1.as_ref() {
897 Value::Pair(second, rest2) => {
898 assert!(matches!(second.as_ref(), Value::Atom(a) if &**a == "hello"));
899
900 match rest2.as_ref() {
901 Value::Pair(third, rest3) => {
902 assert!(
903 matches!(third.as_ref(), Value::String(s) if &**s == "world")
904 );
905
906 match rest3.as_ref() {
907 Value::Pair(fourth, rest4) => {
908 assert!(matches!(fourth.as_ref(), Value::Pair(_, _)));
910 assert!(matches!(rest4.as_ref(), Value::Nil));
911 }
912 _ => panic!("Expected fourth element"),
913 }
914 }
915 _ => panic!("Expected third element"),
916 }
917 }
918 _ => panic!("Expected second element"),
919 }
920 }
921 _ => panic!("Expected list"),
922 }
923 }
924
925 #[test]
926 fn test_parse_whitespace_handling() {
927 let mut interp = Interpreter::new();
928
929 let inputs = [
932 " 1 2 3 ", "1\n2\t3\r\n4", "[ 1 2 ]", "[ 1 | 2 ]", "' hello ", ];
938
939 let expected_lengths = [3, 4, 1, 1, 1];
940
941 for (input, expected_len) in inputs.iter().zip(expected_lengths.iter()) {
942 let result = parse(input, &mut interp).unwrap();
943 assert_eq!(result.len(), *expected_len, "Failed for input: '{}'", input);
944 }
945 }
946
947 #[test]
948 fn test_parse_deeply_nested_lists() {
949 let mut interp = Interpreter::new();
950
951 let result = parse("[[[[1]]]]", &mut interp).unwrap();
954 assert_eq!(result.len(), 1);
955
956 let mut current = &result[0];
958 for _level in 0..4 {
959 match current {
960 Value::Pair(car, cdr) => {
961 current = car.as_ref();
962 assert!(matches!(cdr.as_ref(), Value::Nil));
963 }
964 Value::Number(n) if *n == 1.0 => break,
965 _ => panic!("Expected nested structure"),
966 }
967 }
968 }
969
970 #[test]
971 #[cfg(feature = "complex_numbers")]
972 fn test_parse_complex_pipe_cases() {
973 let mut interp = Interpreter::new();
974
975 assert!(parse("[1 | 2 | 3]", &mut interp).is_err());
979
980 assert!(parse("[| 1]", &mut interp).is_err());
982
983 assert!(parse("[1 | 2 3]", &mut interp).is_err());
985
986 let result = parse("[[1 | 2]]", &mut interp).unwrap();
988 match &result[0] {
989 Value::Pair(inner_list, outer_cdr) => {
990 match inner_list.as_ref() {
991 Value::Pair(one, two) => {
992 assert!(matches!(one.as_ref(), Value::Int32(1)));
993 assert!(matches!(two.as_ref(), Value::Int32(2)));
994 }
995 _ => panic!("Expected inner pair"),
996 }
997 assert!(matches!(outer_cdr.as_ref(), Value::Nil));
998 }
999 _ => panic!("Expected outer list"),
1000 }
1001 }
1002
1003 #[test]
1004 fn test_parse_scientific_notation() {
1005 let mut interp = Interpreter::new();
1006
1007 let result = parse("1e5 2.5e-3 1E10", &mut interp).unwrap();
1010 assert_eq!(result.len(), 3);
1011
1012 let expected = [1e5, 2.5e-3, 1E10];
1013 for (i, expected_val) in expected.iter().enumerate() {
1014 match &result[i] {
1015 Value::Number(n) => assert_eq!(*n, *expected_val),
1016 _ => panic!("Expected number at position {}", i),
1017 }
1018 }
1019 }
1020
1021 #[test]
1022 fn test_parse_empty_input() {
1023 let mut interp = Interpreter::new();
1024
1025 let result = parse("", &mut interp).unwrap();
1027 assert_eq!(result.len(), 0);
1028
1029 let result = parse(" ", &mut interp).unwrap(); assert_eq!(result.len(), 0);
1031
1032 let result = parse("\\ just a comment", &mut interp).unwrap();
1033 assert_eq!(result.len(), 0);
1034 }
1035
1036 #[test]
1037 fn test_parse_quote_edge_cases() {
1038 let mut interp = Interpreter::new();
1039
1040 assert!(parse("'", &mut interp).is_err());
1042
1043 assert!(parse("''hello", &mut interp).is_err());
1047
1048 assert!(parse("'|", &mut interp).is_err());
1050 assert!(parse("']", &mut interp).is_err());
1051
1052 let result = parse("'quote-me", &mut interp).unwrap();
1054 assert_eq!(result.len(), 1);
1055
1056 match &result[0] {
1057 Value::QuotedAtom(atom) => {
1058 assert_eq!(&**atom, "quote-me");
1059 }
1060 _ => panic!("Expected QuotedAtom"),
1061 }
1062 }
1063
1064 #[test]
1065 fn test_parse_error_messages() {
1066 let mut interp = Interpreter::new();
1067
1068 let error_cases = [
1070 ("[1 2", "UnexpectedEndOfInput"),
1071 ("1 2]", "MismatchedBrackets"),
1072 ("[|]", "InvalidPipeNotation"),
1073 ("1 | 2", "InvalidPipeNotation"),
1074 ("'[1 2]", "Lists cannot be quoted"),
1075 ("'\"hello\"", "Strings cannot be quoted"),
1076 ("'42.0", "Numbers cannot be quoted"), ("'", "UnexpectedEndOfInput"), ];
1079
1080 for (input, expected_error) in error_cases.iter() {
1081 let result = parse(input, &mut interp);
1082 assert!(result.is_err(), "Expected error for input: '{}'", input);
1083
1084 let error_string = format!("{:?}", result.unwrap_err());
1085 assert!(
1087 error_string.contains(expected_error),
1088 "Expected '{}' in error message for '{}', got: {}",
1089 expected_error,
1090 input,
1091 error_string
1092 );
1093 }
1094 }
1095
1096 #[test]
1097 fn test_parse_booleans() {
1098 let mut interp = Interpreter::new();
1099
1100 let result = parse("true", &mut interp).unwrap();
1102 assert_eq!(result.len(), 1);
1103 assert!(matches!(result[0], Value::Boolean(true)));
1104
1105 let result = parse("false", &mut interp).unwrap();
1107 assert_eq!(result.len(), 1);
1108 assert!(matches!(result[0], Value::Boolean(false)));
1109
1110 let result = parse("true 42 \"hello\" false", &mut interp).unwrap();
1112 assert_eq!(result.len(), 4);
1113 assert!(matches!(result[0], Value::Boolean(true)));
1114 assert!(matches!(result[1], Value::Int32(42))); assert!(matches!(result[2], Value::String(_)));
1116 assert!(matches!(result[3], Value::Boolean(false)));
1117 }
1118
1119 #[test]
1120 fn test_parse_null() {
1121 let mut interp = Interpreter::new();
1122
1123 let result = parse("null", &mut interp).unwrap();
1125 assert_eq!(result.len(), 1);
1126 assert!(matches!(result[0], Value::Null));
1127
1128 let result = parse("null 42 true \"test\"", &mut interp).unwrap();
1130 assert_eq!(result.len(), 4);
1131 assert!(matches!(result[0], Value::Null));
1132 assert!(matches!(result[1], Value::Int32(42)));
1133 assert!(matches!(result[2], Value::Boolean(true)));
1134 assert!(matches!(result[3], Value::String(_)));
1135 }
1136
1137 #[test]
1138 fn test_parse_boolean_null_in_lists() {
1139 let mut interp = Interpreter::new();
1140
1141 let result = parse("[true false null 42]", &mut interp).unwrap();
1143 assert_eq!(result.len(), 1);
1144
1145 match &result[0] {
1146 Value::Pair(car1, cdr1) => {
1147 assert!(matches!(car1.as_ref(), Value::Boolean(true)));
1148 match cdr1.as_ref() {
1149 Value::Pair(car2, cdr2) => {
1150 assert!(matches!(car2.as_ref(), Value::Boolean(false)));
1151 match cdr2.as_ref() {
1152 Value::Pair(car3, cdr3) => {
1153 assert!(matches!(car3.as_ref(), Value::Null));
1154 match cdr3.as_ref() {
1155 Value::Pair(car4, cdr4) => {
1156 assert!(matches!(car4.as_ref(), Value::Int32(42)));
1157 assert!(matches!(cdr4.as_ref(), Value::Nil));
1158 }
1159 _ => panic!("Expected fourth element"),
1160 }
1161 }
1162 _ => panic!("Expected third element"),
1163 }
1164 }
1165 _ => panic!("Expected second element"),
1166 }
1167 }
1168 _ => panic!("Expected list structure"),
1169 }
1170 }
1171
1172 #[test]
1173 fn test_parse_quoted_booleans_null_error() {
1174 let mut interp = Interpreter::new();
1175
1176 let error_cases = vec![
1178 ("'true", "cannot be quoted"),
1179 ("'false", "cannot be quoted"),
1180 ("'null", "cannot be quoted"),
1181 ];
1182
1183 for (input, expected_error) in error_cases.iter() {
1184 let result = parse(input, &mut interp);
1185 assert!(result.is_err(), "Expected error for input: '{}'", input);
1186
1187 let error_string = format!("{:?}", result.unwrap_err());
1188 assert!(
1189 error_string
1190 .to_lowercase()
1191 .contains(&expected_error.to_lowercase()),
1192 "Expected '{}' in error message for '{}', got: {}",
1193 expected_error,
1194 input,
1195 error_string
1196 );
1197 }
1198 }
1199
1200 #[test]
1201 fn test_boolean_null_not_atoms() {
1202 let mut interp = Interpreter::new();
1203
1204 let result = parse("true false null", &mut interp).unwrap();
1206 assert_eq!(result.len(), 3);
1207
1208 assert!(
1210 matches!(result[0], Value::Boolean(true)),
1211 "Expected Boolean(true), got: {:?}",
1212 result[0]
1213 );
1214 assert!(
1215 !matches!(result[0], Value::Atom(_)),
1216 "true should NOT be parsed as an atom"
1217 );
1218
1219 assert!(
1220 matches!(result[1], Value::Boolean(false)),
1221 "Expected Boolean(false), got: {:?}",
1222 result[1]
1223 );
1224 assert!(
1225 !matches!(result[1], Value::Atom(_)),
1226 "false should NOT be parsed as an atom"
1227 );
1228
1229 assert!(
1230 matches!(result[2], Value::Null),
1231 "Expected Null, got: {:?}",
1232 result[2]
1233 );
1234 assert!(
1235 !matches!(result[2], Value::Atom(_)),
1236 "null should NOT be parsed as an atom"
1237 );
1238
1239 let result = parse("TRUE True false-flag NULL nil", &mut interp).unwrap();
1241 assert_eq!(result.len(), 5);
1242
1243 for (i, val) in result.iter().enumerate() {
1244 assert!(
1245 matches!(val, Value::Atom(_)),
1246 "Element {} should be an atom, got: {:?}",
1247 i,
1248 val
1249 );
1250 }
1251 }
1252
1253 #[test]
1254 fn test_parse_error_message_method() {
1255 let mut interp = Interpreter::new();
1256
1257 let error = ParseError::UnexpectedToken("Custom error message".to_string());
1259 assert_eq!(error.message(), "Custom error message");
1260
1261 assert_eq!(
1263 ParseError::UnexpectedEndOfInput.message(),
1264 "Unexpected end of input"
1265 );
1266 assert_eq!(
1267 ParseError::MismatchedBrackets.message(),
1268 "Mismatched brackets"
1269 );
1270 assert_eq!(
1271 ParseError::InvalidPipeNotation.message(),
1272 "Invalid pipe notation"
1273 );
1274
1275 let result = parse("'", &mut interp);
1277 assert!(result.is_err());
1278 if let Err(error) = result {
1279 let message = error.message();
1280 assert!(!message.is_empty());
1281 }
1282 }
1283
1284 #[test]
1287 fn test_parse_bigint_literals() {
1288 use num_bigint::BigInt;
1289 let mut interp = Interpreter::new();
1290
1291 let result = parse("123n", &mut interp).unwrap();
1293 assert_eq!(result.len(), 1);
1294 assert!(matches!(result[0], Value::Integer(ref i) if *i == BigInt::from(123)));
1295
1296 let result = parse("-456n", &mut interp).unwrap();
1298 assert_eq!(result.len(), 1);
1299 assert!(matches!(result[0], Value::Integer(ref i) if *i == BigInt::from(-456)));
1300
1301 let result = parse("123456789012345678901234567890n", &mut interp).unwrap();
1303 assert_eq!(result.len(), 1);
1304 let expected = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
1305 assert!(matches!(result[0], Value::Integer(ref i) if *i == expected));
1306
1307 let result = parse("0n", &mut interp).unwrap();
1309 assert_eq!(result.len(), 1);
1310 assert!(matches!(result[0], Value::Integer(ref i) if *i == BigInt::from(0)));
1311 }
1312
1313 #[test]
1314 fn test_parse_rational_literals() {
1315 use num_bigint::BigInt;
1316 use num_rational::BigRational;
1317 let mut interp = Interpreter::new();
1318
1319 let result = parse("3/4", &mut interp).unwrap();
1321 assert_eq!(result.len(), 1);
1322 let expected = BigRational::new(BigInt::from(3), BigInt::from(4));
1323 assert!(matches!(result[0], Value::Rational(ref r) if *r == expected));
1324
1325 let result = parse("1/2", &mut interp).unwrap();
1327 assert_eq!(result.len(), 1);
1328 let expected = BigRational::new(BigInt::from(1), BigInt::from(2));
1329 assert!(matches!(result[0], Value::Rational(ref r) if *r == expected));
1330
1331 let result = parse("-5/8", &mut interp).unwrap();
1333 assert_eq!(result.len(), 1);
1334 let expected = BigRational::new(BigInt::from(-5), BigInt::from(8));
1335 assert!(matches!(result[0], Value::Rational(ref r) if *r == expected));
1336 }
1337
1338 #[test]
1339 #[cfg(feature = "complex_numbers")]
1340 fn test_parse_gaussian_and_complex_literals() {
1341 use num_bigint::BigInt;
1342 use num_complex::Complex64;
1343 let mut interp = Interpreter::new();
1344
1345 let result = parse("3+4i", &mut interp).unwrap();
1347 assert_eq!(result.len(), 1);
1348 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1349 if re == &BigInt::from(3) && im == &BigInt::from(4)));
1350
1351 let result = parse("5-2i", &mut interp).unwrap();
1353 assert_eq!(result.len(), 1);
1354 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1355 if re == &BigInt::from(5) && im == &BigInt::from(-2)));
1356
1357 let result = parse("5i", &mut interp).unwrap();
1359 assert_eq!(result.len(), 1);
1360 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1361 if re == &BigInt::from(0) && im == &BigInt::from(5)));
1362
1363 let result = parse("-3+4i", &mut interp).unwrap();
1365 assert_eq!(result.len(), 1);
1366 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1367 if re == &BigInt::from(-3) && im == &BigInt::from(4)));
1368
1369 let result = parse("1.5+2.5i", &mut interp).unwrap();
1371 assert_eq!(result.len(), 1);
1372 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(1.5, 2.5)));
1373 }
1374
1375 #[test]
1376 fn test_parse_mixed_number_types() {
1377 use num_bigint::BigInt;
1378 use num_rational::BigRational;
1379 let mut interp = Interpreter::new();
1380
1381 #[cfg(feature = "complex_numbers")]
1383 {
1384 let result = parse("42 123n 3/4 2+3i", &mut interp).unwrap();
1385 assert_eq!(result.len(), 4);
1386
1387 assert!(matches!(result[0], Value::Int32(42)));
1388 assert!(matches!(result[1], Value::Integer(ref i) if *i == BigInt::from(123)));
1389 assert!(matches!(result[2], Value::Rational(ref r) if *r == BigRational::new(BigInt::from(3), BigInt::from(4))));
1390 assert!(matches!(result[3], Value::GaussianInt(ref re, ref im)
1391 if re == &BigInt::from(2) && im == &BigInt::from(3)));
1392 }
1393
1394 #[cfg(not(feature = "complex_numbers"))]
1395 {
1396 let result = parse("42 123n 3/4", &mut interp).unwrap();
1397 assert_eq!(result.len(), 3);
1398
1399 assert!(matches!(result[0], Value::Int32(42)));
1400 assert!(matches!(result[1], Value::Integer(ref i) if *i == BigInt::from(123)));
1401 assert!(matches!(result[2], Value::Rational(ref r) if *r == BigRational::new(BigInt::from(3), BigInt::from(4))));
1402 }
1403 }
1404
1405 #[test]
1406 fn test_parse_number_types_in_lists() {
1407 use num_bigint::BigInt;
1408 let mut interp = Interpreter::new();
1409
1410 let result = parse("[1 2n 3]", &mut interp).unwrap();
1412 assert_eq!(result.len(), 1);
1413
1414 match &result[0] {
1416 Value::Pair(_, _) => {
1417 }
1419 _ => panic!("Expected list"),
1420 }
1421
1422 #[cfg(feature = "complex_numbers")]
1424 {
1425 let result = parse("[1+2i 3+4i]", &mut interp).unwrap();
1426 assert_eq!(result.len(), 1);
1427 match &result[0] {
1428 Value::Pair(car, cdr) => {
1429 assert!(matches!(**car, Value::GaussianInt(ref re, ref im)
1430 if re == &BigInt::from(1) && im == &BigInt::from(2)));
1431 match cdr.as_ref() {
1432 Value::Pair(car2, _) => {
1433 assert!(matches!(**car2, Value::GaussianInt(ref re, ref im)
1434 if re == &BigInt::from(3) && im == &BigInt::from(4)));
1435 }
1436 _ => panic!("Expected second element"),
1437 }
1438 }
1439 _ => panic!("Expected list"),
1440 }
1441 }
1442 }
1443
1444 #[test]
1447 #[cfg(feature = "complex_numbers")]
1448 fn test_parse_complex_negative_imaginary() {
1449 use num_bigint::BigInt;
1450 let mut interp = Interpreter::new();
1451
1452 let result = parse("3-4i", &mut interp).unwrap();
1454 assert_eq!(result.len(), 1);
1455 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1456 if re == &BigInt::from(3) && im == &BigInt::from(-4)));
1457
1458 let result = parse("-3-4i", &mut interp).unwrap();
1460 assert_eq!(result.len(), 1);
1461 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1462 if re == &BigInt::from(-3) && im == &BigInt::from(-4)));
1463 }
1464
1465 #[test]
1466 #[cfg(feature = "complex_numbers")]
1467 fn test_parse_complex_zero_parts() {
1468 use num_bigint::BigInt;
1469 let mut interp = Interpreter::new();
1470
1471 let result = parse("0+5i", &mut interp).unwrap();
1473 assert_eq!(result.len(), 1);
1474 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1475 if re == &BigInt::from(0) && im == &BigInt::from(5)));
1476
1477 let result = parse("5+0i", &mut interp).unwrap();
1479 assert_eq!(result.len(), 1);
1480 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1481 if re == &BigInt::from(5) && im == &BigInt::from(0)));
1482
1483 let result = parse("0+0i", &mut interp).unwrap();
1485 assert_eq!(result.len(), 1);
1486 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1487 if re == &BigInt::from(0) && im == &BigInt::from(0)));
1488 }
1489
1490 #[test]
1491 #[cfg(feature = "complex_numbers")]
1492 fn test_parse_complex_decimal_parts() {
1493 use num_complex::Complex64;
1494 let mut interp = Interpreter::new();
1495
1496 let result = parse("1.5+2.5i", &mut interp).unwrap();
1498 assert_eq!(result.len(), 1);
1499 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(1.5, 2.5)));
1500
1501 let result = parse("3.14+2i", &mut interp).unwrap();
1503 assert_eq!(result.len(), 1);
1504 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(3.14, 2.0)));
1505
1506 let result = parse("2+3.14i", &mut interp).unwrap();
1508 assert_eq!(result.len(), 1);
1509 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(2.0, 3.14)));
1510
1511 let result = parse("0.1+0.2i", &mut interp).unwrap();
1513 assert_eq!(result.len(), 1);
1514 assert!(matches!(result[0], Value::Complex(c) if (c.re - 0.1).abs() < 0.0001 && (c.im - 0.2).abs() < 0.0001));
1515 }
1516
1517 #[test]
1518 #[cfg(feature = "complex_numbers")]
1519 fn test_parse_complex_pure_imaginary_edge_cases() {
1520 use num_bigint::BigInt;
1521 use num_complex::Complex64;
1522 let mut interp = Interpreter::new();
1523
1524 let result = parse("5i", &mut interp).unwrap();
1526 assert_eq!(result.len(), 1);
1527 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1528 if re == &BigInt::from(0) && im == &BigInt::from(5)));
1529
1530 let result = parse("-5i", &mut interp).unwrap();
1532 assert_eq!(result.len(), 1);
1533 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1534 if re == &BigInt::from(0) && im == &BigInt::from(-5)));
1535
1536 let result = parse("3.5i", &mut interp).unwrap();
1538 assert_eq!(result.len(), 1);
1539 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(0.0, 3.5)));
1540
1541 let result = parse("0i", &mut interp).unwrap();
1543 assert_eq!(result.len(), 1);
1544 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1545 if re == &BigInt::from(0) && im == &BigInt::from(0)));
1546 }
1547
1548 #[test]
1549 #[cfg(feature = "complex_numbers")]
1550 fn test_parse_complex_large_numbers() {
1551 use num_bigint::BigInt;
1552 let mut interp = Interpreter::new();
1553
1554 let result = parse("1000000+2000000i", &mut interp).unwrap();
1556 assert_eq!(result.len(), 1);
1557 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1558 if re == &BigInt::from(1000000) && im == &BigInt::from(2000000)));
1559
1560 let result = parse("123456.789+987654.321i", &mut interp).unwrap();
1562 assert_eq!(result.len(), 1);
1563 match &result[0] {
1564 Value::Complex(c) => {
1565 assert!((c.re - 123456.789).abs() < 0.001);
1566 assert!((c.im - 987654.321).abs() < 0.001);
1567 }
1568 _ => panic!("Expected complex"),
1569 }
1570 }
1571
1572 #[test]
1573 #[cfg(feature = "complex_numbers")]
1574 fn test_parse_complex_with_spaces_fails() {
1575 let mut interp = Interpreter::new();
1576
1577 let result = parse("3 + 4i", &mut interp).unwrap();
1580 assert_eq!(result.len(), 3); let result = parse("3+4i", &mut interp).unwrap();
1584 assert_eq!(result.len(), 1);
1585 assert!(matches!(result[0], Value::GaussianInt(_, _)));
1586 }
1587
1588 #[test]
1589 #[cfg(feature = "complex_numbers")]
1590 fn test_parse_complex_not_confused_with_operators() {
1591 use num_bigint::BigInt;
1592 let mut interp = Interpreter::new();
1593
1594 let result = parse("3 4 +", &mut interp).unwrap();
1597 assert_eq!(result.len(), 3);
1598
1599 let result = parse("3+4i", &mut interp).unwrap();
1601 assert_eq!(result.len(), 1);
1602 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1603 if re == &BigInt::from(3) && im == &BigInt::from(4)));
1604 }
1605
1606 #[test]
1607 #[cfg(feature = "complex_numbers")]
1608 fn test_parse_complex_multiple_signs() {
1609 use num_bigint::BigInt;
1610 let mut interp = Interpreter::new();
1611
1612 let result = parse("1+2i 3-4i -5+6i -7-8i", &mut interp).unwrap();
1614 assert_eq!(result.len(), 4);
1615
1616 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1617 if re == &BigInt::from(1) && im == &BigInt::from(2)));
1618 assert!(matches!(result[1], Value::GaussianInt(ref re, ref im)
1619 if re == &BigInt::from(3) && im == &BigInt::from(-4)));
1620 assert!(matches!(result[2], Value::GaussianInt(ref re, ref im)
1621 if re == &BigInt::from(-5) && im == &BigInt::from(6)));
1622 assert!(matches!(result[3], Value::GaussianInt(ref re, ref im)
1623 if re == &BigInt::from(-7) && im == &BigInt::from(-8)));
1624 }
1625
1626 #[test]
1627 #[cfg(feature = "complex_numbers")]
1628 fn test_parse_complex_scientific_notation() {
1629 use num_complex::Complex64;
1630 let mut interp = Interpreter::new();
1631
1632 let result = parse("1e2+3e1i", &mut interp).unwrap();
1634 assert_eq!(result.len(), 1);
1635 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(100.0, 30.0)));
1636
1637 }
1641
1642 #[test]
1643 fn test_parse_rational_edge_cases() {
1644 use num_rational::BigRational;
1645
1646 let mut interp = Interpreter::new();
1647
1648 let result = parse("1/1", &mut interp).unwrap();
1650 assert_eq!(result.len(), 1);
1651 assert!(matches!(result[0], Value::Int32(1)));
1652
1653 let result = parse("0/1", &mut interp).unwrap();
1655 assert_eq!(result.len(), 1);
1656 assert!(matches!(result[0], Value::Int32(0)));
1657
1658 let result = parse("123456789/987654321", &mut interp).unwrap();
1660 assert_eq!(result.len(), 1);
1661 let expected = BigRational::new(BigInt::from(123456789), BigInt::from(987654321));
1662 assert!(matches!(result[0], Value::Rational(ref r) if *r == expected));
1663 }
1664
1665 #[test]
1666 fn test_parse_bigint_edge_cases() {
1667 use num_bigint::BigInt;
1668 use num_traits::Zero;
1669 let mut interp = Interpreter::new();
1670
1671 let result = parse("0n", &mut interp).unwrap();
1673 assert_eq!(result.len(), 1);
1674 assert!(matches!(result[0], Value::Integer(ref i) if i.is_zero()));
1675
1676 let result = parse("1n", &mut interp).unwrap();
1678 assert_eq!(result.len(), 1);
1679 assert!(matches!(result[0], Value::Integer(ref i) if *i == BigInt::from(1)));
1680
1681 let result = parse("-0n", &mut interp).unwrap();
1683 assert_eq!(result.len(), 1);
1684 assert!(matches!(result[0], Value::Integer(ref i) if i.is_zero()));
1685 }
1686
1687 #[test]
1688 fn test_parse_integer_vs_float_literals() {
1689
1690 let mut interp = Interpreter::new();
1691
1692 let result = parse("1", &mut interp).unwrap();
1694 assert_eq!(result.len(), 1);
1695 assert!(matches!(result[0], Value::Int32(1)));
1696
1697 let result = parse("42", &mut interp).unwrap();
1698 assert_eq!(result.len(), 1);
1699 assert!(matches!(result[0], Value::Int32(42)));
1700
1701 let result = parse("-5", &mut interp).unwrap();
1702 assert_eq!(result.len(), 1);
1703 assert!(matches!(result[0], Value::Int32(-5)));
1704
1705 let result = parse("0", &mut interp).unwrap();
1706 assert_eq!(result.len(), 1);
1707 assert!(matches!(result[0], Value::Int32(0)));
1708
1709 let result = parse("1.0", &mut interp).unwrap();
1711 assert_eq!(result.len(), 1);
1712 assert!(matches!(result[0], Value::Number(n) if n == 1.0));
1713
1714 let result = parse("42.0", &mut interp).unwrap();
1715 assert_eq!(result.len(), 1);
1716 assert!(matches!(result[0], Value::Number(n) if n == 42.0));
1717
1718 let result = parse("-5.0", &mut interp).unwrap();
1719 assert_eq!(result.len(), 1);
1720 assert!(matches!(result[0], Value::Number(n) if n == -5.0));
1721
1722 let result = parse("3.14", &mut interp).unwrap();
1723 assert_eq!(result.len(), 1);
1724 assert!(matches!(result[0], Value::Number(n) if n == 3.14));
1725
1726 let result = parse("1e10", &mut interp).unwrap();
1728 assert_eq!(result.len(), 1);
1729 assert!(matches!(result[0], Value::Number(n) if n == 1e10));
1730
1731 let result = parse("1.5e-3", &mut interp).unwrap();
1732 assert_eq!(result.len(), 1);
1733 assert!(matches!(result[0], Value::Number(n) if n == 1.5e-3));
1734 }
1735
1736 #[test]
1737 #[cfg(feature = "complex_numbers")]
1738 fn test_parse_complex_integer_vs_float() {
1739 use num_bigint::BigInt;
1740 use num_complex::Complex64;
1741 let mut interp = Interpreter::new();
1742
1743 let result = parse("1+2i", &mut interp).unwrap();
1745 assert_eq!(result.len(), 1);
1746 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1747 if re == &BigInt::from(1) && im == &BigInt::from(2)));
1748
1749 let result = parse("3-4i", &mut interp).unwrap();
1750 assert_eq!(result.len(), 1);
1751 assert!(matches!(result[0], Value::GaussianInt(ref re, ref im)
1752 if re == &BigInt::from(3) && im == &BigInt::from(-4)));
1753
1754 let result = parse("1.0+2.0i", &mut interp).unwrap();
1756 assert_eq!(result.len(), 1);
1757 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(1.0, 2.0)));
1758
1759 let result = parse("3.0-4.0i", &mut interp).unwrap();
1760 assert_eq!(result.len(), 1);
1761 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(3.0, -4.0)));
1762
1763 let result = parse("1.0+2i", &mut interp).unwrap();
1765 assert_eq!(result.len(), 1);
1766 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(1.0, 2.0)));
1767
1768 let result = parse("1+2.0i", &mut interp).unwrap();
1769 assert_eq!(result.len(), 1);
1770 assert!(matches!(result[0], Value::Complex(c) if c == Complex64::new(1.0, 2.0)));
1771 }
1772}