[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:
		
							parent
							
								
									15e275513d
								
							
						
					
					
						commit
						34d612a832
					
				
					 6 changed files with 56 additions and 11 deletions
				
			
		|  | @ -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' | ||||
|     } | ||||
|  |  | |||
|  | @ -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
									
								
							
							
						
						
									
										33
									
								
								lexer/src/states/dot.rs
									
										
									
									
									
										Normal 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)) | ||||
|     } | ||||
| } | ||||
|  | @ -8,6 +8,7 @@ use token::Token; | |||
| 
 | ||||
| mod begin; | ||||
| mod bool; | ||||
| mod dot; | ||||
| mod hash; | ||||
| mod number; | ||||
| mod id; | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ pub struct Lex { | |||
| #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||||
| pub enum Token { | ||||
|     Bool(bool), | ||||
|     Dot, | ||||
|     Num(i64), | ||||
|     LeftParen, | ||||
|     RightParen, | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue