@@ 16,117 16,121 @@ pub struct Interpreter {
#[allow(dead_code)]
impl Interpreter {
-
pub fn new<P>(path: P) -> io::Result<Self>
- where P: AsRef<Path>
+ where
+ P: AsRef<Path>,
{
let img = translator::to_piet_img(path)?;
Ok(Interpreter::from_img(img))
}
pub fn with_codel_size<P>(path: P, codel_size: u32) -> io::Result<Self>
- where P: AsRef<Path>
+ where
+ P: AsRef<Path>,
{
let img = translator::with_codel_size(path, codel_size)?;
Ok(Interpreter::from_img(img))
}
- pub fn from_img(img: PietImage) -> Self {
+ pub fn from_img(img: PietImage) -> Self {
Self {
- img,
+ img,
head: Head::default(),
- stack: vec!(),
+ stack: vec![],
debug: false,
}
}
- pub fn head(&self) -> &Head { &self.head }
- pub fn head_as_mut(&mut self) -> &mut Head { &mut self.head }
-
- pub fn debug(&self) -> bool { self.debug }
- pub fn set_debug(&mut self, debug: bool) { self.debug = debug }
+ pub fn head(&self) -> &Head {
+ &self.head
+ }
+ pub fn head_as_mut(&mut self) -> &mut Head {
+ &mut self.head
+ }
+
+ pub fn debug(&self) -> bool {
+ self.debug
+ }
+ pub fn set_debug(&mut self, debug: bool) {
+ self.debug = debug
+ }
- pub fn img(&self) -> &PietImage { &self.img }
- pub fn stack(&self) -> &Vec<isize> { &self.stack }
- pub fn stack_as_mut(&mut self) -> &mut Vec<isize> { &mut self.stack }
+ pub fn img(&self) -> &PietImage {
+ &self.img
+ }
+ pub fn stack(&self) -> &Vec<isize> {
+ &self.stack
+ }
+ pub fn stack_as_mut(&mut self) -> &mut Vec<isize> {
+ &mut self.stack
+ }
pub fn exec(&mut self) -> io::Result<()> {
-
- loop {
+ let mut stdout_handle = std::io::stdout().lock();
+ loop {
let curr = self.head.pos();
//eprintln!("{:?}", curr);
if let Some(next) = self.move_next() {
-
let curr_codel = self.img().get(curr.0, curr.1);
let next_codel = self.img().get(next.0, next.1);
- rules::do_op(self, &curr_codel, &next_codel)?;
-
+ rules::do_op(self, &curr_codel, &next_codel, &mut stdout_handle)?;
+ } else {
+ return Ok(());
}
-
- else { return Ok(()) }
-
- }
-
+ }
}
-
- fn move_next(&mut self) -> Option<(u32, u32)> {
+ fn move_next(&mut self) -> Option<(u32, u32)> {
let curr_codel = self.head.pos;
let block = &self.img.get_block(curr_codel.0, curr_codel.1);
-
+
let mut cc_switches = 0;
let mut tries = 0;
loop {
-
let edge = self.head.get_furthest_edge(&block);
let codel_on_edge = self.head.get_furthest_codel_on_edge(&edge);
- if tries == 8 { return None }
+ if tries == 8 {
+ return None;
+ }
if self.img.get(curr_codel.0, curr_codel.1).color() == Color::White {
- return self.move_through_whitespace(curr_codel);
+ return self.move_through_whitespace(curr_codel);
}
if let Some(next) = self.get_head_next(codel_on_edge.0, codel_on_edge.1) {
-
self.head.pos = next;
- return Some(next);
-
- }
- else {
+ return Some(next);
+ } else {
if cc_switches == 1 {
cc_switches = 0;
self.head.direction_pointer = self.head.direction_pointer.clockwise();
- }
- else {
+ } else {
cc_switches += 1;
- self.head.codel_chooser = self.head.codel_chooser.toggle();
+ self.head.codel_chooser = self.head.codel_chooser.toggle();
}
tries += 1;
}
-
}
}
fn move_through_whitespace(&mut self, start: (u32, u32)) -> Option<(u32, u32)> {
let (width, height) = self.img.dimensions();
let mut curr = start;
- let mut states = vec!();
+ let mut states = vec![];
loop {
//eprintln!("in: {:?}", curr);
- let on_top_edge = curr.1 == 0;
+ let on_top_edge = curr.1 == 0;
let on_bottom_edge = curr.1 == height - 1;
- let on_left_edge = curr.0 == 0;
- let on_right_edge = curr.0 == width - 1;
-
-
+ let on_left_edge = curr.0 == 0;
+ let on_right_edge = curr.0 == width - 1;
if states.contains(&(curr, self.head.direction_pointer)) {
return None;
}
- let (x,y) = curr;
+ let (x, y) = curr;
if self.img.get(x, y).color() != Color::White {
self.head_as_mut().pos = curr;
return Some(curr);
@@ 136,174 140,173 @@ impl Interpreter {
match self.head.direction_pointer {
Direction::Up => {
- if on_top_edge || self.img.get(x, y-1).color() == Color::Black {
+ if on_top_edge || self.img.get(x, y - 1).color() == Color::Black {
self.head.direction_pointer = self.head.direction_pointer.clockwise();
- self.head.codel_chooser = self.head.codel_chooser.toggle();
- }
- else {
- curr = (x, y-1);
+ self.head.codel_chooser = self.head.codel_chooser.toggle();
+ } else {
+ curr = (x, y - 1);
}
}
Direction::Right => {
- if on_right_edge || self.img.get(x+1, y).color() == Color::Black{
+ if on_right_edge || self.img.get(x + 1, y).color() == Color::Black {
self.head.direction_pointer = self.head.direction_pointer.clockwise();
- self.head.codel_chooser = self.head.codel_chooser.toggle();
- }
- else {
- curr = (x+1, y);
+ self.head.codel_chooser = self.head.codel_chooser.toggle();
+ } else {
+ curr = (x + 1, y);
}
}
Direction::Down => {
- if on_bottom_edge || self.img.get(x, y+1).color() == Color::Black {
+ if on_bottom_edge || self.img.get(x, y + 1).color() == Color::Black {
self.head.direction_pointer = self.head.direction_pointer.clockwise();
- self.head.codel_chooser = self.head.codel_chooser.toggle();
-
- }
- else {
- curr = (x, y+1);
+ self.head.codel_chooser = self.head.codel_chooser.toggle();
+ } else {
+ curr = (x, y + 1);
}
}
Direction::Left => {
- if on_left_edge || self.img.get(x-1, y).color() == Color::Black {
+ if on_left_edge || self.img.get(x - 1, y).color() == Color::Black {
self.head.direction_pointer = self.head.direction_pointer.clockwise();
- self.head.codel_chooser = self.head.codel_chooser.toggle();
-
- }
- else {
- curr = (x-1, y);
+ self.head.codel_chooser = self.head.codel_chooser.toggle();
+ } else {
+ curr = (x - 1, y);
}
}
}
}
}
-
-
fn get_head_next(&self, x: u32, y: u32) -> Option<(u32, u32)> {
let (width, height) = self.img.dimensions();
- let on_top_edge = y == 0;
+ let on_top_edge = y == 0;
let on_bottom_edge = y == height - 1;
- let on_left_edge = x == 0;
- let on_right_edge = x == width - 1;
+ let on_left_edge = x == 0;
+ let on_right_edge = x == width - 1;
match self.head.direction_pointer {
Direction::Up => {
- if on_top_edge || self.img.get(x, y-1).color() == Color::Black { None }
- else { Some((x, y-1)) }
+ if on_top_edge || self.img.get(x, y - 1).color() == Color::Black {
+ None
+ } else {
+ Some((x, y - 1))
+ }
}
Direction::Right => {
- if on_right_edge || self.img.get(x+1, y).color() == Color::Black{ None }
- else { Some((x+1, y)) }
+ if on_right_edge || self.img.get(x + 1, y).color() == Color::Black {
+ None
+ } else {
+ Some((x + 1, y))
+ }
}
Direction::Down => {
- if on_bottom_edge || self.img.get(x, y+1).color() == Color::Black { None }
- else { Some((x, y+1)) }
+ if on_bottom_edge || self.img.get(x, y + 1).color() == Color::Black {
+ None
+ } else {
+ Some((x, y + 1))
+ }
}
Direction::Left => {
- if on_left_edge || self.img.get(x-1, y).color() == Color::Black { None }
- else { Some((x-1, y)) }
+ if on_left_edge || self.img.get(x - 1, y).color() == Color::Black {
+ None
+ } else {
+ Some((x - 1, y))
+ }
}
}
}
-
#[allow(dead_code)]
fn reset(&mut self) {
- self.img.reset_block_sizes();
- self.img.update_block_sizes();
-
- self.head.set_pos( (0,0) );
- self.stack = vec!();
-
- }
+ self.img.reset_block_sizes();
+ self.img.update_block_sizes();
- pub fn get_utf8_char(buffer: &str) -> &[u8] {
+ self.head.set_pos((0, 0));
+ self.stack = vec![];
+ }
+ pub fn get_utf8_char(buffer: &str) -> &[u8] {
let bytes = buffer.as_bytes();
let num_bytes = bytes[0].leading_ones() as usize;
- if num_bytes == 0 { &bytes[..1] }
- else { &bytes[..num_bytes] }
+ if num_bytes == 0 {
+ &bytes[..1]
+ } else {
+ &bytes[..num_bytes]
+ }
}
- pub fn utf8_to_unicode(bytes: &[u8]) -> isize {
+ pub fn utf8_to_unicode(bytes: &[u8]) -> isize {
let num_bytes = bytes[0].leading_ones() as usize;
- let mut code_point: Vec<&str> = vec!();
+ let mut code_point: Vec<&str> = vec![];
let byte_strs: Vec<String> = bytes.iter().map(|byte| format!("{:b}", byte)).collect();
let header_str = &byte_strs[0];
-
- // Ascii
- if byte_strs.len() == 1 { return bytes[0] as isize }
+ // Ascii
+ if byte_strs.len() == 1 {
+ return bytes[0] as isize;
+ }
// Non-Ascii UTF-8
- code_point.push(&header_str[num_bytes+1..]);
+ code_point.push(&header_str[num_bytes + 1..]);
for i in 1..num_bytes {
code_point.push(&byte_strs[i][2..]);
}
-
let mut code_point_num: isize = 0;
let mut multiplier = 1;
for bit in code_point.join("").chars().rev() {
code_point_num += (bit.to_digit(2).unwrap() as isize) * multiplier;
multiplier *= 2;
-
}
code_point_num
-
}
-
-
-
}
-
-
-
#[allow(dead_code)]
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Direction {
- Up, Down, Left, Right
+ Up,
+ Down,
+ Left,
+ Right,
}
impl Direction {
pub fn clockwise(&self) -> Self {
match self {
- Direction::Up => Direction::Right,
+ Direction::Up => Direction::Right,
Direction::Right => Direction::Down,
- Direction::Down => Direction::Left,
- Direction::Left => Direction::Up,
+ Direction::Down => Direction::Left,
+ Direction::Left => Direction::Up,
}
}
pub fn anticlockwise(&self) -> Self {
match self {
- Direction::Up => Direction::Left,
+ Direction::Up => Direction::Left,
Direction::Right => Direction::Up,
- Direction::Down => Direction::Right,
- Direction::Left => Direction::Down,
+ Direction::Down => Direction::Right,
+ Direction::Left => Direction::Down,
}
}
-
}
#[allow(dead_code)]
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum CcDirection {
- Left, Right
+ Left,
+ Right,
}
impl CcDirection {
pub fn toggle(&self) -> Self {
match self {
- CcDirection::Left => CcDirection::Right,
+ CcDirection::Left => CcDirection::Right,
CcDirection::Right => CcDirection::Left,
}
}
@@ 319,7 322,6 @@ pub struct Head {
#[allow(dead_code)]
impl Head {
-
pub fn new(pos: (u32, u32), direction_pointer: Direction, codel_chooser: CcDirection) -> Self {
Self {
pos,
@@ 330,14 332,18 @@ impl Head {
pub fn default() -> Self {
Self {
- pos: (0,0),
+ pos: (0, 0),
direction_pointer: Direction::Right,
codel_chooser: CcDirection::Left,
}
}
- pub fn direction_pointer(&self) -> &Direction { &self.direction_pointer }
- pub fn codel_chooser(&self) -> &CcDirection { &self.codel_chooser }
+ 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;
@@ 347,67 353,64 @@ impl Head {
self.codel_chooser = cc;
}
- pub fn pos(&self) -> (u32, u32) { self.pos }
-
- pub fn set_pos(&mut self, pos: (u32, u32)) { self.pos = pos }
-
+ pub fn pos(&self) -> (u32, u32) {
+ self.pos
+ }
+ pub fn set_pos(&mut self, pos: (u32, u32)) {
+ self.pos = pos
+ }
fn get_furthest_edge(&self, block: &Vec<(u32, u32)>) -> Vec<(u32, u32)> {
-
let mut max_x: u32 = block[0].0;
let mut min_x: u32 = block[0].0;
let mut max_y: u32 = block[0].1;
let mut min_y: u32 = block[0].1;
-
+
for &(x, y) in block.iter() {
- if max_x < x { max_x = x; }
- if min_x > x { min_x = x; }
- if max_y < y { max_y = y; }
- if min_y > y { min_y = y; }
+ if max_x < x {
+ max_x = x;
+ }
+ if min_x > x {
+ min_x = x;
+ }
+ if max_y < y {
+ max_y = y;
+ }
+ if min_y > y {
+ min_y = y;
+ }
}
-
- let right_edge = block.iter().filter(|(x, _)| *x == max_x).cloned().collect();
- let left_edge = block.iter().filter(|(x, _)| *x == min_x).cloned().collect();
+
+ let right_edge = block.iter().filter(|(x, _)| *x == max_x).cloned().collect();
+ let left_edge = block.iter().filter(|(x, _)| *x == min_x).cloned().collect();
let bottom_edge = block.iter().filter(|(_, y)| *y == max_y).cloned().collect();
- let top_edge = block.iter().filter(|(_, y)| *y == min_y).cloned().collect();
-
+ let top_edge = block.iter().filter(|(_, y)| *y == min_y).cloned().collect();
+
match self.direction_pointer {
- Direction::Right => { right_edge },
- Direction::Left => { left_edge },
- Direction::Down => { bottom_edge },
- Direction::Up => { top_edge },
-
+ Direction::Right => right_edge,
+ Direction::Left => left_edge,
+ Direction::Down => bottom_edge,
+ Direction::Up => top_edge,
}
-
-
}
fn get_furthest_codel_on_edge(&self, edge: &Vec<(u32, u32)>) -> (u32, u32) {
-
-
- let uppermost = *edge.iter().min_by_key(|(_,y)| y ).unwrap();
- let lowermost = *edge.iter().max_by_key(|(_,y)| y ).unwrap();
- let rightmost = *edge.iter().max_by_key(|(x,_)| x ).unwrap();
- let leftmost = *edge.iter().min_by_key(|(x,_)| x ).unwrap();
-
-
+ let uppermost = *edge.iter().min_by_key(|(_, y)| y).unwrap();
+ let lowermost = *edge.iter().max_by_key(|(_, y)| y).unwrap();
+ let rightmost = *edge.iter().max_by_key(|(x, _)| x).unwrap();
+ let leftmost = *edge.iter().min_by_key(|(x, _)| x).unwrap();
+
match (self.direction_pointer, self.codel_chooser) {
-
- (Direction::Right, CcDirection::Left) => { uppermost },
- (Direction::Right, CcDirection::Right) => { lowermost },
- (Direction::Down, CcDirection::Left) => { rightmost },
- (Direction::Down, CcDirection::Right) => { leftmost },
- (Direction::Left, CcDirection::Left) => { lowermost },
- (Direction::Left, CcDirection::Right) => { uppermost },
- (Direction::Up, CcDirection::Left) => { leftmost },
- (Direction::Up, CcDirection::Right) => { rightmost },
-
+ (Direction::Right, CcDirection::Left) => uppermost,
+ (Direction::Right, CcDirection::Right) => lowermost,
+ (Direction::Down, CcDirection::Left) => rightmost,
+ (Direction::Down, CcDirection::Right) => leftmost,
+ (Direction::Left, CcDirection::Left) => lowermost,
+ (Direction::Left, CcDirection::Right) => uppermost,
+ (Direction::Up, CcDirection::Left) => leftmost,
+ (Direction::Up, CcDirection::Right) => rightmost,
}
-
-}
-
-
-
+ }
}
#[cfg(test)]