[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>
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use error::Error;
|
||||||
|
|
||||||
|
mod digit;
|
||||||
mod prefix;
|
mod prefix;
|
||||||
mod sign;
|
mod sign;
|
||||||
|
|
||||||
pub use self::prefix::Prefix;
|
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)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum Radix { Bin = 2, Oct = 8, Dec = 10, Hex = 16 }
|
pub enum Radix { Bin = 2, Oct = 8, Dec = 10, Hex = 16 }
|
||||||
|
|
||||||
|
@ -65,12 +55,19 @@ impl Builder {
|
||||||
radix: None,
|
radix: None,
|
||||||
sign: None,
|
sign: None,
|
||||||
exact: None,
|
exact: None,
|
||||||
value: 0
|
value: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_digit(&mut self, digit: u8) {
|
fn push_digit(&mut self, c: char) -> Result<(), Error> {
|
||||||
//self.value = self.value * self.base_value() as i64 + digit as i64;
|
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) {
|
fn push_exact(&mut self, ex: Exact) {
|
||||||
|
@ -94,4 +91,12 @@ impl Builder {
|
||||||
fn seen_exact(&self) -> bool { self.exact.is_some() }
|
fn seen_exact(&self) -> bool { self.exact.is_some() }
|
||||||
fn seen_radix(&self) -> bool { self.radix.is_some() }
|
fn seen_radix(&self) -> bool { self.radix.is_some() }
|
||||||
fn seen_sign(&self) -> bool { self.sign.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> {
|
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