diff --git a/src/utils.rs b/src/utils.rs index c2509d9..efbd6e7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,5 @@ -use crate::common::{Pos, Symbol, Whitespace}; +use crate::common::{Pos, Symbol}; +use crate::value::Value; use crate::{Scope, Token, TokenKind}; use std::iter::{Iterator, Peekable}; @@ -38,33 +39,6 @@ pub(crate) fn devour_whitespace_or_comment, W: IsWhitespac found_whitespace } -#[cfg_attr(feature = "nightly", track_caller)] -pub(crate) fn deref_variable(name: &str, scope: &Scope) -> Vec { - let mut toks = scope - .vars - .get(name) - .expect("todo! expected variable to exist") - .iter() - .peekable(); - let mut val = Vec::with_capacity(toks.len()); - while let Some(tok) = toks.next() { - match tok.kind { - TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)), - TokenKind::Whitespace(_) => { - devour_whitespace(&mut toks); - if toks.peek().is_some() { - val.push(Token { - kind: TokenKind::Whitespace(Whitespace::Space), - pos: tok.pos, - }); - } - } - _ => val.push(tok.clone()), - } - } - val -} - pub(crate) fn eat_interpolation>( tokens: &mut I, scope: &Scope, @@ -76,7 +50,10 @@ pub(crate) fn eat_interpolation>( TokenKind::Symbol(Symbol::OpenCurlyBrace) => { todo!("invalid character in interpolation") } - TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)), + TokenKind::Variable(ref v) => val.push(Token { + pos: tok.pos, + kind: TokenKind::Ident(scope.vars.get(v).unwrap().to_string()), + }), TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)), _ => val.push(tok), } @@ -87,17 +64,12 @@ pub(crate) fn eat_interpolation>( pub(crate) fn eat_variable_value>( toks: &mut Peekable, scope: &Scope, -) -> Result, (Pos, String)> { +) -> Result { devour_whitespace(toks); // todo!(line might not end with semicolon) - let iter1 = toks.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon)); - let mut iter2 = Vec::new(); - for tok in iter1 { - match tok.kind { - TokenKind::Variable(ref name) => iter2.extend(deref_variable(name, scope)), - _ => iter2.push(tok), - }; - } + let iter1: Vec = toks + .take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon)) + .collect(); devour_whitespace(toks); - Ok(iter2) + Ok(Value::from_tokens(&mut iter1.into_iter().peekable(), scope).unwrap()) } diff --git a/src/value.rs b/src/value.rs index 6d8fa58..d1e2a80 100644 --- a/src/value.rs +++ b/src/value.rs @@ -8,7 +8,7 @@ use crate::builtin::GLOBAL_FUNCTIONS; use crate::color::Color; use crate::common::{Keyword, Op, Scope, Symbol}; use crate::units::Unit; -use crate::utils::{deref_variable, devour_whitespace_or_comment, eat_interpolation}; +use crate::utils::{devour_whitespace_or_comment, eat_interpolation}; use crate::{Token, TokenKind}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -275,7 +275,7 @@ impl Value { .. }) => { toks.next(); - let args = eat_call_args(toks); + let args = eat_call_args(toks, scope); let func = match scope.functions.get(&s) { Some(f) => f, None => match GLOBAL_FUNCTIONS.get(&s) { @@ -308,9 +308,7 @@ impl Value { } Some(Value::Ident(s, QuoteKind::Single)) } - TokenKind::Variable(ref v) => { - Value::from_tokens(&mut deref_variable(v, scope).into_iter().peekable(), scope) - } + TokenKind::Variable(ref v) => Some(scope.vars.get(v).unwrap().clone()), TokenKind::Interpolation => { let mut s = eat_interpolation(toks, scope) .iter()