~jpl8/piet_interpreter

57afb7ec599a47e3174ecaa91314d4387ed893d8 — jpl 2 years ago d053cdb
add greater, pointer ops. add image to exec test
A images/exec_finishes.png => images/exec_finishes.png +0 -0
A images/test_greater.png => images/test_greater.png +0 -0
A images/test_pointer.png => images/test_pointer.png +0 -0
M src/interpreter/interpreter_tests.rs => src/interpreter/interpreter_tests.rs +22 -16
@@ 218,24 218,10 @@ fn move_next_works_turn() {
#[test]
fn exec_finishes() {

    let r = Codel::from_color(Color::Red);
    let b = Codel::from_color(Color::Black);
    let g = Codel::from_color(Color::Green);
    let c = Codel::from_color(Color::Cyan);

    let m = PietImage::new(
        (4,4),
        vec!( vec!(r, b, g, b),
              vec!(r, c, g, g),
              vec!(b, b, g, b),
              vec!(b, b, b, b),
            ),
        );

    let mut interpreter = Interpreter::from_img(m);
    let mut interpreter = Interpreter::new("images/exec_finishes.png").unwrap();
    interpreter.exec().expect("Execution failed!");

    assert_eq!(interpreter.head().pos(), (2,1));
    assert_eq!(interpreter.head().pos(), (2,2));
}

#[test]


@@ 300,3 286,23 @@ fn mod_works() {
#[test]
#[ignore]
fn not_works() {}


#[test]
fn greater_works() {
    let mut interpreter = Interpreter::new("images/test_greater.png").unwrap();
    interpreter.exec().expect("Execution failed!");
    let popped = interpreter.stack.pop().unwrap();
    assert_eq!(popped, 1);

}


#[test]
fn pointer_works() {
    let mut interpreter = Interpreter::new("images/test_pointer.png").unwrap();
    interpreter.exec().expect("Execution failed!");
    let popped = interpreter.stack.pop().unwrap();
    assert_eq!(popped, 3);

}

M src/interpreter/mod.rs => src/interpreter/mod.rs +69 -24
@@ 32,6 32,7 @@ impl Interpreter {
    }

    pub fn head(&self) -> &Head { &self.head }
    pub fn head_as_mut(&mut self) -> &mut Head { &mut self.head }
    pub fn img(&self) -> &PietImage { &self.img }
    pub fn stack(&self) -> &Vec<isize> { &self.stack }
    pub fn mut_stack(&mut self) -> &Vec<isize> { &mut self.stack }


@@ 81,7 82,7 @@ impl Interpreter {
                        Ok(())
                    }
                    else { 
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack to add!"))
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    }
                }



@@ 93,7 94,7 @@ impl Interpreter {
                        Ok(())
                    }
                    else { 
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack to add!"))
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    }

                }


@@ 107,7 108,7 @@ impl Interpreter {
                        Ok(())
                    }
                    else { 
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack to add!"))
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    }

                }


@@ 124,7 125,7 @@ impl Interpreter {
                        Ok(())
                    }
                    else { 
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack to add!"))
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    }

                }


@@ 140,7 141,7 @@ impl Interpreter {
                        Ok(())
                    }
                    else { 
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack to add!"))
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    }

                }


@@ 150,10 151,43 @@ impl Interpreter {
                    Ok(())
                }

                Op::Greater => {
                    let first_pop  = self.stack.pop();
                    let second_pop = self.stack.pop();
                    if let (Some(a), Some(b)) = (first_pop, second_pop) {
                        if b > a { self.stack.push(1) } else { self.stack.push(0) }
                        Ok(())
                    }
                    else { 
                        Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"))
                    }
 
                }

                Op::Pointer => {
                    if let Some(val) = self.stack.pop() {
                        if val < 0 {
                            for _ in 0..(-val) {
                                let new_dir = self.head().direction_pointer()
                                                         .anticlockwise();
                                self.head_as_mut().set_direction(new_dir);
                            }
                        }
                        else {
                            for _ in 0..val {
                                let new_dir = self.head().direction_pointer()
                                                         .clockwise();
                                self.head_as_mut().set_direction(new_dir);
                            }
                        }
                    }

                    Ok(())

                }

                _ => {Ok(())}

                _ => {Ok(())}

            }



@@ 183,15 217,14 @@ impl Interpreter {
            }
            else {
                if cc_switches == 1 {
                        cc_switches = 0;
                        self.head.direction_pointer = self.head.direction_pointer.clockwise();
                        self.head.codel_chooser = self.head.codel_chooser.toggle(); 
                    }
                    else { 
                        self.head.codel_chooser = self.head.codel_chooser.toggle(); 
                        cc_switches += 1;
                    }
                    tries += 1;
                    cc_switches = 0;
                    self.head.direction_pointer = self.head.direction_pointer.clockwise();
                }
                else { 
                    cc_switches += 1;
                }
                self.head.codel_chooser = self.head.codel_chooser.toggle(); 
                tries += 1;
            }

        }


@@ 201,7 234,6 @@ impl Interpreter {

    fn get_head_next(&self, x: u32, y: u32) -> Option<(u32, u32)> {
        let (width, height) = self.img.dimensions();
        let head_color = self.img.get(x,y).color();

        let on_top_edge    = y == 0;
        let on_bottom_edge = y == height - 1;


@@ 244,7 276,7 @@ impl Interpreter {

#[allow(dead_code)]
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
enum Direction {
pub enum Direction {
    Up, Down, Left, Right
}



@@ 257,11 289,21 @@ impl Direction {
            Direction::Left  => Direction::Up,
        }
    }

    fn anticlockwise(&self) -> Self {
        match self {
            Direction::Up    => Direction::Left,
            Direction::Right => Direction::Up,
            Direction::Down  => Direction::Right,
            Direction::Left  => Direction::Down,
        }
    }

}

#[allow(dead_code)]
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
enum CcDirection {
pub enum CcDirection {
    Left, Right
}



@@ 285,7 327,7 @@ pub struct Head {
#[allow(dead_code)]
impl Head {

    fn new(pos: (u32, u32), direction_pointer: Direction, codel_chooser: CcDirection) -> Self {
    pub fn new(pos: (u32, u32), direction_pointer: Direction, codel_chooser: CcDirection) -> Self {
        Self {
            pos,
            direction_pointer,


@@ 293,7 335,7 @@ impl Head {
        }
    }

    fn default() -> Self {
    pub fn default() -> Self {
        Self {
            pos: (0,0),
            direction_pointer: Direction::Right,


@@ 301,17 343,20 @@ impl Head {
        }
    }

    fn set_direction(&mut self, dir: Direction) {
    pub fn direction_pointer(&self) -> &Direction { &self.direction_pointer }
    pub fn codel_chooser(&self) -> &CcDirection { &self.codel_chooser }

    pub fn set_direction(&mut self, dir: Direction) {
        self.direction_pointer = dir;
    }

    fn set_codel_chooser(&mut self, cc: CcDirection) {
    pub fn set_codel_chooser(&mut self, cc: CcDirection) {
        self.codel_chooser = cc;
    }

    fn pos(&self) -> (u32, u32) {  self.pos  }
    pub fn pos(&self) -> (u32, u32) {  self.pos  }

    fn set_pos(&mut self, pos: (u32, u32)) { self.pos = pos }
    pub fn set_pos(&mut self, pos: (u32, u32)) { self.pos = pos }