Refactoring

This commit is contained in:
bad 2022-03-21 18:42:47 +01:00
parent 5b0263c89f
commit 8b967efda7
3 changed files with 41 additions and 25 deletions

View file

@ -4,17 +4,34 @@ use std::error::Error;
#[derive(Debug)] #[derive(Debug)]
pub struct LexingError { pub struct LexingError {
pub line: usize, pub line: usize,
pub msg: String, pub kind: LexingErrorKind,
} }
impl fmt::Display for LexingError { impl fmt::Display for LexingError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Error on line: {}", self.line) write!(f, "Error: {}\n on line: {}", self.kind, self.line)
} }
} }
impl Error for LexingError { impl Error for LexingError {
fn description(&self) -> &str { fn source(&self) -> Option<&(dyn Error + 'static)> {
&self.msg Some(&self.kind)
} }
} }
#[derive(Debug)]
pub enum LexingErrorKind {
UnmatchedQuote,
UnexpectedCharacter(char),
}
impl fmt::Display for LexingErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LexingErrorKind::UnmatchedQuote => write!(f, "Unmatched \" character"),
LexingErrorKind::UnexpectedCharacter(c) => write!(f, "Unexpected character {c}"),
}
}
}
impl Error for LexingErrorKind {}

View file

@ -5,6 +5,7 @@ use std::str::Chars;
pub use error::LexingError; pub use error::LexingError;
use self::error::LexingErrorKind;
use self::token::Token; use self::token::Token;
#[derive(Debug)] #[derive(Debug)]
@ -101,14 +102,18 @@ impl<'a> Lexer<'a> {
token::TokenType::Greater, token::TokenType::Greater,
), ),
'"' => { '"' => {
let mut string = String::with_capacity(128); let mut string = String::new();
let unmatched_char_error = Some(Err(LexingError { let unmatched_char_error = Some(Err(LexingError {
line: self.line, line: self.line,
msg: "Unmatched \" character".to_string(), kind: LexingErrorKind::UnmatchedQuote,
})); }));
loop { loop {
match self.source_iter.next() { let next_char = self.source_iter.next();
if let Some('\n') = next_char {
self.line+=1;
}
match next_char {
Some('"') => break, Some('"') => break,
Some('\\') => match self.source_iter.next() { Some('\\') => match self.source_iter.next() {
Some(c) => string.push(c), Some(c) => string.push(c),
@ -122,19 +127,14 @@ impl<'a> Lexer<'a> {
} }
c @ '0'..='9' => { c @ '0'..='9' => {
let mut num: i64 = c.to_digit(10).unwrap() as i64; let mut num: i64 = c.to_digit(10).unwrap() as i64;
while let Some(c) = self.source_iter.peek() { while let Some(c) = self.source_iter.next_if(|c| c.is_digit(10)) {
match c {
c@'0'..='9' => {
num *= 10; num *= 10;
num += c.to_digit(10).unwrap() as i64; num += c.to_digit(10).unwrap() as i64;
},
_ => break,
}
} }
self.get_token(token::TokenType::Int(num)) self.get_token(token::TokenType::Int(num))
}, }
c @ 'a'..='z' | c @ 'A'..='Z' => { c @ 'a'..='z' | c @ 'A'..='Z' => {
let mut identifier = String::with_capacity(128); let mut identifier = String::new();
identifier.push(c); identifier.push(c);
while let Some(c) = self.source_iter.next_if(|c| c.is_alphanumeric()) { while let Some(c) = self.source_iter.next_if(|c| c.is_alphanumeric()) {
identifier.push(c); identifier.push(c);
@ -154,10 +154,9 @@ impl<'a> Lexer<'a> {
"let" => token::TokenType::Let, "let" => token::TokenType::Let,
"While" => token::TokenType::While, "While" => token::TokenType::While,
"or" => token::TokenType::Or, "or" => token::TokenType::Or,
_ => token::TokenType::Identifier(identifier) _ => token::TokenType::Identifier(identifier),
}) })
}, }
// Ignore whitespace // Ignore whitespace
' ' | '\r' | '\t' => return None, ' ' | '\r' | '\t' => return None,
'\n' => { '\n' => {
@ -167,7 +166,7 @@ impl<'a> Lexer<'a> {
c => { c => {
return Some(Err(LexingError { return Some(Err(LexingError {
line: self.line, line: self.line,
msg: format!("Unexpected character: {c}"), kind: LexingErrorKind::UnexpectedCharacter(c),
})) }))
} }
})) }))

View file

@ -12,7 +12,7 @@ fn run_file(file: &path::Path) -> Result<(), io::Error> {
} }
fn run_repl() { fn run_repl() {
let mut line_buf = String::with_capacity(1024); let mut line_buf = String::new();
loop { loop {
match io::stdin().read_line(&mut line_buf) { match io::stdin().read_line(&mut line_buf) {
Ok(_) => { Ok(_) => {