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 }
|
|
}
|
|
}
|
|
|
|
pub fn tokenize(program: Vec<u8>) -> Vec<Token> {
|
|
let mut tokens = vec![];
|
|
|
|
let mut ip = 0;
|
|
while ip < program.len() {
|
|
let Some(instruction) = program.get(ip) else {
|
|
break;
|
|
};
|
|
|
|
ip += 1;
|
|
|
|
match instruction {
|
|
b'+' => {
|
|
let count = check_next(&program, &mut ip, instruction);
|
|
tokens.push(Token::new(TokenType::Plus(count)));
|
|
}
|
|
b'-' => {
|
|
let count = check_next(&program, &mut ip, instruction);
|
|
tokens.push(Token::new(TokenType::Minus(count)));
|
|
}
|
|
b'>' => {
|
|
let count = check_next(&program, &mut ip, instruction);
|
|
tokens.push(Token::new(TokenType::MoveRight(count)));
|
|
}
|
|
b'<' => {
|
|
let count = check_next(&program, &mut ip, instruction);
|
|
tokens.push(Token::new(TokenType::MoveLeft(count)));
|
|
}
|
|
b'.' => {
|
|
tokens.push(Token::new(TokenType::Output));
|
|
}
|
|
b',' => {
|
|
tokens.push(Token::new(TokenType::Input));
|
|
}
|
|
b'[' => {}
|
|
b']' => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
// dbg!(&tokens);
|
|
|
|
tokens
|
|
}
|
|
|
|
fn check_next(program: &[u8], ip: &mut usize, instruction: &u8) -> u32 {
|
|
let mut icount = 1;
|
|
let mut next_instruction = program.get(*ip);
|
|
while let Some(next) = next_instruction
|
|
&& *next == *instruction
|
|
{
|
|
icount += 1;
|
|
*ip += 1;
|
|
next_instruction = program.get(*ip);
|
|
}
|
|
|
|
icount
|
|
}
|