2020-01-14 19:34:13 -05:00
|
|
|
use crate::common::{Pos, Scope, Symbol};
|
2020-01-12 20:15:40 -05:00
|
|
|
use crate::style::Style;
|
2020-01-14 19:34:13 -05:00
|
|
|
use crate::utils::{devour_whitespace, eat_variable_value_ref};
|
2020-01-12 20:15:40 -05:00
|
|
|
use crate::{Token, TokenKind};
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Mixin {
|
|
|
|
scope: Scope,
|
|
|
|
args: FuncArgs,
|
|
|
|
body: Vec<Token>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Mixin {
|
|
|
|
pub fn new(scope: Scope, args: FuncArgs, body: Vec<Token>) -> Self {
|
|
|
|
Mixin { scope, args, body }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn eval(&mut self) -> Vec<Style> {
|
|
|
|
let mut toks = self.body.iter().peekable();
|
|
|
|
let mut styles = Vec::new();
|
|
|
|
let mut value = Vec::new();
|
2020-01-14 19:34:13 -05:00
|
|
|
while let Some(tok) = &toks.peek() {
|
|
|
|
dbg!(&tok.kind);
|
|
|
|
match &tok.kind {
|
2020-01-12 20:15:40 -05:00
|
|
|
TokenKind::Symbol(Symbol::SemiColon) => {
|
2020-01-14 19:34:13 -05:00
|
|
|
toks.next();
|
2020-01-12 20:15:40 -05:00
|
|
|
if let Ok(s) = Style::from_tokens(&value, &self.scope) {
|
|
|
|
styles.push(s);
|
2020-01-14 19:34:13 -05:00
|
|
|
value.clear();
|
2020-01-12 20:15:40 -05:00
|
|
|
} else {
|
|
|
|
return styles;
|
|
|
|
}
|
|
|
|
}
|
2020-01-14 19:34:13 -05:00
|
|
|
TokenKind::Variable(ref name) => {
|
|
|
|
toks.next();
|
|
|
|
if let TokenKind::Symbol(Symbol::Colon) =
|
|
|
|
toks.peek().expect("expected something after variable").kind
|
|
|
|
{
|
|
|
|
toks.next();
|
|
|
|
devour_whitespace(&mut toks);
|
|
|
|
self.scope.vars.insert(
|
|
|
|
name.clone(),
|
|
|
|
eat_variable_value_ref(&mut toks, &self.scope).unwrap(),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
value.push(Token {
|
|
|
|
kind: TokenKind::Variable(name.clone()),
|
|
|
|
pos: Pos::new(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2020-01-12 20:15:40 -05:00
|
|
|
_ => {
|
|
|
|
if let Some(tok) = toks.next() {
|
|
|
|
value.push(tok.clone())
|
|
|
|
} else {
|
|
|
|
unsafe { std::hint::unreachable_unchecked() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while let Some(Token {
|
|
|
|
kind: TokenKind::Whitespace(_),
|
|
|
|
..
|
|
|
|
}) = toks.peek()
|
|
|
|
{
|
|
|
|
toks.next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
styles
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct FuncArgs(pub Vec<(Option<String>, Vec<Token>)>);
|
|
|
|
|
|
|
|
impl FuncArgs {
|
|
|
|
pub const fn new() -> Self {
|
|
|
|
FuncArgs(Vec::new())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct CallArgs(Vec<(Option<String>, Vec<Token>)>);
|