use crate::common::{Pos, Symbol}; use crate::lexer::Lexer; use crate::value::Value; use crate::{Scope, Token, TokenKind}; use std::iter::{Iterator, Peekable}; pub(crate) trait IsWhitespace { fn is_whitespace(&self) -> bool; } pub(crate) fn devour_whitespace, W: IsWhitespace>( s: &mut Peekable, ) -> bool { let mut found_whitespace = false; while let Some(w) = s.peek() { if !w.is_whitespace() { break; } found_whitespace = true; s.next(); } found_whitespace } pub(crate) trait IsComment { fn is_comment(&self) -> bool; } pub(crate) fn devour_whitespace_or_comment, W: IsWhitespace + IsComment>( s: &mut Peekable, ) -> bool { let mut found_whitespace = false; while let Some(w) = s.peek() { if !w.is_whitespace() && !w.is_comment() { break; } found_whitespace = true; s.next(); } found_whitespace } pub(crate) fn eat_interpolation>( tokens: &mut I, scope: &Scope, ) -> Vec { let mut val = Vec::new(); 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( Lexer::new(&scope.vars.get(v).unwrap().to_string()).collect::>(), ), TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)), _ => val.push(tok), } } val } pub(crate) fn eat_variable_value>( toks: &mut Peekable, scope: &Scope, ) -> Result { devour_whitespace(toks); // todo!(line might not end with semicolon) let iter1: Vec = toks .take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon)) .collect(); devour_whitespace(toks); Ok(Value::from_tokens(&mut iter1.into_iter().peekable(), scope).unwrap()) }