albert_stream/
lib.rs

1//! Albert stream is an abstraction of token
2//! stream where it is possible implement
3//! stream of tokens with the basic method
4//! for a simple compiler front-end.
5
6use std::fmt;
7
8#[derive(Debug)]
9/// Basic Stream that allow to have out of the box a stream of
10/// tokens with access to the current position and the tot
11/// size of the stream.
12pub struct BasicStream<T> {
13    /// current position in the stream
14    pub pos: usize,
15    /// current stream
16    pub stream: Vec<T>,
17    /// tot size of the stream
18    pub size: usize,
19}
20
21impl<T> Stream<T> for BasicStream<T>
22where
23    T: fmt::Display + Clone,
24{
25    fn new(tokens: &Vec<T>) -> Self {
26        BasicStream::new_with_pos(tokens, 0)
27    }
28
29    fn new_with_pos(stream: &Vec<T>, pos: usize) -> Self {
30        BasicStream {
31            pos,
32            stream: stream.to_vec(),
33            size: stream.len(),
34        }
35    }
36
37    /// advance the position and return the previous element
38    /// in position - 1
39    fn advance<'c>(&'c mut self) -> &'c T {
40        self.next();
41        if self.is_end() {
42            return &self.stream.last().unwrap();
43        }
44        self.prev()
45    }
46
47    fn lookup<'c>(&'c self, step: usize) -> Option<&'c T> {
48        if self.size > self.pos + step {
49            return None;
50        }
51        Some(&self.stream[self.pos + step])
52    }
53
54    fn next(&mut self) {
55        self.pos += 1;
56    }
57
58    fn prev<'c>(&'c self) -> &'c T {
59        assert!(self.pos < self.size, "prev: out of bound");
60        &self.stream[self.pos - 1]
61    }
62
63    /// return he token at the current position
64    fn peek<'c>(&'c self) -> &'c T {
65        assert!(self.pos < self.size);
66        &self.stream[self.pos]
67    }
68
69    fn match_tok(&self, tok: &str) -> bool {
70        self.peek().to_string() == tok
71    }
72
73    /// check if it is reach the end of the stream
74    fn is_end(&self) -> bool {
75        if self.size == 0 {
76            return true;
77        }
78        self.pos > self.size - 1
79    }
80}
81
82pub trait Stream<T> {
83    fn new(tokens: &Vec<T>) -> Self;
84
85    fn new_with_pos(stream: &Vec<T>, pos: usize) -> Self;
86
87    /// advance the position and return the previous element
88    /// in position - 1
89    fn advance<'c>(&'c mut self) -> &'c T;
90
91    fn lookup<'c>(&'c self, step: usize) -> Option<&'c T>;
92
93    fn next(&mut self);
94
95    fn prev<'c>(&'c self) -> &'c T;
96
97    /// return he token at the current position
98    fn peek<'c>(&'c self) -> &'c T;
99
100    fn match_tok(&self, tok: &str) -> bool;
101
102    /// check if it is reach the end of the stream
103    fn is_end(&self) -> bool;
104}