/* lexer/src/states/number/mod.rs * Eryn Wells */ use error::Error; mod digit; mod prefix; mod sign; pub use self::prefix::Prefix; pub use self::digit::Digit; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Radix { Bin = 2, Oct = 8, Dec = 10, Hex = 16 } #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Sign { Neg = -1, Pos = 1 } #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Exact { Yes, No } #[derive(Copy, Clone, Debug)] pub struct Builder { radix: Option, sign: Option, exact: Option, value: i64, } impl Radix { pub fn from(c: char) -> Option { match c { 'b'|'B' => Some(Radix::Bin), 'o'|'O' => Some(Radix::Oct), 'd'|'D' => Some(Radix::Dec), 'x'|'X' => Some(Radix::Hex), _ => None } } } impl Exact { pub fn from(c: char) -> Option { match c { 'i'|'I' => Some(Exact::No), 'e'|'E' => Some(Exact::Yes), _ => None } } } impl Builder { pub fn new() -> Builder { Builder { radix: None, sign: None, exact: None, value: 0, } } 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) { self.exact = Some(ex); } fn push_radix(&mut self, radix: Radix) { self.radix = Some(radix); } fn push_sign(&mut self, sign: Sign) { self.sign = Some(sign); } fn resolve(&self) -> i64 { let sign_factor = self.sign_value() as i64; self.value * sign_factor } 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 { self.radix.unwrap_or(Radix::Dec) as u8 } fn sign_value(&self) -> u8 { self.sign.unwrap_or(Sign::Pos) as u8 } }