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)]
pub struct LexingError {
pub line: usize,
pub msg: String,
pub kind: LexingErrorKind,
}
impl fmt::Display for LexingError {
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 {
fn description(&self) -> &str {
&self.msg
fn source(&self) -> Option<&(dyn Error + 'static)> {
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;
use self::error::LexingErrorKind;
use self::token::Token;
#[derive(Debug)]
@ -101,14 +102,18 @@ impl<'a> Lexer<'a> {
token::TokenType::Greater,
),
'"' => {
let mut string = String::with_capacity(128);
let mut string = String::new();
let unmatched_char_error = Some(Err(LexingError {
line: self.line,
msg: "Unmatched \" character".to_string(),
kind: LexingErrorKind::UnmatchedQuote,
}));
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('\\') => match self.source_iter.next() {
Some(c) => string.push(c),
@ -122,19 +127,14 @@ impl<'a> Lexer<'a> {
}
c @ '0'..='9' => {
let mut num: i64 = c.to_digit(10).unwrap() as i64;
while let Some(c) = self.source_iter.peek() {
match c {
c@'0'..='9' => {
while let Some(c) = self.source_iter.next_if(|c| c.is_digit(10)) {
num *= 10;
num += c.to_digit(10).unwrap() as i64;
},
_ => break,
}
}
self.get_token(token::TokenType::Int(num))
},
}
c @ 'a'..='z' | c @ 'A'..='Z' => {
let mut identifier = String::with_capacity(128);
let mut identifier = String::new();
identifier.push(c);
while let Some(c) = self.source_iter.next_if(|c| c.is_alphanumeric()) {
identifier.push(c);
@ -154,10 +154,9 @@ impl<'a> Lexer<'a> {
"let" => token::TokenType::Let,
"While" => token::TokenType::While,
"or" => token::TokenType::Or,
_ => token::TokenType::Identifier(identifier)
_ => token::TokenType::Identifier(identifier),
})
},
}
// Ignore whitespace
' ' | '\r' | '\t' => return None,
'\n' => {
@ -167,7 +166,7 @@ impl<'a> Lexer<'a> {
c => {
return Some(Err(LexingError {
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() {
let mut line_buf = String::with_capacity(1024);
let mut line_buf = String::new();
loop {
match io::stdin().read_line(&mut line_buf) {
Ok(_) => {