Refactor out variable eating
This commit is contained in:
parent
2389abaeed
commit
e3968ac047
40
src/main.rs
40
src/main.rs
@ -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),
|
||||||
|
51
src/mixin.rs
51
src/mixin.rs
@ -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())
|
||||||
|
34
src/utils.rs
34
src/utils.rs
@ -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)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user