[lexer] We can lex integers!

This commit is contained in:
Eryn Wells 2018-09-03 17:17:49 -07:00
parent d272b211ae
commit 853312ce67
4 changed files with 24 additions and 14 deletions

View file

@ -8,20 +8,28 @@ use token::Token;
use states::{Resume, State, StateResult}; use states::{Resume, State, StateResult};
use states::id::IdSub; use states::id::IdSub;
use states::hash::Hash; use states::hash::Hash;
use states::number::{Builder, Digit};
#[derive(Debug)] #[derive(Debug)]
pub struct Begin; pub struct Begin;
impl State for Begin { impl State for Begin {
fn lex(&mut self, c: char) -> StateResult { fn lex(&mut self, c: char) -> StateResult {
match c { if c.is_left_paren() {
c if c.is_left_paren() => StateResult::Emit(Token::LeftParen, Resume::AtNext), StateResult::Emit(Token::LeftParen, Resume::AtNext)
c if c.is_right_paren() => StateResult::Emit(Token::RightParen, 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. // TODO: Figure out some way to track newlines.
c if c.is_whitespace() => StateResult::Continue, StateResult::Continue
c if c.is_identifier_initial() => StateResult::Advance { to: Box::new(IdSub{}) }, } else if c.is_identifier_initial() {
c if c.is_hash() => StateResult::Advance { to: Box::new(Hash::new()) }, StateResult::advance(Box::new(IdSub{}))
_ => StateResult::fail(Error::invalid_char(c)), } else if c.is_hash() {
StateResult::advance(Box::new(Hash::new()))
} else if let Some(st) = Digit::with_char(Builder::new(), c) {
StateResult::advance(Box::new(st))
} else {
StateResult::fail(Error::invalid_char(c))
} }
} }

View file

@ -39,7 +39,7 @@ impl State for Hash {
} }
fn none(&mut self) -> Result<Option<Token>, Error> { fn none(&mut self) -> Result<Option<Token>, Error> {
Ok(None) Err(Error::unexpected_eof())
} }
} }

View file

@ -2,11 +2,9 @@
* Eryn Wells <eryn@erynwells.me> * Eryn Wells <eryn@erynwells.me>
*/ */
use chars::Lexable;
use error::Error; use error::Error;
use states::{State, StateResult}; use states::{State, StateResult};
use states::number::{Builder, Radix, Exact}; use states::number::{Builder, Radix, Exact};
use states::number::sign::Sign;
use token::Token; use token::Token;
#[derive(Debug)] pub struct Digit(Builder); #[derive(Debug)] pub struct Digit(Builder);
@ -39,6 +37,6 @@ impl State for Digit {
} }
fn none(&mut self) -> Result<Option<Token>, Error> { fn none(&mut self) -> Result<Option<Token>, Error> {
Err(Error::unexpected_eof()) Ok(Some(Token::Num(self.0.resolve())))
} }
} }

View file

@ -9,6 +9,7 @@ mod prefix;
mod sign; mod sign;
pub use self::prefix::Prefix; pub use self::prefix::Prefix;
pub use self::digit::Digit;
#[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 }
@ -83,9 +84,12 @@ impl Builder {
} }
fn resolve(&self) -> i64 { fn resolve(&self) -> i64 {
//let sign_factor: i64 = if let Some(sign) = self.sign { sign as i64 } else { 1 }; let sign_factor: i64 = if let Some(sign) = self.sign {
//self.value * sign_factor sign as i64
0 } else {
1
};
self.value * sign_factor
} }
fn seen_exact(&self) -> bool { self.exact.is_some() } fn seen_exact(&self) -> bool { self.exact.is_some() }