grass/src/lexer.rs

49 lines
1.1 KiB
Rust
Raw Normal View History

2020-06-16 20:00:11 -04:00
use std::{iter::Peekable, str::Chars, sync::Arc};
2020-04-12 19:37:12 -04:00
use codemap::File;
2020-03-29 13:28:17 -04:00
use crate::Token;
2020-01-26 16:50:08 -05:00
2020-05-23 01:17:14 -04:00
const FORM_FEED: char = '\x0C';
2020-02-28 18:27:32 -05:00
#[derive(Debug, Clone)]
pub(crate) struct Lexer<'a> {
buf: Peekable<Chars<'a>>,
2020-04-12 19:37:12 -04:00
pos: usize,
file: &'a Arc<File>,
}
impl<'a> Iterator for Lexer<'a> {
type Item = Token;
fn next(&mut self) -> Option<Self::Item> {
2020-03-29 13:28:17 -04:00
let kind = match self.buf.next()? {
2020-05-01 19:16:57 -04:00
FORM_FEED => '\n',
'\r' => {
2020-03-29 13:28:17 -04:00
if self.buf.peek() == Some(&'\n') {
2020-04-12 19:37:12 -04:00
self.pos += 1;
2020-03-29 13:28:17 -04:00
self.buf.next();
}
2020-05-01 19:16:57 -04:00
'\n'
}
2020-03-29 13:28:17 -04:00
c => c,
};
2020-04-12 19:37:12 -04:00
let len = kind.len_utf8();
let pos = self
.file
.span
.subspan(self.pos as u64, (self.pos + len) as u64);
self.pos += len;
Some(Token { kind, pos })
}
}
impl<'a> Lexer<'a> {
2020-04-12 19:37:12 -04:00
pub fn new(file: &'a Arc<File>) -> Lexer<'a> {
Lexer {
2020-04-21 18:22:26 -04:00
buf: file.source().chars().peekable(),
2020-04-12 19:37:12 -04:00
pos: 0,
file,
}
}
}