Handle variables on global scope
This commit is contained in:
parent
485bb8b94d
commit
1d80b00c20
40
src/main.rs
40
src/main.rs
@ -186,15 +186,30 @@ impl<'a> StyleSheetParser<'a> {
|
||||
_ => todo!("unexpected toplevel token"),
|
||||
};
|
||||
}
|
||||
StyleSheet { rules }
|
||||
Ok(StyleSheet { rules })
|
||||
}
|
||||
|
||||
fn eat_variable_value(&mut self) -> Vec<Token> {
|
||||
self.devour_whitespace();
|
||||
self.lexer
|
||||
let iter1 = self
|
||||
.lexer
|
||||
.by_ref()
|
||||
.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon))
|
||||
.collect::<Vec<Token>>()
|
||||
.collect::<Vec<Token>>();
|
||||
let mut iter2 = Vec::with_capacity(iter1.len());
|
||||
for tok in iter1 {
|
||||
if let TokenKind::Variable(name) = tok.kind {
|
||||
iter2.extend(
|
||||
self.global_variables
|
||||
.get(&name)
|
||||
.expect("expected variable")
|
||||
.clone(),
|
||||
);
|
||||
} else {
|
||||
iter2.push(tok);
|
||||
}
|
||||
}
|
||||
iter2
|
||||
}
|
||||
|
||||
fn eat_rules(
|
||||
@ -207,18 +222,25 @@ impl<'a> StyleSheetParser<'a> {
|
||||
match tok {
|
||||
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
||||
Expr::Selector(s) => {
|
||||
self.scope += 1;
|
||||
let rules = self.eat_rules(&super_selector.clone().zip(s.clone()), vars);
|
||||
stmts.push(Stmt::RuleSet(RuleSet {
|
||||
super_selector: super_selector.clone(),
|
||||
selector: s,
|
||||
rules,
|
||||
}));
|
||||
self.scope -= 1;
|
||||
}
|
||||
Expr::VariableDecl(name, val) => {
|
||||
if self.scope == 0 {
|
||||
vars.insert(name.clone(), val.clone());
|
||||
self.global_variables.insert(name, val);
|
||||
} else {
|
||||
vars.insert(name, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stmts
|
||||
}
|
||||
|
||||
@ -237,13 +259,13 @@ impl<'a> StyleSheetParser<'a> {
|
||||
)));
|
||||
}
|
||||
TokenKind::Variable(name) => {
|
||||
if self
|
||||
if let TokenKind::Symbol(Symbol::Colon) = self
|
||||
.lexer
|
||||
.next()
|
||||
.peek()
|
||||
.expect("expected something after variable")
|
||||
.kind
|
||||
== TokenKind::Symbol(Symbol::Colon)
|
||||
{
|
||||
self.lexer.next();
|
||||
self.devour_whitespace();
|
||||
return Ok(Expr::VariableDecl(name, self.eat_variable_value()));
|
||||
} else {
|
||||
@ -293,7 +315,8 @@ mod test_css {
|
||||
#[test]
|
||||
fn $func() {
|
||||
let mut buf = Vec::new();
|
||||
StyleSheet::new($input).expect(concat!("failed to parse on ", $input))
|
||||
StyleSheet::new($input)
|
||||
.expect(concat!("failed to parse on ", $input))
|
||||
.print_as_css(&mut buf)
|
||||
.expect(concat!("failed to pretty print on ", $input));
|
||||
assert_eq!(
|
||||
@ -306,7 +329,8 @@ mod test_css {
|
||||
#[test]
|
||||
fn $func() {
|
||||
let mut buf = Vec::new();
|
||||
StyleSheet::new($input).expect(concat!("failed to parse on ", $input))
|
||||
StyleSheet::new($input)
|
||||
.expect(concat!("failed to parse on ", $input))
|
||||
.print_as_css(&mut buf)
|
||||
.expect(concat!("failed to pretty print on ", $input));
|
||||
assert_eq!(
|
||||
|
Loading…
x
Reference in New Issue
Block a user