@@ -495,11 +495,6 @@ pub enum ArithmeticPart {
495495 operator : UnaryArithmeticOp ,
496496 operand : Box < ArithmeticPart > ,
497497 } ,
498- #[ error( "Invalid post arithmetic expression" ) ]
499- PostArithmeticExpr {
500- operand : Box < ArithmeticPart > ,
501- operator : PostArithmeticOp ,
502- } ,
503498 #[ error( "Invalid variable" ) ]
504499 Variable ( String ) ,
505500 #[ error( "Invalid number" ) ]
@@ -545,7 +540,9 @@ pub enum AssignmentOp {
545540#[ cfg_attr( feature = "serialization" , derive( serde:: Serialize ) ) ]
546541#[ cfg_attr( feature = "serialization" , serde( rename_all = "camelCase" ) ) ]
547542#[ derive( Debug , Clone , PartialEq , Eq , Copy ) ]
548- pub enum UnaryArithmeticOp {
543+ pub enum PreArithmeticOp {
544+ Increment , // ++
545+ Decrement , // --
549546 Plus , // +
550547 Minus , // -
551548 LogicalNot , // !
@@ -554,12 +551,20 @@ pub enum UnaryArithmeticOp {
554551
555552#[ cfg_attr( feature = "serialization" , derive( serde:: Serialize ) ) ]
556553#[ cfg_attr( feature = "serialization" , serde( rename_all = "camelCase" ) ) ]
557- #[ derive( Debug , Clone , PartialEq , Eq ) ]
554+ #[ derive( Debug , Clone , PartialEq , Eq , Copy ) ]
558555pub enum PostArithmeticOp {
559556 Increment , // ++
560557 Decrement , // --
561558}
562559
560+ #[ cfg_attr( feature = "serialization" , derive( serde:: Serialize ) ) ]
561+ #[ cfg_attr( feature = "serialization" , serde( rename_all = "camelCase" ) ) ]
562+ #[ derive( Debug , Clone , PartialEq , Eq , Copy ) ]
563+ pub enum UnaryArithmeticOp {
564+ Pre ( PreArithmeticOp ) ,
565+ Post ( PostArithmeticOp ) ,
566+ }
567+
563568#[ cfg_attr( feature = "serialization" , derive( serde:: Serialize ) ) ]
564569#[ cfg_attr(
565570 feature = "serialization" ,
@@ -1791,56 +1796,151 @@ fn parse_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
17911796
17921797fn parse_unary_arithmetic_expr ( pair : Pair < Rule > ) -> Result < ArithmeticPart > {
17931798 let mut inner = pair. into_inner ( ) ;
1794- let first = inner. next ( ) . unwrap ( ) ;
1799+ let first = inner
1800+ . next ( )
1801+ . ok_or_else ( || miette ! ( "Expected unary operator" ) ) ?;
1802+
1803+ match first. as_rule ( ) {
1804+ Rule :: unary_pre_arithmetic_expr => unary_pre_arithmetic_expr ( first) ,
1805+ Rule :: unary_post_arithmetic_expr => unary_post_arithmetic_expr ( first) ,
1806+ _ => Err ( miette ! (
1807+ "Unexpected rule in unary arithmetic expression: {:?}" ,
1808+ first. as_rule( )
1809+ ) ) ,
1810+ }
1811+ }
1812+
1813+ fn unary_pre_arithmetic_expr ( pair : Pair < Rule > ) -> Result < ArithmeticPart > {
1814+ let mut inner = pair. into_inner ( ) ;
1815+ let first = inner
1816+ . next ( )
1817+ . ok_or_else ( || miette ! ( "Expected unary pre operator" ) ) ?;
1818+ let second = inner. next ( ) . ok_or_else ( || miette ! ( "Expected operand" ) ) ?;
1819+ let operand = match second. as_rule ( ) {
1820+ Rule :: parentheses_expr => {
1821+ let inner = second
1822+ . into_inner ( )
1823+ . next ( )
1824+ . ok_or_else ( || miette ! ( "Expected expression in parentheses" ) ) ?;
1825+ let parts = parse_arithmetic_sequence ( inner) ?;
1826+ Ok ( ArithmeticPart :: ParenthesesExpr ( Box :: new ( Arithmetic {
1827+ parts,
1828+ } ) ) )
1829+ }
1830+ Rule :: VARIABLE => {
1831+ Ok ( ArithmeticPart :: Variable ( second. as_str ( ) . to_string ( ) ) )
1832+ }
1833+ Rule :: NUMBER => Ok ( ArithmeticPart :: Number ( second. as_str ( ) . to_string ( ) ) ) ,
1834+ _ => Err ( miette ! (
1835+ "Unexpected rule in arithmetic expression: {:?}" ,
1836+ second. as_rule( )
1837+ ) ) ,
1838+ } ?;
17951839
17961840 match first. as_rule ( ) {
1797- Rule :: unary_arithmetic_op => {
1798- let op = parse_unary_arithmetic_op ( first) ?;
1799- let operand = parse_arithmetic_expr ( inner. next ( ) . unwrap ( ) ) ?;
1841+ Rule :: pre_arithmetic_op => {
1842+ let op = parse_pre_arithmetic_op ( first) ?;
1843+ // Validate that increment/decrement are only applied to variables or expressions
1844+ if matches ! (
1845+ op,
1846+ PreArithmeticOp :: Increment | PreArithmeticOp :: Decrement
1847+ ) && matches ! ( operand, ArithmeticPart :: Number ( _) )
1848+ {
1849+ return Err ( miette ! (
1850+ "Increment/decrement operators cannot be applied to literal numbers"
1851+ ) ) ;
1852+ }
18001853 Ok ( ArithmeticPart :: UnaryArithmeticExpr {
1801- operator : op ,
1854+ operator : UnaryArithmeticOp :: Pre ( op ) ,
18021855 operand : Box :: new ( operand) ,
18031856 } )
18041857 }
18051858 Rule :: post_arithmetic_op => {
1806- let operand = parse_arithmetic_expr ( inner. next ( ) . unwrap ( ) ) ?;
18071859 let op = parse_post_arithmetic_op ( first) ?;
1808- Ok ( ArithmeticPart :: PostArithmeticExpr {
1860+ Ok ( ArithmeticPart :: UnaryArithmeticExpr {
1861+ operator : UnaryArithmeticOp :: Post ( op) ,
18091862 operand : Box :: new ( operand) ,
1810- operator : op,
18111863 } )
18121864 }
1813- _ => {
1814- let operand = parse_arithmetic_expr ( first) ?;
1815- let op = parse_post_arithmetic_op ( inner. next ( ) . unwrap ( ) ) ?;
1816- Ok ( ArithmeticPart :: PostArithmeticExpr {
1817- operand : Box :: new ( operand) ,
1818- operator : op,
1819- } )
1865+ _ => Err ( miette ! (
1866+ "Unexpected rule in unary arithmetic operator: {:?}" ,
1867+ first. as_rule( )
1868+ ) ) ,
1869+ }
1870+ }
1871+
1872+ fn unary_post_arithmetic_expr ( pair : Pair < Rule > ) -> Result < ArithmeticPart > {
1873+ let mut inner = pair. into_inner ( ) ;
1874+ let first = inner
1875+ . next ( )
1876+ . ok_or_else ( || miette ! ( "Expected unary post operator" ) ) ?;
1877+ let second = inner. next ( ) . ok_or_else ( || miette ! ( "Expected operand" ) ) ?;
1878+
1879+ let operand = match first. as_rule ( ) {
1880+ Rule :: parentheses_expr => {
1881+ let inner = first
1882+ . into_inner ( )
1883+ . next ( )
1884+ . ok_or_else ( || miette ! ( "Expected expression in parentheses" ) ) ?;
1885+ let parts = parse_arithmetic_sequence ( inner) ?;
1886+ Ok ( ArithmeticPart :: ParenthesesExpr ( Box :: new ( Arithmetic {
1887+ parts,
1888+ } ) ) )
1889+ }
1890+ Rule :: VARIABLE => {
1891+ Ok ( ArithmeticPart :: Variable ( first. as_str ( ) . to_string ( ) ) )
18201892 }
1893+ Rule :: NUMBER => Ok ( ArithmeticPart :: Number ( first. as_str ( ) . to_string ( ) ) ) ,
1894+ _ => Err ( miette ! (
1895+ "Unexpected rule in arithmetic expression: {:?}" ,
1896+ first. as_rule( )
1897+ ) ) ,
1898+ } ?;
1899+
1900+ // Validate that increment/decrement are only applied to variables or expressions
1901+ if matches ! ( operand, ArithmeticPart :: Number ( _) ) {
1902+ return Err ( miette ! (
1903+ "Increment/decrement operators cannot be applied to literal numbers"
1904+ ) ) ;
18211905 }
1906+
1907+ let op = parse_post_arithmetic_op ( second) ?;
1908+ Ok ( ArithmeticPart :: UnaryArithmeticExpr {
1909+ operator : UnaryArithmeticOp :: Post ( op) ,
1910+ operand : Box :: new ( operand) ,
1911+ } )
18221912}
18231913
1824- fn parse_unary_arithmetic_op ( pair : Pair < Rule > ) -> Result < UnaryArithmeticOp > {
1825- match pair. as_str ( ) {
1826- "+" => Ok ( UnaryArithmeticOp :: Plus ) ,
1827- "-" => Ok ( UnaryArithmeticOp :: Minus ) ,
1828- "!" => Ok ( UnaryArithmeticOp :: LogicalNot ) ,
1829- "~" => Ok ( UnaryArithmeticOp :: BitwiseNot ) ,
1914+ fn parse_pre_arithmetic_op ( pair : Pair < Rule > ) -> Result < PreArithmeticOp > {
1915+ let first = pair
1916+ . into_inner ( )
1917+ . next ( )
1918+ . ok_or_else ( || miette ! ( "Expected increment or decrement operator" ) ) ?;
1919+ match first. as_rule ( ) {
1920+ Rule :: increment => Ok ( PreArithmeticOp :: Increment ) ,
1921+ Rule :: decrement => Ok ( PreArithmeticOp :: Decrement ) ,
1922+ Rule :: unary_plus => Ok ( PreArithmeticOp :: Plus ) ,
1923+ Rule :: unary_minus => Ok ( PreArithmeticOp :: Minus ) ,
1924+ Rule :: logical_not => Ok ( PreArithmeticOp :: LogicalNot ) ,
1925+ Rule :: bitwise_not => Ok ( PreArithmeticOp :: BitwiseNot ) ,
18301926 _ => Err ( miette ! (
1831- "Invalid unary arithmetic operator: {}" ,
1832- pair . as_str ( )
1927+ "Unexpected rule in pre arithmetic operator: {:? }" ,
1928+ first . as_rule ( )
18331929 ) ) ,
18341930 }
18351931}
18361932
18371933fn parse_post_arithmetic_op ( pair : Pair < Rule > ) -> Result < PostArithmeticOp > {
1838- match pair. as_str ( ) {
1839- "++" => Ok ( PostArithmeticOp :: Increment ) ,
1840- "--" => Ok ( PostArithmeticOp :: Decrement ) ,
1934+ let first = pair
1935+ . into_inner ( )
1936+ . next ( )
1937+ . ok_or_else ( || miette ! ( "Expected increment or decrement operator" ) ) ?;
1938+ match first. as_rule ( ) {
1939+ Rule :: increment => Ok ( PostArithmeticOp :: Increment ) ,
1940+ Rule :: decrement => Ok ( PostArithmeticOp :: Decrement ) ,
18411941 _ => Err ( miette ! (
1842- "Invalid post arithmetic operator: {}" ,
1843- pair . as_str ( )
1942+ "Unexpected rule in post arithmetic operator: {:? }" ,
1943+ first . as_rule ( )
18441944 ) ) ,
18451945 }
18461946}
0 commit comments