Added == and != along with tests
This commit is contained in:
parent
c0efc2c316
commit
420db45c76
|
@ -33,6 +33,8 @@ pub enum Token {
|
||||||
ExclamationMark,
|
ExclamationMark,
|
||||||
LessThan,
|
LessThan,
|
||||||
GreaterThan,
|
GreaterThan,
|
||||||
|
Equals,
|
||||||
|
NotEquals,
|
||||||
|
|
||||||
// Delimiter
|
// Delimiter
|
||||||
Comma,
|
Comma,
|
||||||
|
@ -75,11 +77,9 @@ impl<'a> Lexer<'a> {
|
||||||
fn read_identifier(&mut self, first: char) -> String {
|
fn read_identifier(&mut self, first: char) -> String {
|
||||||
let mut ident = Vec::new();
|
let mut ident = Vec::new();
|
||||||
ident.push(first);
|
ident.push(first);
|
||||||
|
|
||||||
while self.peek_is_letter() {
|
while self.peek_is_letter() {
|
||||||
ident.push(self.read_char().unwrap());
|
ident.push(self.read_char().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
ident.into_iter().collect::<String>()
|
ident.into_iter().collect::<String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,11 +110,9 @@ impl<'a> Lexer<'a> {
|
||||||
fn read_number(&mut self, first: char) -> i64 {
|
fn read_number(&mut self, first: char) -> i64 {
|
||||||
let mut number = Vec::new();
|
let mut number = Vec::new();
|
||||||
number.push(first);
|
number.push(first);
|
||||||
|
|
||||||
while self.peek_is_ascii_digit() {
|
while self.peek_is_ascii_digit() {
|
||||||
number.push(self.read_char().unwrap());
|
number.push(self.read_char().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
number
|
number
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<String>()
|
.collect::<String>()
|
||||||
|
@ -131,7 +129,18 @@ impl<'a> Iterator for Lexer<'a> {
|
||||||
let ch = self.read_char();
|
let ch = self.read_char();
|
||||||
|
|
||||||
let v = match ch {
|
let v = match ch {
|
||||||
Some('=') => Some(Token::Assign),
|
Some('=') => {
|
||||||
|
let is_e = match self.input.peek() {
|
||||||
|
Some(v) if *v == '=' => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if is_e {
|
||||||
|
self.read_char();
|
||||||
|
Some(Token::Equals)
|
||||||
|
} else {
|
||||||
|
Some(Token::Assign)
|
||||||
|
}
|
||||||
|
}
|
||||||
Some('+') => Some(Token::Plus),
|
Some('+') => Some(Token::Plus),
|
||||||
Some('*') => Some(Token::Multiply),
|
Some('*') => Some(Token::Multiply),
|
||||||
Some('/') => Some(Token::Divide),
|
Some('/') => Some(Token::Divide),
|
||||||
|
@ -142,7 +151,18 @@ impl<'a> Iterator for Lexer<'a> {
|
||||||
Some(')') => Some(Token::RParen),
|
Some(')') => Some(Token::RParen),
|
||||||
Some('{') => Some(Token::LBrace),
|
Some('{') => Some(Token::LBrace),
|
||||||
Some('}') => Some(Token::RBrace),
|
Some('}') => Some(Token::RBrace),
|
||||||
Some('!') => Some(Token::ExclamationMark),
|
Some('!') => {
|
||||||
|
let is_ne = match self.input.peek() {
|
||||||
|
Some(v) if *v == '=' => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if is_ne {
|
||||||
|
self.read_char();
|
||||||
|
Some(Token::NotEquals)
|
||||||
|
} else {
|
||||||
|
Some(Token::ExclamationMark)
|
||||||
|
}
|
||||||
|
}
|
||||||
Some('>') => Some(Token::GreaterThan),
|
Some('>') => Some(Token::GreaterThan),
|
||||||
Some('<') => Some(Token::LessThan),
|
Some('<') => Some(Token::LessThan),
|
||||||
Some(ch @ _) if is_letter(&ch) => {
|
Some(ch @ _) if is_letter(&ch) => {
|
||||||
|
@ -165,7 +185,7 @@ impl<'a> Iterator for Lexer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_letter(c: &char) -> bool {
|
fn is_letter(c: &char) -> bool {
|
||||||
c.is_ascii_alphabetic() || c == &'_'
|
c.is_ascii_alphabetic() || *c == '_'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_ident(ident: &str) -> Token {
|
fn lookup_ident(ident: &str) -> Token {
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -87,6 +87,10 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10 == 10;
|
||||||
|
9 != 10;
|
||||||
|
|
||||||
",
|
",
|
||||||
vec![
|
vec![
|
||||||
Token::Let,
|
Token::Let,
|
||||||
|
@ -128,13 +132,21 @@ mod tests {
|
||||||
Token::False,
|
Token::False,
|
||||||
Token::Semicolon,
|
Token::Semicolon,
|
||||||
Token::RBrace,
|
Token::RBrace,
|
||||||
|
Token::Int(10),
|
||||||
|
Token::Equals,
|
||||||
|
Token::Int(10),
|
||||||
|
Token::Semicolon,
|
||||||
|
Token::Int(9),
|
||||||
|
Token::NotEquals,
|
||||||
|
Token::Int(10),
|
||||||
|
Token::Semicolon,
|
||||||
Token::EOF,
|
Token::EOF,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
for (k, v) in tests {
|
for (k, v) in tests {
|
||||||
let tokenized_output = Lexer::new(k).collect::<Vec<Token>>();
|
let tokenized_output = Lexer::new(k).collect::<Vec<Token>>();
|
||||||
// assert_eq!(v.len(), tokenized_output.len());
|
assert_eq!(v.len(), tokenized_output.len());
|
||||||
|
|
||||||
for (exp, actual) in v.into_iter().zip(tokenized_output) {
|
for (exp, actual) in v.into_iter().zip(tokenized_output) {
|
||||||
if actual != exp {
|
if actual != exp {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user