I'm building my first interpreter to learn Rust better, and I'm sort of stuck on this problem, because me tape/memory is a vector of unsigned 8-bit integers, but loops sometimes result on negatives.
I'm trying to execute this code in BF (which should result in "hello"):
+[----->+++<]>+.---.+++++++..+++.
I keep getting "attempted to subtract with overflow" because the first loop turns the bit into a negative, when it should stop when it notices that it's a 0.
Here's my function:
fn compile(code: Vec<Operations>) {
// Memory vector is of arbitrary length for now //
let mut memory: Vec<u8> = vec![0; 1000];
let mut mem_ptr = 0;
let mut code_ptr = 0;
let mut bracket_idx: Vec<usize> = Vec::new();
println!("{:?}", code);
while code_ptr < code.len() {
let command = code[code_ptr];
match command {
Operations::IncrementByte => memory[mem_ptr] += 1,
Operations::DecrementByte => memory[mem_ptr] -= 1,
Operations::IncrementPtr => mem_ptr += 1,
Operations::DecrementPtr => mem_ptr -= 1,
Operations::Read => log_ptr(&[memory[mem_ptr] as u8]),
Operations::StartLoop => bracket_idx.push(code_ptr),
Operations::EndLoop => {
if memory[mem_ptr] != 0 {
code_ptr = *bracket_idx.last().unwrap()
}
else {
bracket_idx.pop();
}
},
_ => println!("ERROR")
};
code_ptr += 1;
}
println!("{:?}", memory);
}
The first time you enter the loop, the current value will be 1 (because there's one +
before the loop). Inside the loop, you then subtract 5 from that value (because there are 5 -
s). So this program will simply not work if subtracting from 0 causes an overflow error.
So to make this program work, you'll need to use the wrapping_*
family of methods to get wrap around instead of panics on overflow.