rustinterpreterbrainfuck

How should I handle possible negatives in my BrainF**k interpreter?


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);
}

Solution

  • 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.