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 => {
let mut n = 0;
while let Some(tok) = toks.next() {
if tok.kind == TokenKind::Symbol(Symbol::CloseCurlyBrace) {
values.push(tok);
break;
match tok.kind {
TokenKind::Symbol(Symbol::OpenCurlyBrace) => n += 1,
TokenKind::Symbol(Symbol::CloseCurlyBrace) => n -= 1,
TokenKind::Interpolation => n += 1,
_ => {},
}
values.push(tok);
if n == 0 {
break;
}
}
}
_ => 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 color: blue;\n}\n"
);
// test!(
// nested_interpolation,
// "$a: red; a {\n color: #{#{$a}};\n}\n",
// "a {\n color: red;\n}\n"
// );
test!(
nested_interpolation,
"$a: red; a {\n color: #{#{$a}};\n}\n",
"a {\n color: red;\n}\n"
);
}
#[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>>(
tokens: &mut Peekable<I>,
tokens: &mut I,
scope: &Scope,
) -> Vec<Token> {
let mut val = Vec::new();
for tok in tokens {
while let Some(tok) = tokens.next() {
match tok.kind {
TokenKind::Symbol(Symbol::CloseCurlyBrace) => break,
TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
todo!("invalid character in interpolation")
}
TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)),
TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)),
_ => val.push(tok),
}
}