grass/src/utils.rs

79 lines
2.2 KiB
Rust
Raw Normal View History

2020-01-26 09:28:44 -05:00
use crate::common::{Pos, Symbol};
use crate::lexer::Lexer;
2020-01-26 09:28:44 -05:00
use crate::value::Value;
use crate::{Scope, Token, TokenKind};
use std::iter::{Iterator, Peekable};
pub(crate) trait IsWhitespace {
fn is_whitespace(&self) -> bool;
}
2020-01-20 16:00:37 -05:00
pub(crate) fn devour_whitespace<I: Iterator<Item = W>, W: IsWhitespace>(
s: &mut Peekable<I>,
) -> 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<I: Iterator<Item = W>, W: IsWhitespace + IsComment>(
s: &mut Peekable<I>,
) -> 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<I: Iterator<Item = Token>>(
tokens: &mut I,
scope: &Scope,
) -> Vec<Token> {
let mut val = Vec::new();
while let Some(tok) = tokens.next() {
2020-01-18 20:24:28 -05:00
match tok.kind {
TokenKind::Symbol(Symbol::CloseCurlyBrace) => break,
TokenKind::Symbol(Symbol::SingleQuote) | TokenKind::Symbol(Symbol::DoubleQuote) => {
continue
}
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::<Vec<Token>>(),
),
TokenKind::Interpolation => val.extend(eat_interpolation(tokens, scope)),
2020-01-18 20:24:28 -05:00
_ => val.push(tok),
}
}
val
}
2020-01-14 19:34:13 -05:00
pub(crate) fn eat_variable_value<I: Iterator<Item = Token>>(
2020-01-14 19:34:13 -05:00
toks: &mut Peekable<I>,
scope: &Scope,
2020-01-26 09:28:44 -05:00
) -> Result<Value, (Pos, String)> {
2020-01-14 19:34:13 -05:00
devour_whitespace(toks);
2020-01-18 09:42:25 -05:00
// todo!(line might not end with semicolon)
2020-01-26 09:28:44 -05:00
let iter1: Vec<Token> = toks
.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon))
.collect();
2020-01-14 19:34:13 -05:00
devour_whitespace(toks);
2020-01-26 09:28:44 -05:00
Ok(Value::from_tokens(&mut iter1.into_iter().peekable(), scope).unwrap())
2020-01-14 19:34:13 -05:00
}