From 63567da749bdf542128ad6d61f8122437b947a27 Mon Sep 17 00:00:00 2001 From: Connor Skees Date: Wed, 28 Jul 2021 00:35:49 -0400 Subject: [PATCH] more robustly parse commas in call args --- src/parse/args.rs | 13 ++++++++++++ src/parse/value/eval.rs | 20 +++++++++---------- tests/args.rs | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/parse/args.rs b/src/parse/args.rs index 1fa5a2b..f36cfdf 100644 --- a/src/parse/args.rs +++ b/src/parse/args.rs @@ -160,6 +160,16 @@ impl<'a, 'b> Parser<'a, 'b> { return Ok(CallArgs(args, span)); } + if self.consume_char_if_exists(',') { + self.whitespace_or_comment(); + + if self.consume_char_if_exists(',') { + return Err(("expected \")\".", self.span_before).into()); + } + + continue; + } + if let Some(Token { kind: '$', pos }) = self.toks.peek() { let start = self.toks.cursor(); @@ -222,6 +232,9 @@ impl<'a, 'b> Parser<'a, 'b> { value, ); self.whitespace_or_comment(); + if self.consume_char_if_exists(',') { + return Err(("expected \")\".", self.span_before).into()); + } continue; } Some(Token { kind: '.', pos }) => { diff --git a/src/parse/value/eval.rs b/src/parse/value/eval.rs index 3adbf03..3e7796f 100644 --- a/src/parse/value/eval.rs +++ b/src/parse/value/eval.rs @@ -79,13 +79,13 @@ impl<'a, 'b: 'a, 'c> ValueVisitor<'a, 'b, 'c> { op, Box::new(val2), )); - } else { - return Ok(HigherIntermediateValue::BinaryOp( - val1_1, - val1_op, - Box::new(self.bin_op_one_level(*val1_2, op, val2, in_parens)?), - )); } + + return Ok(HigherIntermediateValue::BinaryOp( + val1_1, + val1_op, + Box::new(self.bin_op_one_level(*val1_2, op, val2, in_parens)?), + )); } _ => unreachable!(), }; @@ -132,13 +132,13 @@ impl<'a, 'b: 'a, 'c> ValueVisitor<'a, 'b, 'c> { if let HigherIntermediateValue::BinaryOp(val1_1, val1_op, val1_2) = val1 { let in_parens = op != Op::Div || val1_op != Op::Div; - if val1_op.precedence() >= op.precedence() { + return if val1_op.precedence() >= op.precedence() { val1 = self.bin_op_one_level(*val1_1, val1_op, *val1_2, in_parens)?; - return self.bin_op(val1, op, val2, in_parens); + self.bin_op(val1, op, val2, in_parens) } else { val2 = self.bin_op_one_level(*val1_2, op, val2, in_parens)?; - return self.bin_op(*val1_1, val1_op, val2, in_parens); - } + self.bin_op(*val1_1, val1_op, val2, in_parens) + }; } Ok(match op { diff --git a/tests/args.rs b/tests/args.rs index 12d554e..e8c1124 100644 --- a/tests/args.rs +++ b/tests/args.rs @@ -231,3 +231,47 @@ test!( }", "a {\n color: foo;\n color: bar;\n color: foo;\n}\n" ); +test!( + splat_ends_with_comma, + "@function foo($arg1) { + @return $arg1; + } + + a { + color: foo(a...,); + }", + "a {\n color: a;\n}\n" +); +test!( + two_splat_ends_with_comma, + "@function foo($arg1, $arg2) { + @return $arg1 $arg2; + } + + a { + color: foo((value1,)..., (arg2: value2)...); + }", + "a {\n color: value1 value2;\n}\n" +); +error!( + splat_ends_with_two_commas, + "@function foo($arg1) { + @return $arg1; + } + + a { + color: foo(a...,,); + }", + "Error: expected \")\"." +); +error!( + arg_ends_with_two_commas, + "@function foo($arg1) { + @return $arg1; + } + + a { + color: foo(a,,); + }", + "Error: expected \")\"." +);