From b28295d2b1f0c5c4b2a754c6bc8e9123be84c4cb Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 18 Jan 2020 19:54:47 -0500 Subject: [PATCH] Refactor mixin parsing into mixin.rs --- src/common.rs | 2 +- src/main.rs | 60 +++-------------------------------------------- src/mixin.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/common.rs b/src/common.rs index 19e165a..f74b9e4 100644 --- a/src/common.rs +++ b/src/common.rs @@ -489,7 +489,7 @@ impl Scope { } #[derive(Debug)] -pub(crate) enum Printer { +pub enum Printer { Error(Pos, String), Warn(Pos, String), Debug(Pos, String), diff --git a/src/main.rs b/src/main.rs index 6052b22..71dda26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -349,7 +349,7 @@ impl<'a> StyleSheetParser<'a> { } TokenKind::AtRule(AtRule::Mixin) => { let (name, mixin) = - parse_mixin(&mut self.lexer, self.global_scope.clone()).unwrap(); + Mixin::from_tokens(&mut self.lexer, &self.global_scope).unwrap(); self.global_scope.mixins.insert(name, mixin); } TokenKind::AtRule(_) => { @@ -469,60 +469,6 @@ fn eat_include>( Ok(rules) } -fn parse_mixin>( - toks: &mut Peekable, - scope: Scope, -) -> Result<(String, Mixin), Printer> { - let Token { pos, .. } = toks - .next() - .expect("this must exist because we have already peeked"); - devour_whitespace(toks); - let name = if let Some(Token { - kind: TokenKind::Ident(s), - .. - }) = toks.next() - { - s - } else { - return Err(Printer::Error( - pos, - String::from("expected identifier after mixin declaration"), - )); - }; - devour_whitespace(toks); - let args = match toks.next() { - Some(Token { - kind: TokenKind::Symbol(Symbol::OpenParen), - .. - }) => eat_func_args(toks), - Some(Token { - kind: TokenKind::Symbol(Symbol::OpenCurlyBrace), - .. - }) => FuncArgs::new(), - _ => return Err(Printer::Error(pos, String::from("expected `(` or `{`"))), - }; - - let mut nesting = 1; - let mut body = Vec::new(); - - while nesting > 0 { - if let Some(tok) = toks.next() { - match &tok.kind { - TokenKind::Symbol(Symbol::OpenCurlyBrace) - // interpolation token eats the opening brace but not the closing - | TokenKind::Interpolation => nesting += 1, - TokenKind::Symbol(Symbol::CloseCurlyBrace) => nesting -= 1, - _ => {} - } - body.push(tok) - } else { - return Err(Printer::Error(pos, String::from("unexpected EOF"))); - } - } - - Ok((name, Mixin::new(scope, args, body))) -} - fn eat_at_rule>( rule: &AtRule, pos: Pos, @@ -556,7 +502,7 @@ fn eat_at_rule>( Err(Printer::Debug(pos, message)) } AtRule::Mixin => { - let (name, mixin) = parse_mixin(toks, scope.clone())?; + let (name, mixin) = Mixin::from_tokens(toks, scope)?; Ok(Expr::MixinDecl(name, mixin)) } // AtRule::Include => return Some(self.eat_include()), @@ -640,7 +586,7 @@ pub(crate) fn eat_expr>( } TokenKind::AtRule(AtRule::Mixin) => { toks.next(); - let (name, mixin) = parse_mixin(toks, scope.clone()).unwrap(); + let (name, mixin) = Mixin::from_tokens(toks, scope).unwrap(); return Ok(Some(Expr::MixinDecl(name, mixin))); } TokenKind::AtRule(_) => { diff --git a/src/mixin.rs b/src/mixin.rs index e9fc63d..4e11875 100644 --- a/src/mixin.rs +++ b/src/mixin.rs @@ -1,10 +1,11 @@ use std::iter::Peekable; use std::vec::IntoIter; -use crate::common::{Pos, Scope}; -use crate::function::{CallArgs, FuncArgs}; +use crate::common::{Pos, Printer, Scope, Symbol}; +use crate::function::{eat_func_args, CallArgs, FuncArgs}; use crate::selector::Selector; -use crate::{eat_expr, Expr, RuleSet, Stmt, Token}; +use crate::utils::devour_whitespace; +use crate::{eat_expr, Expr, RuleSet, Stmt, Token, TokenKind}; #[derive(Debug, Clone)] pub struct Mixin { @@ -25,6 +26,60 @@ impl Mixin { } } + pub fn from_tokens>( + toks: &mut Peekable, + scope: &Scope, + ) -> Result<(String, Mixin), Printer> { + let Token { pos, .. } = toks + .next() + .expect("this must exist because we have already peeked"); + devour_whitespace(toks); + let name = if let Some(Token { + kind: TokenKind::Ident(s), + .. + }) = toks.next() + { + s + } else { + return Err(Printer::Error( + pos, + String::from("expected identifier after mixin declaration"), + )); + }; + devour_whitespace(toks); + let args = match toks.next() { + Some(Token { + kind: TokenKind::Symbol(Symbol::OpenParen), + .. + }) => eat_func_args(toks), + Some(Token { + kind: TokenKind::Symbol(Symbol::OpenCurlyBrace), + .. + }) => FuncArgs::new(), + _ => return Err(Printer::Error(pos, String::from("expected `(` or `{`"))), + }; + + let mut nesting = 1; + let mut body = Vec::new(); + + while nesting > 0 { + if let Some(tok) = toks.next() { + match &tok.kind { + TokenKind::Symbol(Symbol::OpenCurlyBrace) + // interpolation token eats the opening brace but not the closing + | TokenKind::Interpolation => nesting += 1, + TokenKind::Symbol(Symbol::CloseCurlyBrace) => nesting -= 1, + _ => {} + } + body.push(tok) + } else { + return Err(Printer::Error(pos, String::from("unexpected EOF"))); + } + } + + Ok((name, Mixin::new(scope.clone(), args, body))) + } + pub fn args(&mut self, args: &CallArgs) -> &mut Mixin { for (idx, arg) in args.0.iter().enumerate() { if arg.is_named() { @@ -57,8 +112,7 @@ impl Mixin { while let Some(expr) = eat_expr(&mut self.body, scope, super_selector)? { match expr { Expr::Style(s) => stmts.push(Stmt::Style(s)), - Expr::Include(_) - | Expr::MixinDecl(_, _) => todo!(), + Expr::Include(_) | Expr::MixinDecl(_, _) => todo!(), Expr::Selector(s) => { self.nesting += 1; let rules = self.eval(&super_selector.clone().zip(s.clone()), scope)?;