1use crate::position::{Located, Positon};
2
3pub trait Lexable
4where
5 Self: Sized,
6{
7 type Error;
8 fn lex(lexer: &mut Lexer) -> Result<Option<Located<Self>>, Located<Self::Error>>;
10}
11
12pub struct Lexer {
13 pub text: String,
14 pub idx: usize,
15 pub ln: usize,
16 pub col: usize,
17}
18impl Lexer {
19 pub fn new(text: String) -> Self {
20 Self {
21 text,
22 idx: 0,
23 ln: 0,
24 col: 0,
25 }
26 }
27 pub fn lex<T: Lexable>(&mut self) -> Result<Vec<Located<T>>, Located<T::Error>> {
29 let mut tokens = vec![];
30 while let Some(token) = T::lex(self)? {
31 tokens.push(token)
32 }
33 Ok(tokens)
34 }
35 pub fn get(&self) -> Option<char> {
37 self.text.get(self.idx..=self.idx)?.chars().next()
38 }
39 pub fn pos(&self) -> Positon {
41 Positon::new(self.ln..self.ln, self.col..self.col + 1)
42 }
43 pub fn advance(&mut self) {
45 if self.get() == Some('\n') {
46 self.ln += 1;
47 self.col = 0;
48 } else {
49 self.col += 1;
50 }
51 self.idx += 1;
52 }
53}