diff --git a/src/main.rs b/src/main.rs index 9f3312e..797c45f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,10 +51,9 @@ use crate::common::{AtRule, Keyword, Op, Pos, Printer, Scope, Symbol, Whitespace use crate::css::Css; use crate::error::SassError; use crate::format::PrettyPrinter; -use crate::function::{eat_call_args, CallArgs}; use crate::imports::import; use crate::lexer::Lexer; -use crate::mixin::Mixin; +use crate::mixin::{eat_include, Mixin}; use crate::selector::{Attribute, Selector}; use crate::style::Style; use crate::units::Unit; @@ -431,56 +430,6 @@ impl<'a> StyleSheetParser<'a> { } } -fn eat_include>( - toks: &mut Peekable, - scope: &Scope, - super_selector: &Selector, -) -> Result, (Pos, &'static str)> { - toks.next(); - devour_whitespace(toks); - let Token { kind, pos } = toks - .next() - .expect("this must exist because we have already peeked"); - let name = if let TokenKind::Ident(s) = kind { - s - } else { - return Err((pos, "expected identifier")); - }; - - devour_whitespace(toks); - - let args = match toks.next() { - Some(Token { - kind: TokenKind::Symbol(Symbol::SemiColon), - .. - }) => CallArgs::new(), - Some(Token { - kind: TokenKind::Symbol(Symbol::OpenParen), - .. - }) => eat_call_args(toks), - Some(Token { pos, .. }) => return Err((pos, "expected `(` or `;`")), - None => return Err((pos, "unexpected EOF")), - }; - - devour_whitespace(toks); - - if !args.is_empty() { - if let Some(tok) = toks.next() { - assert_eq!(tok.kind, TokenKind::Symbol(Symbol::SemiColon)); - } - } - - devour_whitespace(toks); - - let mixin = if let Some(m) = scope.mixins.get(&name) { - m.clone() - } else { - return Err((pos, "expected identifier")); - }; - let rules = mixin.args(&args).call(super_selector)?; - Ok(rules) -} - fn eat_at_rule>( rule: &AtRule, pos: Pos, diff --git a/src/mixin.rs b/src/mixin.rs index 5e21bee..b3ffab3 100644 --- a/src/mixin.rs +++ b/src/mixin.rs @@ -2,7 +2,7 @@ use std::iter::Peekable; use std::vec::IntoIter; use crate::common::{Pos, Printer, Scope, Symbol}; -use crate::function::{eat_func_args, CallArgs, FuncArgs}; +use crate::function::{eat_call_args, eat_func_args, CallArgs, FuncArgs}; use crate::selector::Selector; use crate::utils::devour_whitespace; use crate::{eat_expr, Expr, RuleSet, Stmt, Token, TokenKind}; @@ -99,7 +99,7 @@ impl Mixin { pub fn eval(&mut self, super_selector: &Selector) -> Result, (Pos, &'static str)> { let mut stmts = Vec::new(); - while let Some(expr) = eat_expr(&mut self.body, &mut self.scope, super_selector)? { + while let Some(expr) = eat_expr(&mut self.body, &self.scope, super_selector)? { match expr { Expr::Style(s) => stmts.push(Stmt::Style(s)), Expr::Include(_) | Expr::MixinDecl(_, _) => todo!(), @@ -120,3 +120,49 @@ impl Mixin { Ok(stmts) } } + +pub fn eat_include>( + toks: &mut Peekable, + scope: &Scope, + super_selector: &Selector, +) -> Result, (Pos, &'static str)> { + toks.next(); + devour_whitespace(toks); + let Token { kind, pos } = toks + .next() + .expect("this must exist because we have already peeked"); + let name = match kind { + TokenKind::Ident(s) => s, + _ => return Err((pos, "expected identifier")), + }; + + devour_whitespace(toks); + + let args = if let Some(tok) = toks.next() { + match tok.kind { + TokenKind::Symbol(Symbol::SemiColon) => CallArgs::new(), + TokenKind::Symbol(Symbol::OpenParen) => eat_call_args(toks), + _ => return Err((pos, "expected `(` or `;`")), + } + } else { + return Err((pos, "unexpected EOF")); + }; + + devour_whitespace(toks); + + if !args.is_empty() { + if let Some(tok) = toks.next() { + assert_eq!(tok.kind, TokenKind::Symbol(Symbol::SemiColon)); + } + } + + devour_whitespace(toks); + + let mixin = match scope.mixins.get(&name) { + Some(m) => m.clone(), + _ => return Err((pos, "expected identifier")), + }; + + let rules = mixin.args(&args).call(super_selector)?; + Ok(rules) +}