~jpl8/piet_interpreter

58c98b1976a721865948595c8892ccb27c7e830d — jpl 2 years ago fb174a5
add extra debug information
A images/99bottles_big.png => images/99bottles_big.png +0 -0
A images/ILoveYouLaura.png => images/ILoveYouLaura.png +0 -0
A images/erat2_big.png => images/erat2_big.png +0 -0
A images/hanoibig.gif => images/hanoibig.gif +0 -0
A images/helloworld-cmb.png => images/helloworld-cmb.png +0 -0
A images/helloworld-mondrian-big.png => images/helloworld-mondrian-big.png +0 -0
A images/hw3-5.gif => images/hw3-5.gif +0 -0
A images/hw6_big.png => images/hw6_big.png +0 -0
A images/japh_big.png => images/japh_big.png +0 -0
A images/nprime.gif => images/nprime.gif +0 -0
A images/piet_factorial_big.png => images/piet_factorial_big.png +0 -0
M images/primetest.png => images/primetest.png +0 -0
A images/primetest2big.png => images/primetest2big.png +0 -0
M src/interpreter/interpreter_tests.rs => src/interpreter/interpreter_tests.rs +1 -0
@@ 370,3 370,4 @@ fn whitespace_works() {
    assert_eq!(interpreter.head().pos(), (13,9));
    assert_eq!(interpreter.stack().len(), 1);
}


M src/interpreter/mod.rs => src/interpreter/mod.rs +1 -0
@@ 254,6 254,7 @@ impl Interpreter {
    }



}



M src/interpreter/rules.rs => src/interpreter/rules.rs +63 -33
@@ 103,68 103,98 @@ pub fn do_op(interpreter: &mut Interpreter, curr: &Codel, next: &Codel) -> io::R
            }

            Op::Sub => {
                let first_pop  = interpreter.stack_as_mut().pop();
                let second_pop = interpreter.stack_as_mut().pop();
                if let (Some(a), Some(b)) = (first_pop, second_pop) {
                    interpreter.stack_as_mut().push(b - a);
                    Ok(())
                if interpreter.stack.len() >= 2 {
                    let first_pop  = interpreter.stack_as_mut().pop().unwrap();
                    let second_pop = interpreter.stack_as_mut().pop().unwrap();
                    interpreter.stack_as_mut().push(second_pop - first_pop);
 
                    if interpreter.debug {
                        eprintln!("Executed: Sub({}, {}) -> {}", second_pop, first_pop, second_pop-first_pop);
                    }

                }
                else { 
                    Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    eprintln!("Not enough values on the stack! Were {}, needed 2", interpreter.stack.len());
                }

               Ok(())
            }


            Op::Mult => {
                let first_pop  = interpreter.stack_as_mut().pop();
                let second_pop = interpreter.stack_as_mut().pop();
                if let (Some(a), Some(b)) = (first_pop, second_pop) {
                    interpreter.stack_as_mut().push(b * a);
                    Ok(())
                if interpreter.stack.len() >= 2 {
                    let first_pop  = interpreter.stack_as_mut().pop().unwrap();
                    let second_pop = interpreter.stack_as_mut().pop().unwrap();
                    interpreter.stack_as_mut().push(second_pop * first_pop);

                    if interpreter.debug {
                        eprintln!("Executed: Mult({}, {}) -> {}", second_pop, first_pop, second_pop*first_pop);
                    }
                }
                else { 
                    Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    eprintln!("Not enough values on the stack! Were {}, needed 2", interpreter.stack.len());
                }
                Ok(())

            }


            Op::Div => {
                let first_pop  = interpreter.stack_as_mut().pop();
                let second_pop = interpreter.stack_as_mut().pop();
                if let (Some(a), Some(b)) = (first_pop, second_pop) {
                    if a == 0 {
                        return Err(Error::new(ErrorKind::InvalidInput, "Division by zero!"))
                if interpreter.stack.len() >= 2 {
                    let first_pop  = interpreter.stack_as_mut().pop().unwrap();
                    let second_pop = interpreter.stack_as_mut().pop().unwrap();
                    if first_pop == 0 {
                        return Ok(());
                    }
                    interpreter.stack_as_mut().push(second_pop / first_pop);

                    if interpreter.debug {
                        eprintln!("Executed: Div({}, {}) -> {}", second_pop, first_pop, second_pop/first_pop);
                    }
                    interpreter.stack_as_mut().push(b / a);
                    Ok(())
                }
                else { 
                    Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    eprintln!("Not enough values on the stack! Were {}, needed 2", interpreter.stack.len());
                }

                Ok(())
            }

            Op::Mod => {
                let first_pop  = interpreter.stack_as_mut().pop();
                let second_pop = interpreter.stack_as_mut().pop();
                if let (Some(a), Some(b)) = (first_pop, second_pop) {
                    if a == 0 {
                        return Err(Error::new(ErrorKind::InvalidInput, "Division by zero!"))
                if interpreter.stack.len() >= 2 {
                let first_pop  = interpreter.stack_as_mut().pop().unwrap();
                let second_pop = interpreter.stack_as_mut().pop().unwrap();
                    if first_pop == 0 {
                        eprintln!("Division by zero!");
                        return Ok(()); 
                    }

                    interpreter.stack_as_mut().push(second_pop % first_pop + if second_pop%first_pop < 0 { first_pop } else { 0 });

                    if interpreter.debug {
                        eprintln!("Executed: Div({}, {}) -> {}", second_pop, first_pop, second_pop/first_pop);
                    }
                    interpreter.stack_as_mut().push(b % a + if b%a < 0 { a } else { 0 } );
                    Ok(())
                }
                else { 
                    Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    eprintln!("Not enough values on the stack! Were {}, needed 2", interpreter.stack.len());
                }
                Ok(())

            }

            Op::Not => {
                if interpreter.stack().len() == 0 { return Ok(()); }
                if interpreter.stack_as_mut().pop() == Some(0) { interpreter.stack_as_mut().push(1) } else { interpreter.stack_as_mut().push(0) }
                if interpreter.stack().len() > 0 { 
                    let popped = interpreter.stack_as_mut().pop().unwrap();
                    let negated = if popped == 0 { 1 } else { 0 };

                    interpreter.stack_as_mut().push(negated);

                    if interpreter.debug {
                        eprintln!("Executed: Not({}) -> {}", popped, negated);
                    }
                    
                }
                else {
                    eprintln!("Not enough values on the stack! Were {}, needed 1", interpreter.stack.len());
                }
                Ok(())
            }



@@ 260,6 290,7 @@ pub fn do_op(interpreter: &mut Interpreter, curr: &Codel, next: &Codel) -> io::R
            Op::InNum => {
                let mut input = String::with_capacity(8);
                // Ignore errors (it's what the author recommended)
                io::stdout().flush().expect("Failed to flush to stdout!");
                if let Err(_) = io::stdin().read_line(&mut input) {
                    return Ok(());
                }


@@ 274,6 305,7 @@ pub fn do_op(interpreter: &mut Interpreter, curr: &Codel, next: &Codel) -> io::R
            Op::InChar => {
                let mut input = String::with_capacity(8);
                // Ignore errors (it's what the author recommended)
                io::stdout().flush().expect("Failed to flush to stdout!");
                if let Err(_) = io::stdin().read_line(&mut input) {
                    return Ok(());
                }


@@ 290,7 322,6 @@ pub fn do_op(interpreter: &mut Interpreter, curr: &Codel, next: &Codel) -> io::R
            Op::OutNum => {
                if let Some(val) = interpreter.stack_as_mut().pop() {
                        print!("{}", val);
                        io::stdout().flush().expect("Failed to flush to stdout!");
                }
                Ok(())
            }


@@ 300,7 331,6 @@ pub fn do_op(interpreter: &mut Interpreter, curr: &Codel, next: &Codel) -> io::R
                if let Some(val) = interpreter.stack_as_mut().pop() {
                    if let Some(c) = char::from_u32(val as u32) {
                        print!("{}", c);
                        io::stdout().flush().expect("Failed to flush to stdout!");
                    }
                }
                Ok(())

M src/main.rs => src/main.rs +6 -0
@@ 22,6 22,12 @@ fn main() {
            .long("debug")
            .help("Enable debug information")
        )
        .arg(
            Arg::with_name("codel_size")
            .short("c")
            .long("codel_size")
            .help("Codel size to interpret")
        )
        .get_matches();



M src/translator.rs => src/translator.rs +5 -6
@@ 35,8 35,7 @@ where P: AsRef<Path>
    return Ok(PietImage::new(dimensions, upscaled_codels));
    

}

} 
pub fn codel_size(codels: &Vec<Vec<Codel>>) -> u32 {
    let mut min_width = usize::MAX;
    for row in codels {


@@ 74,15 73,15 @@ pub fn codel_size(codels: &Vec<Vec<Codel>>) -> u32 {

}

#[cfg(test)]

mod tests {
    use crate::color::Color;
    use super::*;
    #[test]
    fn upscale_works() {
        let img = to_piet_img("images/test_upscale.png").expect("Error on new");
        assert_eq!(codel_size(img.codels()), 4);

    
    }

}