grass/src/mixin.rs

84 lines
2.5 KiB
Rust
Raw Normal View History

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>)>);