Refactoring
This commit is contained in:
parent
5b0263c89f
commit
8b967efda7
3 changed files with 41 additions and 25 deletions
|
@ -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 {}
|
||||
|
|
|
@ -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),
|
||||
|
@ -120,26 +125,21 @@ impl<'a> Lexer<'a> {
|
|||
}
|
||||
self.get_token(token::TokenType::String(string))
|
||||
}
|
||||
c@'0'..='9' => {
|
||||
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' => {
|
||||
num *= 10;
|
||||
num += c.to_digit(10).unwrap() as i64;
|
||||
},
|
||||
_ => break,
|
||||
}
|
||||
while let Some(c) = self.source_iter.next_if(|c| c.is_digit(10)) {
|
||||
num *= 10;
|
||||
num += c.to_digit(10).unwrap() as i64;
|
||||
}
|
||||
self.get_token(token::TokenType::Int(num))
|
||||
},
|
||||
c@'a'..='z' | c@'A'..='Z' => {
|
||||
let mut identifier = String::with_capacity(128);
|
||||
}
|
||||
c @ 'a'..='z' | c @ 'A'..='Z' => {
|
||||
let mut identifier = String::new();
|
||||
identifier.push(c);
|
||||
while let Some(c) = self.source_iter.next_if(|c| c.is_alphanumeric()) {
|
||||
identifier.push(c);
|
||||
}
|
||||
|
||||
|
||||
self.get_token(match identifier.as_str() {
|
||||
"and" => token::TokenType::And,
|
||||
"else" => token::TokenType::Else,
|
||||
|
@ -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),
|
||||
}))
|
||||
}
|
||||
}))
|
||||
|
|
|
@ -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(_) => {
|
||||
|
|
Loading…
Reference in a new issue