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