refactor function eval
This commit is contained in:
parent
a29d8aea7b
commit
38c45129d9
@ -9,7 +9,7 @@ use crate::atrule::AtRule;
|
|||||||
use crate::error::SassResult;
|
use crate::error::SassResult;
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
use crate::selector::Selector;
|
use crate::selector::Selector;
|
||||||
use crate::utils::{devour_whitespace, eat_ident};
|
use crate::utils::{devour_whitespace, eat_ident, read_until_closing_curly_brace};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{Stmt, Token};
|
use crate::{Stmt, Token};
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ use crate::{Stmt, Token};
|
|||||||
pub(crate) struct Function {
|
pub(crate) struct Function {
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
args: FuncArgs,
|
args: FuncArgs,
|
||||||
body: Vec<Spanned<Stmt>>,
|
body: Vec<Token>,
|
||||||
pos: Span,
|
pos: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl PartialEq for Function {
|
|||||||
impl Eq for Function {}
|
impl Eq for Function {}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn new(scope: Scope, args: FuncArgs, body: Vec<Spanned<Stmt>>, pos: Span) -> Self {
|
pub fn new(scope: Scope, args: FuncArgs, body: Vec<Token>, pos: Span) -> Self {
|
||||||
Function {
|
Function {
|
||||||
scope,
|
scope,
|
||||||
args,
|
args,
|
||||||
@ -54,18 +54,19 @@ impl Function {
|
|||||||
|
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
|
||||||
let body = eat_stmts(toks, &mut scope.clone(), super_selector)?;
|
let mut body = read_until_closing_curly_brace(toks); //eat_stmts(toks, &mut scope.clone(), super_selector)?;
|
||||||
|
body.push(toks.next().unwrap());
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
|
||||||
Ok((name, Function::new(scope, args, body, span)))
|
Ok((name, Function::new(scope, args, body, span)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn args(
|
pub fn args(
|
||||||
mut self,
|
&mut self,
|
||||||
mut args: CallArgs,
|
mut args: CallArgs,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
) -> SassResult<Function> {
|
) -> SassResult<()> {
|
||||||
for (idx, arg) in self.args.0.iter().enumerate() {
|
for (idx, arg) in self.args.0.iter().enumerate() {
|
||||||
if arg.is_variadic {
|
if arg.is_variadic {
|
||||||
let span = args.span();
|
let span = args.span();
|
||||||
@ -98,11 +99,26 @@ impl Function {
|
|||||||
};
|
};
|
||||||
self.scope.insert_var(&arg.name, val)?;
|
self.scope.insert_var(&arg.name, val)?;
|
||||||
}
|
}
|
||||||
Ok(self)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body(&self) -> Vec<Spanned<Stmt>> {
|
pub fn eval_body(&mut self, super_selector: &Selector) -> SassResult<Vec<Spanned<Stmt>>> {
|
||||||
self.body.clone()
|
eat_stmts(
|
||||||
|
&mut std::mem::take(&mut self.body).into_iter().peekmore(),
|
||||||
|
&mut self.scope,
|
||||||
|
super_selector,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval(
|
||||||
|
mut self,
|
||||||
|
args: CallArgs,
|
||||||
|
scope: &Scope,
|
||||||
|
super_selector: &Selector,
|
||||||
|
) -> SassResult<Value> {
|
||||||
|
self.args(args, scope, super_selector)?;
|
||||||
|
let stmts = self.eval_body(super_selector)?;
|
||||||
|
self.call(super_selector, stmts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(&self, super_selector: &Selector, stmts: Vec<Spanned<Stmt>>) -> SassResult<Value> {
|
pub fn call(&self, super_selector: &Selector, stmts: Vec<Spanned<Stmt>>) -> SassResult<Value> {
|
||||||
|
@ -551,12 +551,11 @@ impl Value {
|
|||||||
};
|
};
|
||||||
Ok(IntermediateValue::Value(
|
Ok(IntermediateValue::Value(
|
||||||
func.clone()
|
func.clone()
|
||||||
.args(
|
.eval(
|
||||||
eat_call_args(toks, scope, super_selector)?,
|
eat_call_args(toks, scope, super_selector)?,
|
||||||
scope,
|
scope,
|
||||||
super_selector,
|
super_selector,
|
||||||
)?
|
)?
|
||||||
.call(super_selector, func.body())?
|
|
||||||
.span(span),
|
.span(span),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -60,10 +60,7 @@ impl SassFunction {
|
|||||||
match self {
|
match self {
|
||||||
Self::Builtin(f, ..) => f.0(args, scope, super_selector),
|
Self::Builtin(f, ..) => f.0(args, scope, super_selector),
|
||||||
// todo: superselector
|
// todo: superselector
|
||||||
Self::UserDefined(f, ..) => f
|
Self::UserDefined(f, ..) => f.clone().eval(args, scope, super_selector),
|
||||||
.clone()
|
|
||||||
.args(args, scope, super_selector)?
|
|
||||||
.call(&Selector::new(), f.body()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,3 +78,8 @@ test!(
|
|||||||
"a {\n color: unquote(\"a, b, c, d\");\n}\n",
|
"a {\n color: unquote(\"a, b, c, d\");\n}\n",
|
||||||
"a {\n color: a, b, c, d;\n}\n"
|
"a {\n color: a, b, c, d;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
variable_declaration,
|
||||||
|
"@function str-replace($string, $search, $replace: \"\") {\n $index: $string;\n @return $index;\n}\n\na {\n color: str-replace(\"a#b#c\", \"#\", \":\");\n}",
|
||||||
|
"a {\n color: \"a#b#c\";\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user