82 lines
1.9 KiB
Rust
82 lines
1.9 KiB
Rust
|
#[derive(Debug)]
|
||
|
pub enum TokenType {
|
||
|
Plus(u32),
|
||
|
Minus(u32),
|
||
|
MoveRight(u32),
|
||
|
MoveLeft(u32),
|
||
|
Output,
|
||
|
Input,
|
||
|
BracketOpen,
|
||
|
BracketClose,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Token {
|
||
|
pub r#type: TokenType,
|
||
|
}
|
||
|
|
||
|
impl Token {
|
||
|
fn new(r#type: TokenType) -> Self {
|
||
|
Self { r#type }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Default)]
|
||
|
pub struct Tokenizer {
|
||
|
index: u32,
|
||
|
}
|
||
|
|
||
|
impl Tokenizer {
|
||
|
pub fn tokenize(&self, program: Vec<u8>) -> Vec<Token> {
|
||
|
let mut tokens = vec![];
|
||
|
|
||
|
let mut ip = 0;
|
||
|
let mut icount = 0;
|
||
|
while ip < program.len() {
|
||
|
let Some(instruction) = program.get(ip) else {
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
let next_instruction = program.get(&ip + 1);
|
||
|
|
||
|
ip += 1;
|
||
|
|
||
|
match instruction {
|
||
|
b'+' => {
|
||
|
icount += 1;
|
||
|
if let Some(next) = next_instruction
|
||
|
&& *next == b'+'
|
||
|
{
|
||
|
continue;
|
||
|
} else {
|
||
|
tokens.push(Token::new(TokenType::Plus(icount)));
|
||
|
icount = 0;
|
||
|
}
|
||
|
}
|
||
|
b'-' => {
|
||
|
icount += 1;
|
||
|
if let Some(next) = next_instruction
|
||
|
&& *next == b'-'
|
||
|
{
|
||
|
continue;
|
||
|
} else {
|
||
|
tokens.push(Token::new(TokenType::Minus(icount)));
|
||
|
icount = 0;
|
||
|
}
|
||
|
}
|
||
|
b'>' => {}
|
||
|
b'<' => {}
|
||
|
b'.' => {
|
||
|
tokens.push(Token::new(TokenType::Output));
|
||
|
}
|
||
|
b',' => {}
|
||
|
b'[' => {}
|
||
|
b']' => {}
|
||
|
_ => {}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
tokens
|
||
|
}
|
||
|
}
|