2626//! assert_eq!(result, 15);
2727//! ```
2828
29- use anyhow:: { anyhow, Result } ;
3029use crate :: state:: ShellState ;
30+ use anyhow:: { anyhow, Result } ;
3131
3232/// Arithmetic operators
3333#[ derive( Debug , Clone , PartialEq ) ]
@@ -144,7 +144,8 @@ impl Tokenizer {
144144 }
145145 }
146146
147- num_str. parse :: < i64 > ( )
147+ num_str
148+ . parse :: < i64 > ( )
148149 . map_err ( |_| anyhow ! ( "Invalid number: {}" , num_str) )
149150 }
150151
@@ -295,7 +296,10 @@ impl Tokenizer {
295296 }
296297 }
297298
298- Some ( ch) => Err ( anyhow ! ( "Unexpected character in arithmetic expression: {}" , ch) ) ,
299+ Some ( ch) => Err ( anyhow ! (
300+ "Unexpected character in arithmetic expression: {}" ,
301+ ch
302+ ) ) ,
299303 }
300304 }
301305}
@@ -508,7 +512,11 @@ impl Parser {
508512 if matches ! ( self . peek( ) , Token :: Op ( ArithOp :: Pow ) ) {
509513 self . advance ( ) ;
510514 let right = self . parse_power ( ) ?; // Right-associative recursion
511- Ok ( ArithExpr :: BinaryOp ( ArithOp :: Pow , Box :: new ( left) , Box :: new ( right) ) )
515+ Ok ( ArithExpr :: BinaryOp (
516+ ArithOp :: Pow ,
517+ Box :: new ( left) ,
518+ Box :: new ( right) ,
519+ ) )
512520 } else {
513521 Ok ( left)
514522 }
@@ -554,7 +562,10 @@ impl Parser {
554562 Ok ( expr)
555563 }
556564
557- token => Err ( anyhow ! ( "Unexpected token in arithmetic expression: {:?}" , token) ) ,
565+ token => Err ( anyhow ! (
566+ "Unexpected token in arithmetic expression: {:?}" ,
567+ token
568+ ) ) ,
558569 }
559570 }
560571}
@@ -704,65 +715,149 @@ mod tests {
704715 fn test_arith_basic_ops ( ) {
705716 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
706717
707- assert_eq ! ( eval_arith( & parse_arithmetic( "5 + 3" ) . unwrap( ) , & state) . unwrap( ) , 8 ) ;
708- assert_eq ! ( eval_arith( & parse_arithmetic( "10 - 4" ) . unwrap( ) , & state) . unwrap( ) , 6 ) ;
709- assert_eq ! ( eval_arith( & parse_arithmetic( "6 * 7" ) . unwrap( ) , & state) . unwrap( ) , 42 ) ;
710- assert_eq ! ( eval_arith( & parse_arithmetic( "20 / 4" ) . unwrap( ) , & state) . unwrap( ) , 5 ) ;
711- assert_eq ! ( eval_arith( & parse_arithmetic( "17 % 5" ) . unwrap( ) , & state) . unwrap( ) , 2 ) ;
718+ assert_eq ! (
719+ eval_arith( & parse_arithmetic( "5 + 3" ) . unwrap( ) , & state) . unwrap( ) ,
720+ 8
721+ ) ;
722+ assert_eq ! (
723+ eval_arith( & parse_arithmetic( "10 - 4" ) . unwrap( ) , & state) . unwrap( ) ,
724+ 6
725+ ) ;
726+ assert_eq ! (
727+ eval_arith( & parse_arithmetic( "6 * 7" ) . unwrap( ) , & state) . unwrap( ) ,
728+ 42
729+ ) ;
730+ assert_eq ! (
731+ eval_arith( & parse_arithmetic( "20 / 4" ) . unwrap( ) , & state) . unwrap( ) ,
732+ 5
733+ ) ;
734+ assert_eq ! (
735+ eval_arith( & parse_arithmetic( "17 % 5" ) . unwrap( ) , & state) . unwrap( ) ,
736+ 2
737+ ) ;
712738 }
713739
714740 #[ test]
715741 fn test_arith_precedence ( ) {
716742 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
717743
718- assert_eq ! ( eval_arith( & parse_arithmetic( "2 + 3 * 4" ) . unwrap( ) , & state) . unwrap( ) , 14 ) ;
719- assert_eq ! ( eval_arith( & parse_arithmetic( "(2 + 3) * 4" ) . unwrap( ) , & state) . unwrap( ) , 20 ) ;
720- assert_eq ! ( eval_arith( & parse_arithmetic( "2 ** 3 + 1" ) . unwrap( ) , & state) . unwrap( ) , 9 ) ;
721- assert_eq ! ( eval_arith( & parse_arithmetic( "2 ** (3 + 1)" ) . unwrap( ) , & state) . unwrap( ) , 16 ) ;
744+ assert_eq ! (
745+ eval_arith( & parse_arithmetic( "2 + 3 * 4" ) . unwrap( ) , & state) . unwrap( ) ,
746+ 14
747+ ) ;
748+ assert_eq ! (
749+ eval_arith( & parse_arithmetic( "(2 + 3) * 4" ) . unwrap( ) , & state) . unwrap( ) ,
750+ 20
751+ ) ;
752+ assert_eq ! (
753+ eval_arith( & parse_arithmetic( "2 ** 3 + 1" ) . unwrap( ) , & state) . unwrap( ) ,
754+ 9
755+ ) ;
756+ assert_eq ! (
757+ eval_arith( & parse_arithmetic( "2 ** (3 + 1)" ) . unwrap( ) , & state) . unwrap( ) ,
758+ 16
759+ ) ;
722760 }
723761
724762 #[ test]
725763 fn test_arith_power_right_associative ( ) {
726764 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
727765
728766 // 2 ** 3 ** 2 = 2 ** (3 ** 2) = 2 ** 9 = 512
729- assert_eq ! ( eval_arith( & parse_arithmetic( "2 ** 3 ** 2" ) . unwrap( ) , & state) . unwrap( ) , 512 ) ;
767+ assert_eq ! (
768+ eval_arith( & parse_arithmetic( "2 ** 3 ** 2" ) . unwrap( ) , & state) . unwrap( ) ,
769+ 512
770+ ) ;
730771 }
731772
732773 #[ test]
733774 fn test_arith_comparison ( ) {
734775 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
735776
736- assert_eq ! ( eval_arith( & parse_arithmetic( "5 > 3" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
737- assert_eq ! ( eval_arith( & parse_arithmetic( "5 < 3" ) . unwrap( ) , & state) . unwrap( ) , 0 ) ;
738- assert_eq ! ( eval_arith( & parse_arithmetic( "5 == 5" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
739- assert_eq ! ( eval_arith( & parse_arithmetic( "5 != 3" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
740- assert_eq ! ( eval_arith( & parse_arithmetic( "5 >= 5" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
741- assert_eq ! ( eval_arith( & parse_arithmetic( "5 <= 4" ) . unwrap( ) , & state) . unwrap( ) , 0 ) ;
777+ assert_eq ! (
778+ eval_arith( & parse_arithmetic( "5 > 3" ) . unwrap( ) , & state) . unwrap( ) ,
779+ 1
780+ ) ;
781+ assert_eq ! (
782+ eval_arith( & parse_arithmetic( "5 < 3" ) . unwrap( ) , & state) . unwrap( ) ,
783+ 0
784+ ) ;
785+ assert_eq ! (
786+ eval_arith( & parse_arithmetic( "5 == 5" ) . unwrap( ) , & state) . unwrap( ) ,
787+ 1
788+ ) ;
789+ assert_eq ! (
790+ eval_arith( & parse_arithmetic( "5 != 3" ) . unwrap( ) , & state) . unwrap( ) ,
791+ 1
792+ ) ;
793+ assert_eq ! (
794+ eval_arith( & parse_arithmetic( "5 >= 5" ) . unwrap( ) , & state) . unwrap( ) ,
795+ 1
796+ ) ;
797+ assert_eq ! (
798+ eval_arith( & parse_arithmetic( "5 <= 4" ) . unwrap( ) , & state) . unwrap( ) ,
799+ 0
800+ ) ;
742801 }
743802
744803 #[ test]
745804 fn test_arith_logical ( ) {
746805 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
747806
748- assert_eq ! ( eval_arith( & parse_arithmetic( "1 && 1" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
749- assert_eq ! ( eval_arith( & parse_arithmetic( "1 && 0" ) . unwrap( ) , & state) . unwrap( ) , 0 ) ;
750- assert_eq ! ( eval_arith( & parse_arithmetic( "1 || 0" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
751- assert_eq ! ( eval_arith( & parse_arithmetic( "0 || 0" ) . unwrap( ) , & state) . unwrap( ) , 0 ) ;
752- assert_eq ! ( eval_arith( & parse_arithmetic( "!0" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
753- assert_eq ! ( eval_arith( & parse_arithmetic( "!5" ) . unwrap( ) , & state) . unwrap( ) , 0 ) ;
807+ assert_eq ! (
808+ eval_arith( & parse_arithmetic( "1 && 1" ) . unwrap( ) , & state) . unwrap( ) ,
809+ 1
810+ ) ;
811+ assert_eq ! (
812+ eval_arith( & parse_arithmetic( "1 && 0" ) . unwrap( ) , & state) . unwrap( ) ,
813+ 0
814+ ) ;
815+ assert_eq ! (
816+ eval_arith( & parse_arithmetic( "1 || 0" ) . unwrap( ) , & state) . unwrap( ) ,
817+ 1
818+ ) ;
819+ assert_eq ! (
820+ eval_arith( & parse_arithmetic( "0 || 0" ) . unwrap( ) , & state) . unwrap( ) ,
821+ 0
822+ ) ;
823+ assert_eq ! (
824+ eval_arith( & parse_arithmetic( "!0" ) . unwrap( ) , & state) . unwrap( ) ,
825+ 1
826+ ) ;
827+ assert_eq ! (
828+ eval_arith( & parse_arithmetic( "!5" ) . unwrap( ) , & state) . unwrap( ) ,
829+ 0
830+ ) ;
754831 }
755832
756833 #[ test]
757834 fn test_arith_bitwise ( ) {
758835 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
759836
760- assert_eq ! ( eval_arith( & parse_arithmetic( "5 & 3" ) . unwrap( ) , & state) . unwrap( ) , 1 ) ;
761- assert_eq ! ( eval_arith( & parse_arithmetic( "5 | 3" ) . unwrap( ) , & state) . unwrap( ) , 7 ) ;
762- assert_eq ! ( eval_arith( & parse_arithmetic( "5 ^ 3" ) . unwrap( ) , & state) . unwrap( ) , 6 ) ;
763- assert_eq ! ( eval_arith( & parse_arithmetic( "~5" ) . unwrap( ) , & state) . unwrap( ) , -6 ) ;
764- assert_eq ! ( eval_arith( & parse_arithmetic( "8 << 2" ) . unwrap( ) , & state) . unwrap( ) , 32 ) ;
765- assert_eq ! ( eval_arith( & parse_arithmetic( "8 >> 2" ) . unwrap( ) , & state) . unwrap( ) , 2 ) ;
837+ assert_eq ! (
838+ eval_arith( & parse_arithmetic( "5 & 3" ) . unwrap( ) , & state) . unwrap( ) ,
839+ 1
840+ ) ;
841+ assert_eq ! (
842+ eval_arith( & parse_arithmetic( "5 | 3" ) . unwrap( ) , & state) . unwrap( ) ,
843+ 7
844+ ) ;
845+ assert_eq ! (
846+ eval_arith( & parse_arithmetic( "5 ^ 3" ) . unwrap( ) , & state) . unwrap( ) ,
847+ 6
848+ ) ;
849+ assert_eq ! (
850+ eval_arith( & parse_arithmetic( "~5" ) . unwrap( ) , & state) . unwrap( ) ,
851+ -6
852+ ) ;
853+ assert_eq ! (
854+ eval_arith( & parse_arithmetic( "8 << 2" ) . unwrap( ) , & state) . unwrap( ) ,
855+ 32
856+ ) ;
857+ assert_eq ! (
858+ eval_arith( & parse_arithmetic( "8 >> 2" ) . unwrap( ) , & state) . unwrap( ) ,
859+ 2
860+ ) ;
766861 }
767862
768863 #[ test]
@@ -771,16 +866,25 @@ mod tests {
771866 state. set_variable ( "x" , "5" ) ;
772867 state. set_variable ( "y" , "10" ) ;
773868
774- assert_eq ! ( eval_arith( & parse_arithmetic( "x + y" ) . unwrap( ) , & state) . unwrap( ) , 15 ) ;
775- assert_eq ! ( eval_arith( & parse_arithmetic( "x * 2 + y" ) . unwrap( ) , & state) . unwrap( ) , 20 ) ;
869+ assert_eq ! (
870+ eval_arith( & parse_arithmetic( "x + y" ) . unwrap( ) , & state) . unwrap( ) ,
871+ 15
872+ ) ;
873+ assert_eq ! (
874+ eval_arith( & parse_arithmetic( "x * 2 + y" ) . unwrap( ) , & state) . unwrap( ) ,
875+ 20
876+ ) ;
776877 }
777878
778879 #[ test]
779880 fn test_arith_undefined_variable ( ) {
780881 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
781882
782883 // Undefined variables should be treated as 0
783- assert_eq ! ( eval_arith( & parse_arithmetic( "undefined_var + 5" ) . unwrap( ) , & state) . unwrap( ) , 5 ) ;
884+ assert_eq ! (
885+ eval_arith( & parse_arithmetic( "undefined_var + 5" ) . unwrap( ) , & state) . unwrap( ) ,
886+ 5
887+ ) ;
784888 }
785889
786890 #[ test]
@@ -795,24 +899,45 @@ mod tests {
795899 fn test_arith_nested ( ) {
796900 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
797901
798- assert_eq ! ( eval_arith( & parse_arithmetic( "((5 + 3) * 2) + 1" ) . unwrap( ) , & state) . unwrap( ) , 17 ) ;
799- assert_eq ! ( eval_arith( & parse_arithmetic( "2 ** (3 ** 2)" ) . unwrap( ) , & state) . unwrap( ) , 512 ) ;
902+ assert_eq ! (
903+ eval_arith( & parse_arithmetic( "((5 + 3) * 2) + 1" ) . unwrap( ) , & state) . unwrap( ) ,
904+ 17
905+ ) ;
906+ assert_eq ! (
907+ eval_arith( & parse_arithmetic( "2 ** (3 ** 2)" ) . unwrap( ) , & state) . unwrap( ) ,
908+ 512
909+ ) ;
800910 }
801911
802912 #[ test]
803913 fn test_arith_unary_minus ( ) {
804914 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
805915
806- assert_eq ! ( eval_arith( & parse_arithmetic( "-5" ) . unwrap( ) , & state) . unwrap( ) , -5 ) ;
807- assert_eq ! ( eval_arith( & parse_arithmetic( "-(5 + 3)" ) . unwrap( ) , & state) . unwrap( ) , -8 ) ;
808- assert_eq ! ( eval_arith( & parse_arithmetic( "10 + -5" ) . unwrap( ) , & state) . unwrap( ) , 5 ) ;
916+ assert_eq ! (
917+ eval_arith( & parse_arithmetic( "-5" ) . unwrap( ) , & state) . unwrap( ) ,
918+ -5
919+ ) ;
920+ assert_eq ! (
921+ eval_arith( & parse_arithmetic( "-(5 + 3)" ) . unwrap( ) , & state) . unwrap( ) ,
922+ -8
923+ ) ;
924+ assert_eq ! (
925+ eval_arith( & parse_arithmetic( "10 + -5" ) . unwrap( ) , & state) . unwrap( ) ,
926+ 5
927+ ) ;
809928 }
810929
811930 #[ test]
812931 fn test_arith_whitespace ( ) {
813932 let state = ShellState :: new ( "/tmp" ) . unwrap ( ) ;
814933
815- assert_eq ! ( eval_arith( & parse_arithmetic( " 5 + 3 " ) . unwrap( ) , & state) . unwrap( ) , 8 ) ;
816- assert_eq ! ( eval_arith( & parse_arithmetic( "( ( 5 + 3 ) * 2 )" ) . unwrap( ) , & state) . unwrap( ) , 16 ) ;
934+ assert_eq ! (
935+ eval_arith( & parse_arithmetic( " 5 + 3 " ) . unwrap( ) , & state) . unwrap( ) ,
936+ 8
937+ ) ;
938+ assert_eq ! (
939+ eval_arith( & parse_arithmetic( "( ( 5 + 3 ) * 2 )" ) . unwrap( ) , & state) . unwrap( ) ,
940+ 16
941+ ) ;
817942 }
818943}
0 commit comments