diff --git a/src/lexer/char.rs b/src/lexer/char.rs index 42e5f7e..a4335f8 100644 --- a/src/lexer/char.rs +++ b/src/lexer/char.rs @@ -10,6 +10,8 @@ pub trait Lexable { fn is_identifier_initial(&self) -> bool; fn is_identifier_subsequent(&self) -> bool; fn is_identifier_single(&self) -> bool; + fn is_hash(&self) -> bool; + fn is_boolean(&self) -> bool; fn is_newline(&self) -> bool; } @@ -34,6 +36,14 @@ impl Lexable for char { charset::identifier_singles().contains(&self) } + fn is_hash(&self) -> bool { + *self == '#' + } + + fn is_boolean(&self) -> bool { + *self == 't' || *self == 'f' + } + fn is_newline(&self) -> bool { *self == '\n' } diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs index 9df933e..5cb0213 100644 --- a/src/lexer/mod.rs +++ b/src/lexer/mod.rs @@ -16,6 +16,7 @@ use self::token::Kind; enum State { Initial, Identifier, + Hash, } pub struct Lexer { @@ -72,13 +73,13 @@ impl Lexer { impl Lexer { /// Handle self.state == State::Initial fn state_initial(&mut self, c: char, token: &mut Option) { - println!("Initial! c='{}'", c); if c.is_left_paren() { *token = Some(Token::new(Kind::LeftParen, c.to_string())); } else if c.is_right_paren() { *token = Some(Token::new(Kind::RightParen, c.to_string())); } + else if c.is_identifier_single() { *token = Some(Token::new(Kind::Identifier, c.to_string())); } @@ -86,6 +87,12 @@ impl Lexer { self.state = State::Identifier; self.advance(); } + + else if c.is_hash() { + self.state = State::Hash; + self.advance(); + } + else if c.is_whitespace() { if c.is_newline() { self.line += 1; @@ -96,7 +103,6 @@ impl Lexer { /// Handle self.state == State::Identifier fn state_identifier(&mut self, c: char, token: &mut Option) { - println!("Identifier! c='{}'", c); if c.is_identifier_subsequent() { // State in Identifier state. self.advance(); @@ -106,6 +112,13 @@ impl Lexer { self.retract(); } } + + fn state_hash(&mut self, c: char, token: &mut Option) { + if c.is_boolean() { + self.advance(); + *token = Some(Token::new(Kind::Boolean, self.value())); + } + } } impl Iterator for Lexer { @@ -120,9 +133,11 @@ impl Iterator for Lexer { println!("Lexing '{}'", &self.input[self.begin ..]); while token.is_none() { if let Some(c) = self.input.char_at(self.forward) { + println!("{}! c='{}'", self.state, c); match self.state { State::Initial => self.state_initial(c, &mut token), State::Identifier => self.state_identifier(c, &mut token), + State::Hash => self.state_hash(c, &mut token), } } else { diff --git a/src/lexer/token.rs b/src/lexer/token.rs index 240a02e..ec8873a 100644 --- a/src/lexer/token.rs +++ b/src/lexer/token.rs @@ -6,6 +6,7 @@ pub enum Kind { LeftParen, RightParen, Identifier, + Boolean, } pub struct Token { @@ -29,6 +30,7 @@ impl fmt::Display for Kind { Kind::LeftParen => "LeftParen", Kind::RightParen => "RightParen", Kind::Identifier => "Identifier", + Kind::Boolean => "Boolean", }; write!(f, "{}", s) } diff --git a/src/main.rs b/src/main.rs index 9ea6d22..123d065 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ mod lexer; fn main() { - let lexer = lexer::Lexer::new(String::from("((abc def + ghi))")); + let lexer = lexer::Lexer::new(String::from("((abc def + ghi #f))")); for t in lexer { println!("token = {}", t); }