es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo debo manejar los posibles errores en mi intérprete de BrainF**k?

Estoy construyendo mi primer intérprete para aprender mejor Rust, y estoy un poco atascado en este problema, porque mi cinta/memoria es un vector de enteros sin signo de 8 bits, pero a veces los bucles resultan en números negativos.

Estoy tratando de ejecutar este código en BF (que debe resultar en “hola”):

none
+[----->+++<]>+.---.+++++++..+++.

Sigo obteniendo “intentó restar con desbordamiento” porque el primer bucle convierte el bit en un número negativo, cuando debería detenerse cuando note que es un 0.

Aquí está mi función:

“`rust
fn compile(code: Vec<operations>) {
// El vector de memoria tiene una longitud arbitraria por ahora //
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);

<pre><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);
</code></pre>

}
“`

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución a este problema es cambiar el tipo de dato del vector de memoria de u8 a i8 (entero con signo de 8 bits), para que pueda contener tanto valores positivos como negativos.

    Otra solución es modificar los comandos de bucle para verificar los valores negativos y tratarlos como cero en lugar de restarles. Por ejemplo, el comando de bucle [ se puede modificar de la siguiente manera:

    Operations::StartLoop => {
        if memory[mem_ptr] == 0 {
            // saltar el bucle si el valor actual es cero
            let mut level = 1;
            while level > 0 {
                code_ptr += 1;
                let next_command = code[code_ptr];
                if next_command == Operations::StartLoop {
                    level += 1;
                } else if next_command == Operations::EndLoop {
                    level -= 1;
                }
            }
        } else {
            bracket_idx.push(code_ptr);
        }
    },
    

    Esto modifica el comando de bucle para verificar si el valor actual de memoria es cero, y saltar completamente el bucle si lo es. Si el valor no es cero, agrega el puntero de código actual a la pila de índices de corchetes como antes.

    Ten en cuenta que esta modificación asume que el código BF de entrada no contiene bucles que dependan de valores negativos para terminar. En ese caso, el tipo de dato del vector de memoria debería cambiarse para manejar adecuadamente los valores negativos.

Comments are closed.