bfin/src/tokenizer.rs

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
}