diff --git a/lexer/src/states/hash.rs b/lexer/src/states/hash.rs index 9123773..ffccbb5 100644 --- a/lexer/src/states/hash.rs +++ b/lexer/src/states/hash.rs @@ -6,7 +6,7 @@ use chars::Lexable; use error::Error; use states::{State, StateResult}; use states::bool::Bool; -use states::number::Prefix; +use states::number::{Builder, Prefix}; use token::Token; trait HashLexable { @@ -28,7 +28,7 @@ impl State for Hash { StateResult::advance(Box::new(Bool::new(buf.as_str()))) }, c if c.is_radix() || c.is_exactness() => { - if let Some(st) = Prefix::with_char(c) { + if let Some(st) = Prefix::with_char(Builder::new(), c) { StateResult::advance(Box::new(st)) } else { StateResult::fail(Error::new(format!("invalid numeric prefix character: {}", c))) diff --git a/lexer/src/states/number/prefix.rs b/lexer/src/states/number/prefix.rs index 0bf8a39..dddadfa 100644 --- a/lexer/src/states/number/prefix.rs +++ b/lexer/src/states/number/prefix.rs @@ -17,16 +17,24 @@ impl Prefix { Prefix(b) } - pub fn with_char(c: char) -> Option { - let mut builder = Builder::new(); + pub fn with_char(b: Builder, c: char) -> Option { if let Some(ex) = Exact::from(c) { - builder.push_exact(ex); + if b.seen_exact() { + return None; + } + let mut b = b.clone(); + b.push_exact(ex); + Some(Prefix::new(b)) } else if let Some(rx) = Radix::from(c) { - builder.push_radix(rx); + if b.seen_radix() { + return None; + } + let mut b = b.clone(); + b.push_radix(rx); + Some(Prefix::new(b)) } else { - return None; + None } - Some(Prefix::new(builder)) } } @@ -48,20 +56,8 @@ impl State for Prefix { impl State for Hash { fn lex(&mut self, c: char) -> StateResult { - if let Some(ex) = Exact::from(c) { - if !self.0.seen_exact() { - self.0.push_exact(ex); - StateResult::advance(Box::new(Prefix::new(self.0))) - } else { - StateResult::fail(Error::invalid_char(c)) - } - } else if let Some(rx) = Radix::from(c) { - if !self.0.seen_radix() { - self.0.push_radix(rx); - StateResult::advance(Box::new(Prefix::new(self.0))) - } else { - StateResult::fail(Error::invalid_char(c)) - } + if let Some(st) = Prefix::with_char(self.0, c) { + StateResult::advance(Box::new(st)) } else { StateResult::fail(Error::invalid_char(c)) }