grass/src/lexer.rs

50 lines
1.0 KiB
Rust
Raw Normal View History

use std::iter::Peekable;
use std::str::Chars;
2020-03-29 13:28:17 -04:00
use crate::common::Pos;
use crate::Token;
2020-01-26 16:50:08 -05:00
2020-03-29 13:28:17 -04:00
pub 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>>,
pos: Pos,
}
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()? {
'\n' | FORM_FEED => {
self.pos.newline();
2020-03-29 13:28:17 -04:00
'\n'
}
'\r' => {
2020-03-29 13:28:17 -04:00
if self.buf.peek() == Some(&'\n') {
self.buf.next();
'\n'
} else {
'\n'
}
}
'\0' => return None,
2020-03-29 13:28:17 -04:00
c => c,
};
self.pos.next_char();
Some(Token {
kind,
pos: self.pos,
})
}
}
impl<'a> Lexer<'a> {
pub fn new(buf: &'a str) -> Lexer<'a> {
Lexer {
buf: buf.chars().peekable(),
pos: Pos::new(),
}
}
}