use std::fmt;
#[derive(Debug)]
pub struct BasicStream<T> {
pub pos: usize,
pub stream: Vec<T>,
pub size: usize,
}
impl<T> Stream<T> for BasicStream<T>
where
T: fmt::Display + Clone,
{
fn new(tokens: &Vec<T>) -> Self {
BasicStream::new_with_pos(tokens, 0)
}
fn new_with_pos(stream: &Vec<T>, pos: usize) -> Self {
BasicStream {
pos,
stream: stream.to_vec(),
size: stream.len(),
}
}
fn advance<'c>(&'c mut self) -> &'c T {
self.next();
if self.is_end() {
return &self.stream.last().unwrap();
}
self.prev()
}
fn lookup<'c>(&'c self, step: usize) -> Option<&'c T> {
if self.size > self.pos + step {
return None;
}
Some(&self.stream[self.pos + step])
}
fn next(&mut self) {
self.pos += 1;
}
fn prev<'c>(&'c self) -> &'c T {
assert!(self.pos < self.size, "prev: out of bound");
&self.stream[self.pos - 1]
}
fn peek<'c>(&'c self) -> &'c T {
assert!(self.pos < self.size);
&self.stream[self.pos]
}
fn match_tok(&self, tok: &str) -> bool {
self.peek().to_string() == tok
}
fn is_end(&self) -> bool {
if self.size == 0 {
return true;
}
self.pos > self.size - 1
}
}
pub trait Stream<T> {
fn new(tokens: &Vec<T>) -> Self;
fn new_with_pos(stream: &Vec<T>, pos: usize) -> Self;
fn advance<'c>(&'c mut self) -> &'c T;
fn lookup<'c>(&'c self, step: usize) -> Option<&'c T>;
fn next(&mut self);
fn prev<'c>(&'c self) -> &'c T;
fn peek<'c>(&'c self) -> &'c T;
fn match_tok(&self, tok: &str) -> bool;
fn is_end(&self) -> bool;
}