From 927faf30c623e81537b6a5e9874b02ee8162283a Mon Sep 17 00:00:00 2001 From: Connor Skees Date: Thu, 2 Jul 2020 16:32:43 -0400 Subject: [PATCH] eagerly evaluate call args --- src/args.rs | 11 +++++----- src/parse/args.rs | 56 +++++++++++++++++++---------------------------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/args.rs b/src/args.rs index 0314f1f..2ebb8cb 100644 --- a/src/args.rs +++ b/src/args.rs @@ -6,6 +6,7 @@ use crate::{ common::Identifier, error::SassResult, parse::Parser, + value::Value, {Cow, Token}, }; @@ -35,7 +36,7 @@ impl FuncArgs { } #[derive(Debug, Clone)] -pub(crate) struct CallArgs(pub HashMap>, pub Span); +pub(crate) struct CallArgs(pub HashMap>, pub Span); #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub(crate) enum CallArg { @@ -100,25 +101,25 @@ impl CallArgs { /// Get argument by name /// /// Removes the argument - pub fn get_named>(&mut self, val: T) -> Option> { + pub fn get_named>(&mut self, val: T) -> Option> { self.0.remove(&CallArg::Named(val.into())) } /// Get a positional argument by 0-indexed position /// /// Removes the argument - pub fn get_positional(&mut self, val: usize) -> Option> { + pub fn get_positional(&mut self, val: usize) -> Option> { self.0.remove(&CallArg::Positional(val)) } - pub fn get>(&mut self, position: usize, name: T) -> Option> { + pub fn get>(&mut self, position: usize, name: T) -> Option> { match self.get_named(name) { Some(v) => Some(v), None => self.get_positional(position), } } - pub fn get_err(&mut self, position: usize, name: &'static str) -> SassResult> { + pub fn get_err(&mut self, position: usize, name: &'static str) -> SassResult> { match self.get_named(name) { Some(v) => Ok(v), None => match self.get_positional(position) { diff --git a/src/parse/args.rs b/src/parse/args.rs index 1736934..9bd48d8 100644 --- a/src/parse/args.rs +++ b/src/parse/args.rs @@ -125,7 +125,7 @@ impl<'a> Parser<'a> { } pub(super) fn parse_call_args(&mut self) -> SassResult { - let mut args: HashMap> = HashMap::new(); + let mut args = HashMap::new(); self.whitespace_or_comment(); let mut name = String::new(); let mut val: Vec = Vec::new(); @@ -176,7 +176,10 @@ impl<'a> Parser<'a> { } else { CallArg::Named(name.into()) }, - val, + { + let val = self.parse_value_from_vec(val)?; + val.node.eval(val.span)? + }, ); span = span.merge(tok.pos()); return Ok(CallArgs(args, span)); @@ -204,7 +207,10 @@ impl<'a> Parser<'a> { } else { CallArg::Named(name.as_str().into()) }, - mem::take(&mut val), + { + let val = self.parse_value_from_vec(mem::take(&mut val))?; + val.node.eval(val.span)? + }, ); self.whitespace(); @@ -222,11 +228,7 @@ impl<'a> Parser<'a> { position: usize, name: &'static str, ) -> SassResult { - Ok(self - .parse_value_from_vec(args.get_err(position, name)?)? - .node - .eval(args.span())? - .node) + Ok(args.get_err(position, name)?.node) } pub fn default_arg( @@ -237,12 +239,7 @@ impl<'a> Parser<'a> { default: Value, ) -> SassResult { Ok(match args.get(position, name) { - Some(toks) => { - self.parse_value_from_vec(toks)? - .node - .eval(args.span())? - .node - } + Some(val) => val.node, None => default, }) } @@ -251,17 +248,13 @@ impl<'a> Parser<'a> { &mut self, args: &mut CallArgs, position: usize, - ) -> Option>> { - Some(self.parse_value_from_vec(args.get_positional(position)?)) + ) -> Option> { + args.get_positional(position) } #[allow(dead_code)] - fn named_arg( - &mut self, - args: &mut CallArgs, - name: &'static str, - ) -> Option>> { - Some(self.parse_value_from_vec(args.get_named(name)?)) + fn named_arg(&mut self, args: &mut CallArgs, name: &'static str) -> Option> { + args.get_named(name) } pub fn default_named_arg( @@ -271,31 +264,25 @@ impl<'a> Parser<'a> { default: Value, ) -> SassResult { Ok(match args.get_named(name) { - Some(toks) => { - self.parse_value_from_vec(toks)? - .node - .eval(args.span())? - .node - } + Some(val) => val.node, None => default, }) } pub fn variadic_args(&mut self, args: CallArgs) -> SassResult>> { let mut vals = Vec::new(); - let span = args.span(); let mut args = match args .0 .into_iter() .map(|(a, v)| Ok((a.position()?, v))) - .collect::)>, String>>() + .collect::)>, String>>() { Ok(v) => v, Err(e) => return Err((format!("No argument named ${}.", e), args.1).into()), }; args.sort_by(|(a1, _), (a2, _)| a1.cmp(a2)); for arg in args { - vals.push(self.parse_value_from_vec(arg.1)?.node.eval(span)?); + vals.push(arg.1); } Ok(vals) } @@ -322,9 +309,12 @@ impl<'a> Parser<'a> { break; } let val = match args.get(idx, arg.name.clone()) { - Some(v) => self.parse_value_from_vec(v)?, + Some(v) => v, None => match arg.default.as_mut() { - Some(v) => self.parse_value_from_vec(mem::take(v))?, + Some(v) => { + let val = self.parse_value_from_vec(mem::take(v))?; + val.node.eval(val.span)? + } None => { return Err( (format!("Missing argument ${}.", &arg.name), args.span()).into()