[lexer] WIP number::Digit state
This commit is contained in:
		
							parent
							
								
									176686b3a7
								
							
						
					
					
						commit
						d272b211ae
					
				
					 3 changed files with 66 additions and 17 deletions
				
			
		
							
								
								
									
										44
									
								
								lexer/src/states/number/digit.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								lexer/src/states/number/digit.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| /* lexer/src/states/number/digit.rs
 | ||||
|  * Eryn Wells <eryn@erynwells.me> | ||||
|  */ | ||||
| 
 | ||||
| use chars::Lexable; | ||||
| use error::Error; | ||||
| use states::{State, StateResult}; | ||||
| use states::number::{Builder, Radix, Exact}; | ||||
| use states::number::sign::Sign; | ||||
| use token::Token; | ||||
| 
 | ||||
| #[derive(Debug)] pub struct Digit(Builder); | ||||
| 
 | ||||
| impl Digit { | ||||
|     pub fn new(b: Builder) -> Digit { | ||||
|         Digit(b) | ||||
|     } | ||||
| 
 | ||||
|     pub fn with_char(b: Builder, c: char) -> Option<Digit> { | ||||
|         let mut b = b.clone(); | ||||
|         if !b.seen_radix() { | ||||
|             b.push_radix(Radix::Dec); | ||||
|         } | ||||
|         match b.push_digit(c) { | ||||
|             Ok(_) => Some(Digit::new(b)), | ||||
|             // TODO: Deal with this error properly. Don't just ignore it.
 | ||||
|             Err(_) => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl State for Digit { | ||||
|     fn lex(&mut self, c: char) -> StateResult { | ||||
|         if self.0.push_digit(c).is_ok() { | ||||
|             StateResult::Continue | ||||
|         } else { | ||||
|             StateResult::fail(Error::invalid_char(c)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn none(&mut self) -> Result<Option<Token>, Error> { | ||||
|         Err(Error::unexpected_eof()) | ||||
|     } | ||||
| } | ||||
|  | @ -2,24 +2,14 @@ | |||
|  * Eryn Wells <eryn@erynwells.me> | ||||
|  */ | ||||
| 
 | ||||
| use error::Error; | ||||
| 
 | ||||
| mod digit; | ||||
| mod prefix; | ||||
| mod sign; | ||||
| 
 | ||||
| pub use self::prefix::Prefix; | ||||
| 
 | ||||
| trait NumberLexable { | ||||
|     /// Returns the value of this character interpreted as the indicator for a
 | ||||
|     /// base. In Scheme, you indicate the base of a number by prefixing it with
 | ||||
|     /// #[bodx].
 | ||||
|     fn base_value(&self) -> Option<Radix>; | ||||
|     /// Returns the value of the character interpreted as a numerical digit.
 | ||||
|     fn digit_value(&self) -> Option<u8>; | ||||
|     fn sign_value(&self) -> Option<Sign>; | ||||
|     fn is_dot(&self) -> bool; | ||||
|     fn is_hash(&self) -> bool; | ||||
|     fn is_sign(&self) -> bool; | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||||
| pub enum Radix { Bin = 2, Oct = 8, Dec = 10, Hex = 16 } | ||||
| 
 | ||||
|  | @ -65,12 +55,19 @@ impl Builder { | |||
|              radix: None, | ||||
|              sign: None, | ||||
|              exact: None, | ||||
|              value: 0 | ||||
|              value: 0, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn push_digit(&mut self, digit: u8) { | ||||
|         //self.value = self.value * self.base_value() as i64 + digit as i64;
 | ||||
|     fn push_digit(&mut self, c: char) -> Result<(), Error> { | ||||
|         let rx = self.radix_value(); | ||||
|         match c.to_digit(rx as u32) { | ||||
|             Some(d) => { | ||||
|                 self.value = self.value * rx as i64 + d as i64; | ||||
|                 Ok(()) | ||||
|             }, | ||||
|             None => Err(Error::invalid_char(c)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn push_exact(&mut self, ex: Exact) { | ||||
|  | @ -94,4 +91,12 @@ impl Builder { | |||
|     fn seen_exact(&self) -> bool { self.exact.is_some() } | ||||
|     fn seen_radix(&self) -> bool { self.radix.is_some() } | ||||
|     fn seen_sign(&self) -> bool { self.sign.is_some() } | ||||
| 
 | ||||
|     fn radix_value(&self) -> u8 { | ||||
|         let rx = match self.radix { | ||||
|             Some(r) => r, | ||||
|             None => Radix::Dec, | ||||
|         }; | ||||
|         rx as u8 | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ impl State for Prefix { | |||
|     } | ||||
| 
 | ||||
|     fn none(&mut self) -> Result<Option<Token>, Error> { | ||||
|         Err(Error::new("blah".to_string())) | ||||
|         Err(Error::unexpected_eof()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue