Add some character class methods to a Lexable trait for char

This commit is contained in:
Eryn Wells 2017-05-13 15:37:01 -07:00
parent 1dfdc001b3
commit 237dca4b4b
2 changed files with 19 additions and 3 deletions

13
lexer/src/chars.rs Normal file
View file

@ -0,0 +1,13 @@
/* lexer/src/chars.rs
* Eryn Wells <eryn@erynwells.me>
*/
pub trait Lexable {
fn is_left_paren(&self) -> bool;
fn is_right_paren(&self) -> bool;
}
impl Lexable for char {
fn is_left_paren(&self) -> bool { *self == '(' }
fn is_right_paren(&self) -> bool { *self == ')' }
}

View file

@ -4,10 +4,13 @@
use std::iter::Peekable;
mod chars;
mod error;
pub use error::Error;
use chars::Lexable;
#[derive(Debug, Eq, PartialEq)]
pub enum Token { LeftParen, RightParen, Id(String), }
@ -49,8 +52,8 @@ impl<T> Iterator for Lexer<T> where T: Iterator<Item=char> {
let peek = self.input.peek().map(char::clone);
let result = if buffer.is_empty() {
match peek {
Some('(') => self.emit(Token::LeftParen, Resume::AtNext),
Some(')') => self.emit(Token::RightParen, Resume::AtNext),
Some(c) if c.is_left_paren() => self.emit(Token::LeftParen, Resume::AtNext),
Some(c) if c.is_right_paren() => self.emit(Token::RightParen, Resume::AtNext),
Some(c) if c.is_whitespace() => IterationResult::Continue,
Some(c) if c.is_alphabetic() => {
buffer.push(c);
@ -67,7 +70,7 @@ impl<T> Iterator for Lexer<T> where T: Iterator<Item=char> {
buffer.push(c);
IterationResult::Continue
}
Some(c) if c == '(' || c == ')' || c.is_whitespace() =>
Some(c) if c.is_left_paren() || c.is_right_paren() || c.is_whitespace() =>
self.emit(Token::Id(buffer.clone()), Resume::Here),
Some(c) => self.fail(format!("Invalid character: {}", c)),
// Found EOF. Emit what we have and finish.