diff --git a/lexer/src/lib.rs b/lexer/src/lib.rs index dd947a9..449afc3 100644 --- a/lexer/src/lib.rs +++ b/lexer/src/lib.rs @@ -62,7 +62,7 @@ impl Iterator for Lexer where T: Iterator { out = Some(Ok(Lex::new(token, &buffer, self.line, self.offset))); break; }, - Err(msg) => panic!("{}", msg) + Err(err) => panic!("{}:{}: {}", self.line, self.offset, err.msg()) }, Some(c) => { let result = state.lex(c); @@ -84,8 +84,8 @@ impl Iterator for Lexer where T: Iterator { out = Some(Ok(Lex::new(token, &buffer, self.line, self.offset))); break; }, - StateResult::Fail { msg } => { - panic!("{}", msg); + StateResult::Fail(err) => { + panic!("{}:{}: {}", self.line, self.offset, err.msg()); } } }, diff --git a/lexer/src/states/begin.rs b/lexer/src/states/begin.rs index cea8aa5..b4d9732 100644 --- a/lexer/src/states/begin.rs +++ b/lexer/src/states/begin.rs @@ -3,6 +3,7 @@ */ use chars::Lexable; +use error::Error; use token::Token; use states::{Resume, State, StateResult}; use states::id::IdSub; @@ -20,14 +21,11 @@ impl State for Begin { c if c.is_whitespace() => StateResult::Continue, c if c.is_identifier_initial() => StateResult::Advance { to: Box::new(IdSub{}) }, c if c.is_hash() => StateResult::Advance { to: Box::new(Hash::new()) }, - _ => { - let msg = format!("Invalid character: {}", c); - StateResult::Fail { msg } - } + _ => StateResult::fail(Error::invalid_char(c)), } } - fn none(&mut self) -> Result, String> { + fn none(&mut self) -> Result, Error> { Ok(None) } } diff --git a/lexer/src/states/bool.rs b/lexer/src/states/bool.rs index 20796f2..c9a52e0 100644 --- a/lexer/src/states/bool.rs +++ b/lexer/src/states/bool.rs @@ -2,6 +2,7 @@ * Eryn Wells */ +use error::Error; use chars::Lexable; use states::{Resume, State, StateResult}; use token::Token; @@ -34,10 +35,7 @@ impl State for Bool { match c { c if c.is_identifier_delimiter() => match self.handle_delimiter() { Some(token) => StateResult::Emit(token, Resume::Here), - None => { - let msg = format!("Invalid character: {}", c); - StateResult::fail(msg.as_str()) - }, + None => StateResult::fail(Error::invalid_char(c)), }, _ => { let buf = { @@ -48,20 +46,16 @@ impl State for Bool { if TRUE.starts_with(&buf) || FALSE.starts_with(&buf) { StateResult::advance(Box::new(Bool(buf))) } else { - let msg = format!("Invalid character: {}", c); - StateResult::fail(msg.as_str()) + StateResult::fail(Error::invalid_char(c)) } }, } } - fn none(&mut self) -> Result, String> { + fn none(&mut self) -> Result, Error> { match self.handle_delimiter() { Some(token) => Ok(Some(token)), - None => { - let msg = format!("Found EOF while trying to parse a bool"); - Err(msg) - } + None => Err(Error::new("Found EOF while trying to parse a bool".to_string())) } } } diff --git a/lexer/src/states/hash.rs b/lexer/src/states/hash.rs index 04f078b..9123773 100644 --- a/lexer/src/states/hash.rs +++ b/lexer/src/states/hash.rs @@ -3,6 +3,7 @@ */ use chars::Lexable; +use error::Error; use states::{State, StateResult}; use states::bool::Bool; use states::number::Prefix; @@ -30,17 +31,14 @@ impl State for Hash { if let Some(st) = Prefix::with_char(c) { StateResult::advance(Box::new(st)) } else { - StateResult::fail(format!("invalid numeric prefix character: {}", c).as_str()) + StateResult::fail(Error::new(format!("invalid numeric prefix character: {}", c))) } }, - _ => { - let msg = format!("Invalid character: {}", c); - StateResult::fail(msg.as_str()) - }, + _ => StateResult::fail(Error::invalid_char(c)), } } - fn none(&mut self) -> Result, String> { + fn none(&mut self) -> Result, Error> { Ok(None) } } diff --git a/lexer/src/states/id.rs b/lexer/src/states/id.rs index 0232c00..bd792ce 100644 --- a/lexer/src/states/id.rs +++ b/lexer/src/states/id.rs @@ -3,6 +3,7 @@ */ use chars::Lexable; +use error::Error; use states::{Resume, State, StateResult}; use token::Token; @@ -14,14 +15,11 @@ impl State for IdSub { match c { c if c.is_identifier_subsequent() => StateResult::Continue, c if c.is_identifier_delimiter() => StateResult::Emit(Token::Id, Resume::Here), - _ => { - let msg = format!("Invalid character: {}", c); - StateResult::Fail { msg } - } + _ => StateResult::fail(Error::invalid_char(c)), } } - fn none(&mut self) -> Result, String> { + fn none(&mut self) -> Result, Error> { Ok(Some(Token::Id)) } } diff --git a/lexer/src/states/mod.rs b/lexer/src/states/mod.rs index 3c6194d..33f0360 100644 --- a/lexer/src/states/mod.rs +++ b/lexer/src/states/mod.rs @@ -3,6 +3,7 @@ */ use std::fmt::Debug; +use error::Error; use token::Token; mod begin; @@ -22,7 +23,7 @@ pub enum StateResult { /// Emit a Lex with the provided Token and the accumulated buffer. The Resume value indicates /// whether to revisit the current input character or advance to the next one. Emit(Token, Resume), - Fail { msg: String } + Fail(Error) } #[derive(Debug, Eq, PartialEq)] @@ -35,7 +36,7 @@ pub enum Resume { pub trait State: Debug { fn lex(&mut self, c: char) -> StateResult; - fn none(&mut self) -> Result, String>; + fn none(&mut self) -> Result, Error>; } impl StateResult { @@ -47,7 +48,7 @@ impl StateResult { StateResult::Emit(token, at) } - pub fn fail(msg: &str) -> StateResult { - StateResult::Fail { msg: msg.to_string() } + pub fn fail(err: Error) -> StateResult { + StateResult::Fail(err) } } diff --git a/lexer/src/states/number/prefix.rs b/lexer/src/states/number/prefix.rs index 9c68043..fbb7460 100644 --- a/lexer/src/states/number/prefix.rs +++ b/lexer/src/states/number/prefix.rs @@ -2,8 +2,9 @@ * Eryn Wells */ -use super::{Radix, Exact}; +use error::Error; use states::{State, StateResult}; +use states::number::{Radix, Exact}; use states::number::Builder; use token::Token; @@ -32,12 +33,12 @@ impl State for Prefix { fn lex(&mut self, c: char) -> StateResult { match c { '#' => StateResult::advance(Box::new(Hash(self.0))), - _ => StateResult::fail(format!("invalid char: {}", c).as_str()) + _ => StateResult::fail(Error::invalid_char(c)) } } - fn none(&mut self) -> Result, String> { - Err("blah".to_string()) + fn none(&mut self) -> Result, Error> { + Err(Error::new("blah".to_string())) } } @@ -48,21 +49,21 @@ impl State for Hash { self.0.push_exact(ex); StateResult::advance(Box::new(Prefix::new(self.0))) } else { - StateResult::fail(format!("invalid char: {}", c).as_str()) + 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(format!("invalid char: {}", c).as_str()) + StateResult::fail(Error::invalid_char(c)) } } else { - StateResult::fail(format!("invalid char: {}", c).as_str()) + StateResult::fail(Error::invalid_char(c)) } } - fn none(&mut self) -> Result, String> { - Err("blah".to_string()) + fn none(&mut self) -> Result, Error> { + Err(Error::new("blah".to_string())) } }