From cdbd4ff9a6ce7f9daf3174e0aa1b7b42f531293c Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sun, 12 Jan 2020 20:56:07 -0500 Subject: [PATCH] Considate variable dereferencing into util function --- src/selector.rs | 27 +++------------------------ src/style.rs | 46 +++++++++++++--------------------------------- src/utils.rs | 28 ++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 57 deletions(-) diff --git a/src/selector.rs b/src/selector.rs index b8aeb7a..5f68abb 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -1,5 +1,5 @@ use crate::common::{Scope, Symbol}; -use crate::utils::{devour_whitespace, IsWhitespace}; +use crate::utils::{deref_variable, devour_whitespace, IsWhitespace}; use crate::{Token, TokenKind}; use std::fmt::{self, Display}; use std::iter::Peekable; @@ -185,9 +185,9 @@ impl<'a> SelectorParser<'a> { .collect::>(); //.iter().peekable(); let mut toks = toks.iter().peekable(); while let Some(Token { kind, .. }) = toks.peek() { - if let TokenKind::Variable(_) = kind { + if let TokenKind::Variable(ref var) = kind { toks.next(); - let these_toks = self.deref_variable(kind); + let these_toks = deref_variable(var, self.scope); let mut these_toks = these_toks.iter().peekable(); while let Some(s) = self.selector_from_token_stream(&mut these_toks) { v.push(s); @@ -235,27 +235,6 @@ impl<'a> SelectorParser<'a> { } None } - - fn deref_variable(&mut self, variable: &TokenKind) -> Vec { - let mut val = Vec::with_capacity(25); - let v = match variable { - TokenKind::Variable(ref v) => self - .scope - .vars - .get(v) - .expect("todo! expected variable to exist"), - _ => todo!("expected variable"), - } - .iter() - .peekable(); - for tok in v { - match &tok.kind { - TokenKind::Variable(_) => val.extend(self.deref_variable(&tok.kind)), - _ => val.push(tok.clone()), - }; - } - val - } } impl<'a> SelectorParser<'a> { diff --git a/src/style.rs b/src/style.rs index 082de57..c287afd 100644 --- a/src/style.rs +++ b/src/style.rs @@ -1,4 +1,5 @@ use crate::common::{Scope, Symbol}; +use crate::utils::deref_variable; use crate::{Token, TokenKind}; use std::fmt::{self, Display}; use std::iter::Peekable; @@ -37,37 +38,6 @@ impl<'a> StyleParser<'a> { Ok(StyleParser { tokens, scope }) } - fn deref_variable(&mut self, variable: &TokenKind) -> String { - let mut val = String::with_capacity(25); - let mut v = match variable { - TokenKind::Variable(ref v) => self - .scope - .vars - .get(v) - .expect("todo! expected variable to exist"), - _ => panic!("expected variable"), - } - .iter() - .peekable(); - while let Some(tok) = v.next() { - match &tok.kind { - TokenKind::Variable(_) => val.push_str(&self.deref_variable(&tok.kind)), - TokenKind::Whitespace(_) => { - while let Some(w) = v.peek() { - if let TokenKind::Whitespace(_) = w.kind { - v.next(); - } else { - val.push(' '); - break; - } - } - } - _ => val.push_str(&tok.kind.to_string()), - }; - } - val - } - fn devour_whitespace_or_comment(&mut self) { while let Some(Token { kind, .. }) = self.tokens.peek() { match kind { @@ -85,7 +55,12 @@ impl<'a> StyleParser<'a> { TokenKind::Symbol(Symbol::OpenCurlyBrace) => { todo!("invalid character in interpolation") } - TokenKind::Variable(_) => val.push_str(&self.deref_variable(kind)), + TokenKind::Variable(ref v) => val.push_str( + &deref_variable(v, self.scope) + .iter() + .map(|x| x.kind.to_string()) + .collect::(), + ), _ => val.push_str(&kind.to_string()), } } @@ -138,7 +113,12 @@ impl<'a> StyleParser<'a> { break; } } - TokenKind::Variable(_) => value.push_str(&self.deref_variable(&tok.kind)), + TokenKind::Variable(ref v) => value.push_str( + &deref_variable(v, self.scope) + .iter() + .map(|x| x.kind.to_string()) + .collect::(), + ), TokenKind::MultilineComment(_) => continue, TokenKind::Interpolation => value.push_str(&self.eat_interpolation()), _ => value.push_str(&tok.kind.to_string()), diff --git a/src/utils.rs b/src/utils.rs index 5d29e71..fcd132f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,5 @@ +use crate::common::Whitespace; +use crate::{Scope, Token, TokenKind}; use std::iter::Iterator; use std::iter::Peekable; @@ -16,3 +18,29 @@ pub fn devour_whitespace, W: IsWhitespace>(s: &mut Peekabl } found_whitespace } + +pub fn deref_variable(name: &str, scope: &Scope) -> Vec { + let mut toks = scope + .vars + .get(name) + .expect("todo! expected variable to exist") + .iter() + .peekable(); + let mut val = Vec::with_capacity(toks.len()); + while let Some(tok) = toks.next() { + match &tok.kind { + TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)), + TokenKind::Whitespace(_) => { + devour_whitespace(&mut toks); + if toks.peek().is_some() { + val.push(Token { + kind: TokenKind::Whitespace(Whitespace::Space), + pos: tok.pos, + }); + } + } + _ => val.push(tok.clone()), + } + } + val +}