grass/src/utils/read_until.rs

252 lines
6.7 KiB
Rust
Raw Normal View History

use std::iter::Iterator;
use peekmore::PeekMoreIterator;
use crate::Token;
2020-04-20 14:53:52 -04:00
use super::{devour_whitespace, read_until_newline};
// Eat tokens until an open curly brace
//
// Does not consume the open curly brace
pub(crate) fn read_until_open_curly_brace<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
) -> Vec<Token> {
2020-04-22 10:57:57 -04:00
let mut t = Vec::new();
let mut n = 0;
while let Some(tok) = toks.peek() {
match tok.kind {
'{' => n += 1,
'}' => n -= 1,
'/' => {
let next = toks.next().unwrap();
match toks.peek().unwrap().kind {
'/' => read_until_newline(toks),
2020-04-22 10:57:57 -04:00
_ => t.push(next),
};
continue;
}
2020-04-22 10:57:57 -04:00
'\\' => {
t.push(toks.next().unwrap());
if toks.peek().is_some() {
t.push(toks.next().unwrap());
}
}
_ => {}
}
if n == 1 {
break;
}
2020-04-22 10:57:57 -04:00
t.push(toks.next().unwrap());
}
2020-04-22 10:57:57 -04:00
t
}
pub(crate) fn read_until_closing_curly_brace<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
) -> Vec<Token> {
let mut t = Vec::new();
let mut nesting = 0;
while let Some(tok) = toks.peek() {
match tok.kind {
q @ '"' | q @ '\'' => {
t.push(toks.next().unwrap());
t.extend(read_until_closing_quote(toks, q));
}
'{' => {
nesting += 1;
t.push(toks.next().unwrap());
}
'}' => {
if nesting == 0 {
break;
} else {
nesting -= 1;
t.push(toks.next().unwrap());
}
}
'/' => {
let next = toks.next().unwrap();
match toks.peek().unwrap().kind {
2020-05-02 12:49:42 -04:00
'/' => {
read_until_newline(toks);
devour_whitespace(toks);
}
_ => t.push(next),
};
continue;
}
2020-04-21 04:20:35 -04:00
'(' => {
t.push(toks.next().unwrap());
t.extend(read_until_closing_paren(toks));
}
2020-04-22 10:57:57 -04:00
'\\' => {
t.push(toks.next().unwrap());
if toks.peek().is_some() {
t.push(toks.next().unwrap());
}
}
_ => t.push(toks.next().unwrap()),
}
}
devour_whitespace(toks);
t
}
pub(crate) fn read_until_closing_quote<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
q: char,
) -> Vec<Token> {
let mut t = Vec::new();
while let Some(tok) = toks.next() {
match tok.kind {
'"' if q == '"' => {
t.push(tok);
break;
}
'\'' if q == '\'' => {
t.push(tok);
break;
}
'\\' => {
t.push(tok);
2020-04-22 10:57:57 -04:00
if toks.peek().is_some() {
t.push(toks.next().unwrap());
}
}
'#' => {
t.push(tok);
let next = toks.peek().unwrap();
if next.kind == '{' {
t.push(toks.next().unwrap());
t.append(&mut read_until_closing_curly_brace(toks));
}
}
_ => t.push(tok),
}
}
t
}
pub(crate) fn read_until_semicolon_or_closing_curly_brace<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
) -> Vec<Token> {
let mut t = Vec::new();
let mut nesting = 0;
while let Some(tok) = toks.peek() {
match tok.kind {
';' => {
break;
}
'\\' => {
t.push(toks.next().unwrap());
2020-04-22 10:57:57 -04:00
if toks.peek().is_some() {
t.push(toks.next().unwrap());
}
}
'"' | '\'' => {
let quote = toks.next().unwrap();
2020-04-21 18:22:26 -04:00
t.push(quote);
t.extend(read_until_closing_quote(toks, quote.kind));
}
'{' => {
nesting += 1;
t.push(toks.next().unwrap());
}
'}' => {
if nesting == 0 {
break;
} else {
nesting -= 1;
t.push(toks.next().unwrap());
}
}
'/' => {
let next = toks.next().unwrap();
match toks.peek().unwrap().kind {
2020-05-02 12:49:42 -04:00
'/' => {
read_until_newline(toks);
devour_whitespace(toks);
}
_ => t.push(next),
};
continue;
}
_ => t.push(toks.next().unwrap()),
}
}
devour_whitespace(toks);
t
}
pub(crate) fn read_until_closing_paren<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
) -> Vec<Token> {
2020-04-22 10:57:57 -04:00
let mut t = Vec::new();
let mut scope = 0;
while let Some(tok) = toks.next() {
match tok.kind {
')' => {
if scope < 1 {
2020-04-22 10:57:57 -04:00
t.push(tok);
return t;
} else {
scope -= 1;
}
}
'(' => scope += 1,
'"' | '\'' => {
2020-04-22 10:57:57 -04:00
t.push(tok);
t.extend(read_until_closing_quote(toks, tok.kind));
continue;
}
'\\' => {
t.push(tok);
if toks.peek().is_some() {
t.push(toks.next().unwrap());
}
continue;
}
_ => {}
}
2020-04-22 10:57:57 -04:00
t.push(tok)
}
2020-04-22 10:57:57 -04:00
t
}
pub(crate) fn read_until_closing_square_brace<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
) -> Vec<Token> {
2020-04-22 10:57:57 -04:00
let mut t = Vec::new();
let mut scope = 0;
while let Some(tok) = toks.next() {
2020-05-02 12:49:42 -04:00
// TODO: comments
match tok.kind {
']' => {
if scope < 1 {
2020-04-22 10:57:57 -04:00
t.push(tok);
return t;
} else {
scope -= 1;
}
}
'[' => scope += 1,
'"' | '\'' => {
2020-04-22 10:57:57 -04:00
t.push(tok);
t.extend(read_until_closing_quote(toks, tok.kind));
continue;
}
2020-04-22 10:57:57 -04:00
'\\' => {
t.push(tok);
if toks.peek().is_some() {
t.push(toks.next().unwrap());
}
}
_ => {}
}
2020-04-22 10:57:57 -04:00
t.push(tok)
}
2020-04-22 10:57:57 -04:00
t
}