diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 05ffe94..2699c12 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -915,7 +915,7 @@ impl<'a> Parser<'a> { } let loc = self.map.look_up_span(message.span); eprintln!( - "{}:{} Debug: {}", + "{}:{} DEBUG: {}", loc.file.name(), loc.begin.line + 1, message.node diff --git a/src/value/number/mod.rs b/src/value/number/mod.rs index e836e35..1662898 100644 --- a/src/value/number/mod.rs +++ b/src/value/number/mod.rs @@ -711,6 +711,10 @@ impl DivAssign for Number { } } +fn modulo(n1: BigRational, n2: BigRational) -> BigRational { + (n1 % n2.clone() + n2.clone()) % n2 +} + impl Rem for Number { type Output = Self; @@ -721,25 +725,29 @@ impl Rem for Number { Self::Small(val2) => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = val2.into(); - Self::Big(Box::new( - BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) - % BigRational::new_raw(BigInt::from(tuple2.0), BigInt::from(tuple2.1)), - )) + + Self::Big(Box::new(modulo( + BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)), + BigRational::new_raw(BigInt::from(tuple2.0), BigInt::from(tuple2.1)), + ))) } Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big(Box::new( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) % *val2, - )) + + Self::Big(Box::new(modulo( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + *val2, + ))) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(Box::new(*val1 % *val2)), + Self::Big(val2) => Self::Big(Box::new(modulo(*val1, *val2))), Self::Small(val2) => { let tuple: (i64, i64) = val2.into(); - Self::Big(Box::new( - *val1 % BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - )) + Self::Big(Box::new(modulo( + *val1, + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + ))) } }, } diff --git a/tests/modulo.rs b/tests/modulo.rs index fb9abb8..87ee618 100644 --- a/tests/modulo.rs +++ b/tests/modulo.rs @@ -65,3 +65,23 @@ error!( positive_unit_mod_zero_unit_incompatible_units, "a {\n color: 1rem % 0px;\n}\n", "Error: Incompatible units rem and px." ); +test!( + positive_mod_negative, + "a {\n color: 1 % -4;\n}\n", + "a {\n color: -3;\n}\n" +); +test!( + negative_mod_positive, + "a {\n color: -4 % 3;\n}\n", + "a {\n color: 2;\n}\n" +); +test!( + negative_mod_negative, + "a {\n color: -4 % -3;\n}\n", + "a {\n color: -1;\n}\n" +); +test!( + big_negative_mod_positive, + "a {\n color: -99999990000099999999999999 % 2;\n}\n", + "a {\n color: 1;\n}\n" +);