Handle arbitrarily nested interpolation

This commit is contained in:
ConnorSkees 2020-01-20 17:01:25 -05:00
parent edb851c536
commit 296bc864fa
2 changed files with 17 additions and 10 deletions

View File

@ -581,12 +581,18 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
} }
} }
TokenKind::Interpolation => { TokenKind::Interpolation => {
let mut n = 0;
while let Some(tok) = toks.next() { while let Some(tok) = toks.next() {
if tok.kind == TokenKind::Symbol(Symbol::CloseCurlyBrace) { match tok.kind {
values.push(tok); TokenKind::Symbol(Symbol::OpenCurlyBrace) => n += 1,
break; TokenKind::Symbol(Symbol::CloseCurlyBrace) => n -= 1,
TokenKind::Interpolation => n += 1,
_ => {},
} }
values.push(tok); values.push(tok);
if n == 0 {
break;
}
} }
} }
_ => match toks.next() { _ => match toks.next() {
@ -730,11 +736,11 @@ mod test_variables {
"a {\n $c: red;\nb {\n $c: blue;\n }\n color: $c;\n}\n", "a {\n $c: red;\nb {\n $c: blue;\n }\n color: $c;\n}\n",
"a {\n color: blue;\n}\n" "a {\n color: blue;\n}\n"
); );
// test!( test!(
// nested_interpolation, nested_interpolation,
// "$a: red; a {\n color: #{#{$a}};\n}\n", "$a: red; a {\n color: #{#{$a}};\n}\n",
// "a {\n color: red;\n}\n" "a {\n color: red;\n}\n"
// ); );
} }
#[cfg(test)] #[cfg(test)]

View File

@ -48,17 +48,18 @@ pub(crate) fn deref_variable(name: &str, scope: &Scope) -> Vec<Token> {
} }
pub(crate) fn eat_interpolation<I: Iterator<Item = Token>>( pub(crate) fn eat_interpolation<I: Iterator<Item = Token>>(
tokens: &mut Peekable<I>, tokens: &mut I,
scope: &Scope, scope: &Scope,
) -> Vec<Token> { ) -> Vec<Token> {
let mut val = Vec::new(); let mut val = Vec::new();
for tok in tokens { while let Some(tok) = tokens.next() {
match tok.kind { match tok.kind {
TokenKind::Symbol(Symbol::CloseCurlyBrace) => break, TokenKind::Symbol(Symbol::CloseCurlyBrace) => break,
TokenKind::Symbol(Symbol::OpenCurlyBrace) => { TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
todo!("invalid character in interpolation") todo!("invalid character in interpolation")
} }
TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)), TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)),
TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)),
_ => val.push(tok), _ => val.push(tok),
} }
} }