From f08ae95b9d8be5165f9c8cac4c755d0510c3a18a Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 19 Apr 2023 17:51:33 +0200 Subject: Fix argument sinks Fixes #886. --- src/eval/args.rs | 21 +++++++++++++++------ src/eval/scope.rs | 8 ++++---- src/syntax/parser.rs | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/eval/args.rs b/src/eval/args.rs index 8617bd93..bea2baa1 100644 --- a/src/eval/args.rs +++ b/src/eval/args.rs @@ -62,14 +62,23 @@ impl Args { } /// Consume n positional arguments if possible. - pub fn consume(&mut self, n: usize) -> SourceResult> { - if n > self.items.len() { + pub fn consume(&mut self, n: usize) -> SourceResult> { + let mut list = vec![]; + + let mut i = 0; + while i < self.items.len() && list.len() < n { + if self.items[i].name.is_none() { + list.push(self.items.remove(i)); + } else { + i += 1; + } + } + + if list.len() < n { bail!(self.span, "not enough arguments"); } - let vec = self.items.to_vec(); - let (left, right) = vec.split_at(n); - self.items = right.into(); - Ok(left.into()) + + Ok(list) } /// Consume and cast the first positional argument. diff --git a/src/eval/scope.rs b/src/eval/scope.rs index f2207188..76633bf2 100644 --- a/src/eval/scope.rs +++ b/src/eval/scope.rs @@ -38,20 +38,20 @@ impl<'a> Scopes<'a> { /// Try to access a variable immutably. pub fn get(&self, var: &str) -> StrResult<&Value> { - Ok(std::iter::once(&self.top) + std::iter::once(&self.top) .chain(self.scopes.iter().rev()) .chain(self.base.map(|base| base.global.scope())) .find_map(|scope| scope.get(var)) - .ok_or(eco_format!("unknown variable: {}", var))?) + .ok_or_else(|| eco_format!("unknown variable: {}", var)) } /// Try to access a variable immutably in math. pub fn get_in_math(&self, var: &str) -> StrResult<&Value> { - Ok(std::iter::once(&self.top) + std::iter::once(&self.top) .chain(self.scopes.iter().rev()) .chain(self.base.map(|base| base.math.scope())) .find_map(|scope| scope.get(var)) - .ok_or(eco_format!("unknown variable: {}", var))?) + .ok_or_else(|| eco_format!("unknown variable: {}", var)) } /// Try to access a variable mutably. diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs index 4bc25a30..801fdfc8 100644 --- a/src/syntax/parser.rs +++ b/src/syntax/parser.rs @@ -1047,7 +1047,7 @@ fn validate_dict(p: &mut Parser, m: Marker) { }; if !used.insert(key.clone()) { - first.convert_to_error(eco_format!("duplicate key: {}", key)); + first.convert_to_error(eco_format!("duplicate key: {key}")); child.make_erroneous(); } } -- cgit v1.2.3