diff --git a/src/value/mod.rs b/src/value/mod.rs index 005debf..d6bcc0d 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -160,6 +160,7 @@ impl Value { Op::Rem => *lhs % *rhs, _ => Ok(Self::BinaryOp(lhs, op, rhs)), }, + Self::Paren(v) => v.eval(), _ => Ok(self), } } diff --git a/src/value/ops.rs b/src/value/ops.rs index 447bf85..a7d5df2 100644 --- a/src/value/ops.rs +++ b/src/value/ops.rs @@ -50,6 +50,9 @@ impl Add for Value { Value::Ident(format!("{}{}{}", num, unit, s), quotes) } Self::Null => Value::Ident(format!("{}{}", num, unit), QuoteKind::None), + Self::List(..) => { + Value::Ident(format!("{}{}{}", num, unit, other), QuoteKind::None) + } _ => { return Err( format!("Undefined operation \"{}{} + {}\".", num, unit, other).into(), @@ -64,9 +67,10 @@ impl Add for Value { Value::Ident(format!("{}{}", c, s), QuoteKind::None) } Self::Null => Value::Ident(c.to_string(), QuoteKind::None), + Self::List(..) => Value::Ident(format!("{}{}", c, other), QuoteKind::None), _ => return Err(format!("Undefined operation \"{} + {}\".", c, other).into()), }, - Self::BinaryOp(..) | Self::Paren(..) => self.eval()?, + Self::BinaryOp(..) | Self::Paren(..) => (self.eval()? + other)?, Self::Ident(s1, quotes1) => match other { Self::Ident(s2, quotes2) => { let quotes = match (quotes1, quotes2) { @@ -99,9 +103,20 @@ impl Add for Value { }; Value::Ident(format!("{}{}", s1, c), quotes) } - Self::BinaryOp(..) | Self::Paren(..) | Self::List(..) => todo!(), + Self::List(..) => Value::Ident(format!("{}{}", s1, other), quotes1), + Self::BinaryOp(..) | Self::Paren(..) => todo!(), }, - _ => todo!(), + Self::List(..) => match other { + Self::Ident(s, q) => { + let quotes = match q { + QuoteKind::Double | QuoteKind::Single => QuoteKind::Double, + QuoteKind::None => QuoteKind::None, + }; + Value::Ident(format!("{}{}", self, s), quotes) + } + Self::Paren(..) => (self + other.eval()?)?, + _ => Value::Ident(format!("{}{}", self, other), QuoteKind::None), + } }) } } @@ -133,6 +148,9 @@ impl Sub for Value { ) } } + Self::List(..) => { + Value::Ident(format!("{}{}-{}", num, unit, other), QuoteKind::None) + } _ => todo!(), }, Self::Color(c) => match other { @@ -149,7 +167,7 @@ impl Sub for Value { } _ => Value::Ident(format!("{}-{}", c, other), QuoteKind::None), }, - Self::BinaryOp(..) | Self::Paren(..) => self.eval()?, + Self::BinaryOp(..) | Self::Paren(..) => (self.eval()? - other)?, Self::Ident(s1, quotes1) => match other { Self::Ident(s2, quotes2) => { let quotes1 = match quotes1 { @@ -186,8 +204,26 @@ impl Sub for Value { }; Value::Ident(format!("{}{}{}-", quotes, s1, quotes), QuoteKind::None) } + Self::List(..) => { + let quotes = match quotes1 { + QuoteKind::Double | QuoteKind::Single => QuoteKind::Double, + QuoteKind::None => QuoteKind::None, + }; + Value::Ident(format!("{}{}{}-{}", quotes, s1, quotes, other), QuoteKind::None) + } _ => todo!(), }, + Self::List(..) => match other { + Self::Ident(s, q) => { + let quotes = match q { + QuoteKind::Double | QuoteKind::Single => QuoteKind::Double, + QuoteKind::None => QuoteKind::None, + }; + Value::Ident(format!("{}-{}{}{}", self, quotes, s, quotes), QuoteKind::None) + } + Self::Paren(..) => (self + other.eval()?)?, + _ => Value::Ident(format!("{}-{}", self, other), QuoteKind::None), + } _ => match other { Self::Ident(s, quotes) => { let quotes = match quotes { diff --git a/tests/values.rs b/tests/values.rs index 02548d2..5956b61 100644 --- a/tests/values.rs +++ b/tests/values.rs @@ -326,12 +326,11 @@ test!( "a {\n color: 1 + null;\n}\n", "a {\n color: 1;\n}\n" ); -// blocked on proper parsing of binary ops -// test!( -// unitless_plus_null_plus_unitless, -// "a {\n color: 1 + null + 1;\n}\n", -// "a {\n color: 11;\n}\n" -// ); +test!( + unitless_plus_null_plus_unitless, + "a {\n color: 1 + null + 1;\n}\n", + "a {\n color: 11;\n}\n" +); test!( unit_plus_null, "a {\n color: 1px + null;\n}\n", @@ -388,3 +387,79 @@ test!( "a {\n color: foo + 1 + bar + 2;\n}\n", "a {\n color: foo1bar2;\n}\n" ); +test!( + many_parens, + "a {\n color: (((((red)))));\n}\n", + "a {\n color: red;\n}\n" +); + +test!( + num_plus_list, + "a {\n color: 1 + (2 3);\n}\n", + "a {\n color: 12 3;\n}\n" +); +test!( + list_plus_num, + "a {\n color: (1 2) + 3;\n}\n", + "a {\n color: 1 23;\n}\n" +); +test!( + num_minus_list, + "a {\n color: 1 - (2 3);\n}\n", + "a {\n color: 1-2 3;\n}\n" +); +test!( + list_minus_num, + "a {\n color: (1 2) - 3;\n}\n", + "a {\n color: 1 2-3;\n}\n" +); +test!( + dblquoted_plus_list, + "a {\n color: \"1\" + (2 3);\n}\n", + "a {\n color: \"12 3\";\n}\n" +); +test!( + list_plus_dblquoted, + "a {\n color: (1 2) + \"3\";\n}\n", + "a {\n color: \"1 23\";\n}\n" +); +test!( + dblquoted_minus_list, + "a {\n color: \"1\" - (2 3);\n}\n", + "a {\n color: \"1\"-2 3;\n}\n" +); +test!( + list_minus_dblquoted, + "a {\n color: (1 2) - \"3\";\n}\n", + "a {\n color: 1 2-\"3\";\n}\n" +); +test!( + sglquoted_plus_list, + "a {\n color: 'a' + (b c);\n}\n", + "a {\n color: \"ab c\";\n}\n" +); +test!( + list_plus_sglquoted, + "a {\n color: (b c) + 'a';\n}\n", + "a {\n color: \"b ca\";\n}\n" +); +test!( + sglquoted_minus_list, + "a {\n color: 'a' - (b c);\n}\n", + "a {\n color: \"a\"-b c;\n}\n" +); +test!( + list_minus_sglquoted, + "a {\n color: (b c) - 'a';\n}\n", + "a {\n color: b c-\"a\";\n}\n" +); +test!( + list_plus_list, + "a {\n color: (a b) + (1 2);\n}\n", + "a {\n color: a b1 2;\n}\n" +); +test!( + list_minus_list, + "a {\n color: (a b) - (1 2);\n}\n", + "a {\n color: a b-1 2;\n}\n" +);