[lexer] Add state for finding Dots at the beginning of input

This happens to be a valid token by itself and the beginning of a decimal number.
This commit is contained in:
Eryn Wells 2018-09-06 18:07:40 -07:00
parent 15e275513d
commit 34d612a832
6 changed files with 56 additions and 11 deletions

View file

@ -3,18 +3,22 @@
*/
pub trait Lexable {
fn is_left_paren(&self) -> bool;
fn is_right_paren(&self) -> bool;
fn is_dot(&self) -> bool;
fn is_exactness(&self) -> bool;
fn is_hash(&self) -> bool;
fn is_identifier_delimiter(&self) -> bool;
fn is_identifier_initial(&self) -> bool;
fn is_identifier_subsequent(&self) -> bool;
fn is_identifier_delimiter(&self) -> bool;
fn is_exactness(&self) -> bool;
fn is_left_paren(&self) -> bool;
fn is_radix(&self) -> bool;
fn is_hash(&self) -> bool;
fn is_right_paren(&self) -> bool;
}
impl Lexable for char {
fn is_dot(&self) -> bool {
*self == '.'
}
fn is_exactness(&self) -> bool {
*self == 'i' || *self == 'e'
}

View file

@ -6,13 +6,13 @@ use chars::Lexable;
use error::Error;
use token::Token;
use states::{Resume, State, StateResult};
use states::dot::Dot;
use states::id::IdSub;
use states::hash::Hash;
use states::number::{Builder, Digit};
use states::whitespace::Whitespace;
#[derive(Debug)]
pub struct Begin;
#[derive(Debug)] pub struct Begin;
impl Begin {
pub fn new() -> Begin {
@ -28,9 +28,8 @@ impl State for Begin {
StateResult::Emit(Token::LeftParen, Resume::AtNext)
} else if c.is_right_paren() {
StateResult::Emit(Token::RightParen, Resume::AtNext)
} else if c.is_whitespace() {
// TODO: Figure out some way to track newlines.
StateResult::Continue
} else if c.is_dot() {
StateResult::advance(Box::new(Dot::new()))
} else if c.is_identifier_initial() {
StateResult::advance(Box::new(IdSub{}))
} else if c.is_hash() {

33
lexer/src/states/dot.rs Normal file
View file

@ -0,0 +1,33 @@
/* lexer/src/states/dot.rs
* Eryn Wells <eryn@erynwells.me>
*/
use chars::Lexable;
use error::Error;
use states::{Resume, State, StateResult};
use states::number::{Builder, Digit};
use token::Token;
#[derive(Debug)] pub struct Dot;
impl Dot {
pub fn new() -> Dot {
Dot{}
}
}
impl State for Dot {
fn lex(&mut self, c: char) -> StateResult {
if c.is_identifier_delimiter() {
StateResult::emit(Token::Dot, Resume::Here)
} else if let Some(st) = Digit::with_char(&Builder::new(), c) {
StateResult::advance(Box::new(st))
} else {
StateResult::fail(Error::invalid_char(c))
}
}
fn none(&mut self) -> Result<Option<Token>, Error> {
Ok(Some(Token::Dot))
}
}

View file

@ -8,6 +8,7 @@ use token::Token;
mod begin;
mod bool;
mod dot;
mod hash;
mod number;
mod id;

View file

@ -13,6 +13,7 @@ pub struct Lex {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Token {
Bool(bool),
Dot,
Num(i64),
LeftParen,
RightParen,

View file

@ -88,3 +88,10 @@ fn integers_in_alternative_bases() {
assert_eq!(lex.next(), Some(Ok(Lex::new(Token::Num(0b11001), "#b11001", 0, 5))));
assert_eq!(lex.next(), None);
}
#[test]
fn dot() {
let mut lex = Lexer::new(".".chars());
assert_eq!(lex.next(), Some(Ok(Lex::new(Token::Dot, ".", 0, 0))));
assert_eq!(lex.next(), None);
}