Day three
This commit is contained in:
61
day-03-rust/src/lexer.rs
Normal file
61
day-03-rust/src/lexer.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use std::io::{Bytes, Read};
|
||||
use std::iter::Peekable;
|
||||
|
||||
pub type Number = i32;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum Token {
|
||||
Identifier(String),
|
||||
Number(Number),
|
||||
Operator(u8),
|
||||
}
|
||||
|
||||
pub struct Lexer<R: Read> {
|
||||
reader: Peekable<Bytes<R>>,
|
||||
}
|
||||
|
||||
impl<R: Read> Lexer<R> {
|
||||
pub fn new(reader: R) -> Lexer<R> {
|
||||
Lexer { reader: reader.bytes().peekable() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Read> Iterator for Lexer<R> {
|
||||
type Item = Token;
|
||||
|
||||
fn next(&mut self) -> Option<Token> {
|
||||
if let Some(Ok(ch)) = self.reader.next() {
|
||||
match ch {
|
||||
b'A' ..= b'Z' | b'a' ..= b'z' | b'\'' => {
|
||||
let mut identifier = String::new();
|
||||
identifier.push(ch as char);
|
||||
while let Some(Ok(b'A' ..= b'Z' | b'a' ..= b'z' | b'\'')) = self.reader.peek() {
|
||||
identifier.push(self.reader.next().unwrap().unwrap() as char);
|
||||
}
|
||||
Some(Token::Identifier(identifier))
|
||||
}
|
||||
b'0' ..= b'9' | b'-' => {
|
||||
let negative: bool;
|
||||
let mut number: Number = 0;
|
||||
if ch == b'-' {
|
||||
negative = true;
|
||||
} else {
|
||||
negative = false;
|
||||
number = (ch - b'0') as Number;
|
||||
}
|
||||
while let Some(Ok(b'0' ..= b'9')) = self.reader.peek() {
|
||||
number *= 10;
|
||||
number += (self.reader.next().unwrap().unwrap() - b'0') as Number;
|
||||
}
|
||||
if negative {
|
||||
number *= -1;
|
||||
}
|
||||
Some(Token::Number(number))
|
||||
}
|
||||
_ => Some(Token::Operator(ch))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user