diff --git a/src/parse/args.rs b/src/parse/args.rs index e7ee5e8..1736934 100644 --- a/src/parse/args.rs +++ b/src/parse/args.rs @@ -5,6 +5,7 @@ use codemap::{Span, Spanned}; use crate::{ args::{CallArg, CallArgs, FuncArg, FuncArgs}, error::SassResult, + scope::Scope, utils::{read_until_closing_paren, read_until_closing_quote, read_until_closing_square_brace}, value::Value, Token, @@ -298,4 +299,45 @@ impl<'a> Parser<'a> { } Ok(vals) } + + pub(super) fn eval_args( + &mut self, + mut fn_args: FuncArgs, + mut args: CallArgs, + scope: &mut Scope, + ) -> SassResult<()> { + self.scopes.push(self.scopes.last().clone()); + for (idx, arg) in fn_args.0.iter_mut().enumerate() { + if arg.is_variadic { + let span = args.span(); + // todo: does this get the most recent scope? + let arg_list = Value::ArgList(self.variadic_args(args)?); + scope.insert_var( + arg.name.clone(), + Spanned { + node: arg_list, + span, + }, + )?; + break; + } + let val = match args.get(idx, arg.name.clone()) { + Some(v) => self.parse_value_from_vec(v)?, + None => match arg.default.as_mut() { + Some(v) => self.parse_value_from_vec(mem::take(v))?, + None => { + return Err( + (format!("Missing argument ${}.", &arg.name), args.span()).into() + ) + } + }, + }; + self.scopes + .last_mut() + .insert_var(arg.name.clone(), val.clone())?; + scope.insert_var(mem::take(&mut arg.name), val)?; + } + self.scopes.pop(); + Ok(()) + } } diff --git a/src/parse/function.rs b/src/parse/function.rs index f209dca..85da2fc 100644 --- a/src/parse/function.rs +++ b/src/parse/function.rs @@ -1,5 +1,3 @@ -use std::mem; - use codemap::Spanned; use peekmore::PeekMore; @@ -91,14 +89,21 @@ impl<'a> Parser<'a> { Ok(Box::new(v.node)) } - pub fn eval_function(&mut self, mut function: Function, args: CallArgs) -> SassResult { - self.eval_fn_args(&mut function, args)?; + pub fn eval_function(&mut self, function: Function, args: CallArgs) -> SassResult { + let Function { + mut scope, + body, + args: fn_args, + .. + } = function; + + self.eval_args(fn_args, args, &mut scope)?; let mut return_value = Parser { - toks: &mut function.body.into_iter().peekmore(), + toks: &mut body.into_iter().peekmore(), map: self.map, path: self.path, - scopes: &mut NeverEmptyVec::new(function.scope), + scopes: &mut NeverEmptyVec::new(scope), global_scope: self.global_scope, super_selectors: self.super_selectors, span_before: self.span_before, @@ -121,39 +126,4 @@ impl<'a> Parser<'a> { _ => todo!("should be unreachable"), } } - - fn eval_fn_args(&mut self, function: &mut Function, mut args: CallArgs) -> SassResult<()> { - self.scopes.push(self.scopes.last().clone()); - for (idx, arg) in function.args.0.iter_mut().enumerate() { - if arg.is_variadic { - let span = args.span(); - let arg_list = Value::ArgList(self.variadic_args(args)?); - function.scope.insert_var( - arg.name.clone(), - Spanned { - node: arg_list, - span, - }, - )?; - break; - } - let val = match args.get(idx, arg.name.clone()) { - Some(v) => self.parse_value_from_vec(v)?, - None => match arg.default.as_mut() { - Some(v) => self.parse_value_from_vec(mem::take(v))?, - None => { - return Err( - (format!("Missing argument ${}.", &arg.name), args.span()).into() - ) - } - }, - }; - self.scopes - .last_mut() - .insert_var(arg.name.clone(), val.clone())?; - function.scope.insert_var(mem::take(&mut arg.name), val)?; - } - self.scopes.pop(); - Ok(()) - } } diff --git a/src/parse/mixin.rs b/src/parse/mixin.rs index a82fae1..26e8866 100644 --- a/src/parse/mixin.rs +++ b/src/parse/mixin.rs @@ -1,5 +1,3 @@ -use std::mem; - use codemap::Spanned; use peekmore::PeekMore; @@ -8,9 +6,7 @@ use crate::{ args::{CallArgs, FuncArgs}, atrule::{Content, Mixin}, error::SassResult, - scope::Scope, utils::read_until_closing_curly_brace, - value::Value, Token, }; @@ -185,45 +181,4 @@ impl<'a> Parser<'a> { .into()) } } - - fn eval_args( - &mut self, - mut fn_args: FuncArgs, - mut args: CallArgs, - scope: &mut Scope, - ) -> SassResult<()> { - self.scopes.push(self.scopes.last().clone()); - for (idx, arg) in fn_args.0.iter_mut().enumerate() { - if arg.is_variadic { - let span = args.span(); - // todo: does this get the most recent scope? - let arg_list = Value::ArgList(self.variadic_args(args)?); - scope.insert_var( - arg.name.clone(), - Spanned { - node: arg_list, - span, - }, - )?; - break; - } - let val = match args.get(idx, arg.name.clone()) { - Some(v) => self.parse_value_from_vec(v)?, - None => match arg.default.as_mut() { - Some(v) => self.parse_value_from_vec(mem::take(v))?, - None => { - return Err( - (format!("Missing argument ${}.", &arg.name), args.span()).into() - ) - } - }, - }; - self.scopes - .last_mut() - .insert_var(arg.name.clone(), val.clone())?; - scope.insert_var(mem::take(&mut arg.name), val)?; - } - self.scopes.pop(); - Ok(()) - } }