Refactor out variable eating

This commit is contained in:
ConnorSkees 2020-01-14 19:34:13 -05:00
parent 2389abaeed
commit e3968ac047
3 changed files with 66 additions and 59 deletions

View File

@ -13,7 +13,6 @@
clippy::use_self, clippy::use_self,
clippy::missing_docs_in_private_items, clippy::missing_docs_in_private_items,
clippy::todo, clippy::todo,
clippy::dbg_macro,
clippy::unreachable, clippy::unreachable,
clippy::wildcard_enum_match_arm, clippy::wildcard_enum_match_arm,
clippy::option_expect_used, clippy::option_expect_used,
@ -41,7 +40,7 @@ use crate::mixin::{CallArgs, FuncArgs, Mixin};
use crate::selector::{Attribute, Selector}; use crate::selector::{Attribute, Selector};
use crate::style::Style; use crate::style::Style;
use crate::units::Unit; use crate::units::Unit;
use crate::utils::{devour_whitespace, IsWhitespace}; use crate::utils::{devour_whitespace, eat_variable_value, IsWhitespace};
mod color; mod color;
mod common; mod common;
@ -254,7 +253,8 @@ impl<'a> StyleSheetParser<'a> {
{ {
self.error(pos, "unexpected variable use at toplevel"); self.error(pos, "unexpected variable use at toplevel");
} }
let val = self.eat_variable_value(); let val = eat_variable_value(&mut self.lexer, &self.global_scope)
.unwrap_or_else(|err| self.error(err.0, err.1));
self.global_scope.vars.insert(name, val); self.global_scope.vars.insert(name, val);
} }
TokenKind::MultilineComment(comment) => { TokenKind::MultilineComment(comment) => {
@ -395,34 +395,6 @@ impl<'a> StyleSheetParser<'a> {
Expr::Styles(styles) Expr::Styles(styles)
} }
fn eat_variable_value(&mut self) -> Vec<Token> {
devour_whitespace(&mut self.lexer);
let iter1 = self
.lexer
.by_ref()
.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon))
.collect::<Vec<Token>>();
let mut iter2 = Vec::with_capacity(iter1.len());
for tok in iter1 {
if let Token {
kind: TokenKind::Variable(ref name),
pos,
} = tok
{
iter2.extend(
self.global_scope
.vars
.get(name)
.unwrap_or_else(|| self.error(pos, "Undefined variable"))
.clone(),
);
} else {
iter2.push(tok);
}
}
iter2
}
fn eat_func_call(&mut self) {} fn eat_func_call(&mut self) {}
fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> { fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> {
@ -492,7 +464,11 @@ impl<'a> StyleSheetParser<'a> {
{ {
self.lexer.next(); self.lexer.next();
devour_whitespace(&mut self.lexer); devour_whitespace(&mut self.lexer);
return Ok(Expr::VariableDecl(name, self.eat_variable_value())); return Ok(Expr::VariableDecl(
name,
eat_variable_value(&mut self.lexer, scope)
.unwrap_or_else(|err| self.error(err.0, err.1)),
));
} else { } else {
values.push(Token { values.push(Token {
kind: TokenKind::Variable(name), kind: TokenKind::Variable(name),

View File

@ -1,6 +1,6 @@
use crate::common::Scope; use crate::common::{Pos, Scope, Symbol};
use crate::common::Symbol;
use crate::style::Style; use crate::style::Style;
use crate::utils::{devour_whitespace, eat_variable_value_ref};
use crate::{Token, TokenKind}; use crate::{Token, TokenKind};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -19,37 +19,36 @@ impl Mixin {
let mut toks = self.body.iter().peekable(); let mut toks = self.body.iter().peekable();
let mut styles = Vec::new(); let mut styles = Vec::new();
let mut value = Vec::new(); let mut value = Vec::new();
while let Some(tok) = toks.peek() { while let Some(tok) = &toks.peek() {
match tok.kind { dbg!(&tok.kind);
match &tok.kind {
TokenKind::Symbol(Symbol::SemiColon) => { TokenKind::Symbol(Symbol::SemiColon) => {
toks.next();
if let Ok(s) = Style::from_tokens(&value, &self.scope) { if let Ok(s) = Style::from_tokens(&value, &self.scope) {
styles.push(s); styles.push(s);
value.clear();
} else { } else {
return styles; return styles;
} }
} }
// TokenKind::Variable(_) => { TokenKind::Variable(ref name) => {
// let tok = toks.next().unwrap(); toks.next();
// let name = if let TokenKind::Variable(n) = tok.kind { if let TokenKind::Symbol(Symbol::Colon) =
// n toks.peek().expect("expected something after variable").kind
// } else { {
// unsafe { std::hint::unreachable_unchecked() } toks.next();
// }; devour_whitespace(&mut toks);
// if let TokenKind::Symbol(Symbol::Colon) = toks self.scope.vars.insert(
// .peek() name.clone(),
// .expect("expected something after variable") eat_variable_value_ref(&mut toks, &self.scope).unwrap(),
// .kind );
// { } else {
// toks.next(); value.push(Token {
// devour_whitespace(&mut toks); kind: TokenKind::Variable(name.clone()),
// return Ok(Expr::VariableDecl(name, self.eat_variable_value())); pos: Pos::new(),
// } else { });
// values.push(Token { }
// kind: TokenKind::Variable(name), }
// pos: tok.pos,
// });
// }
// }
_ => { _ => {
if let Some(tok) = toks.next() { if let Some(tok) = toks.next() {
value.push(tok.clone()) value.push(tok.clone())

View File

@ -1,4 +1,4 @@
use crate::common::{Symbol, Whitespace}; use crate::common::{Pos, Symbol, Whitespace};
use crate::{Scope, Token, TokenKind}; use crate::{Scope, Token, TokenKind};
use std::iter::{Iterator, Peekable}; use std::iter::{Iterator, Peekable};
@ -61,3 +61,35 @@ pub fn eat_interpolation<'a, I: Iterator<Item = &'a Token>>(
} }
val val
} }
pub fn eat_variable_value<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>,
scope: &Scope,
) -> Result<Vec<Token>, (Pos, &'static str)> {
devour_whitespace(toks);
let iter1 = toks.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon));
let mut iter2 = Vec::new();
for tok in iter1 {
match tok.kind {
TokenKind::Variable(ref name) => iter2.extend(deref_variable(name, scope)),
_ => iter2.push(tok),
};
}
Ok(iter2)
}
pub fn eat_variable_value_ref<'a, I: Iterator<Item = &'a Token>>(
toks: &mut Peekable<I>,
scope: &Scope,
) -> Result<Vec<Token>, (Pos, &'static str)> {
devour_whitespace(toks);
let iter1 = toks.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon));
let mut iter2 = Vec::new();
for tok in iter1 {
match tok.kind {
TokenKind::Variable(ref name) => iter2.extend(deref_variable(name, scope)),
_ => iter2.push(tok.clone()),
};
}
Ok(iter2)
}