Created
May 4, 2017 04:36
-
-
Save llllllllll/752ec733900387fb66ca6f6cdaaf4b28 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(use_extern_macros)] | |
use std::io::Read; | |
struct State { | |
program: Vec<u8>, | |
ipt: usize, | |
tape: [u8; 30000], | |
ptr: usize, | |
control_stack: Vec<usize>, | |
} | |
impl State { | |
pub fn new(program: Vec<u8>) -> State { | |
State { | |
program: program, | |
ipt: 0, | |
tape: [0; 30000], | |
ptr: 0, | |
control_stack: vec![], | |
} | |
} | |
fn step(self) -> Option<State> { | |
let new = match self.program[self.ipt] { | |
b'+' => { | |
let mut new = self; | |
new.tape[new.ptr] = new.tape[new.ptr].wrapping_add(1); | |
new.ipt += 1; | |
new | |
}, | |
b'-' => { | |
let mut new = self; | |
new.tape[new.ptr] = new.tape[new.ptr].wrapping_sub(1); | |
new.ipt += 1; | |
new | |
}, | |
b'>' => Self { ptr: self.ptr + 1, ipt: self.ipt + 1, .. self }, | |
b'<' => Self { ptr: self.ptr - 1, ipt: self.ipt + 1, .. self }, | |
b'.' => { | |
print!("{}", self.tape[self.ptr] as char); | |
Self { ipt: self.ipt + 1, .. self } | |
}, | |
b',' => { | |
let value = match std::io::stdin().bytes().next() { | |
Some(v) => v.unwrap(), | |
_ => std::panic!("failed to read input"), | |
}; | |
let mut new = self; | |
new.tape[new.ptr] = value; | |
new.ipt += 1; | |
new | |
}, | |
b'[' => { | |
let mut new = self; | |
if new.tape[new.ptr] != 0 { | |
new.control_stack.push(new.ipt); | |
} | |
else { | |
let mut found = false; | |
let mut stack = 0; | |
for n in new.ipt + 1..new.program.len() { | |
match new.program[n] { | |
b'[' => { | |
stack += 1; | |
}, | |
b']' => { | |
if stack == 0 { | |
new.ipt = n; | |
found = true; | |
break | |
} | |
stack -= 1; | |
}, | |
_ => {}, | |
} | |
} | |
if !found { | |
std::panic!("unmatched '['"); | |
} | |
} | |
new.ipt += 1; | |
new | |
}, | |
b']' => { | |
let mut new = self; | |
new.ipt = new.control_stack.pop().unwrap(); | |
new | |
} | |
_ => Self { ipt: self.ipt + 1, .. self }, | |
}; | |
if new.ipt == new.program.len() { | |
None | |
} | |
else { | |
Some(new) | |
} | |
} | |
pub fn run(self) { | |
let mut state = self; | |
loop { | |
state = match state.step() { | |
Some(new) => new, | |
None => break, | |
} | |
} | |
} | |
} | |
fn main() { | |
let mut program = Vec::new(); | |
match std::io::stdin().read_to_end(&mut program) { | |
Ok(_) => { | |
State::new(program).run(); | |
() | |
}, | |
Err(e) => { | |
println!("{}", e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment