Skip to content

Instantly share code, notes, and snippets.

@krdln
Created June 6, 2015 22:46
Show Gist options
  • Save krdln/325898ec5cb639c5d362 to your computer and use it in GitHub Desktop.
Save krdln/325898ec5cb639c5d362 to your computer and use it in GitHub Desktop.
use std::num::Wrapping;
enum Instr {
Inc(Wrapping<u8>),
Move(isize),
Loop(Box<[Instr]>),
Print
}
use Instr::*;
fn run(program: &[Instr], tape: &mut[Wrapping<u8>], mut pos: usize) -> usize {
for i in program {
match *i {
Inc(x) => tape[pos] = tape[pos] + x,
Move(x) => pos = (pos as isize + x) as usize,
Loop(ref program) => while tape[pos] != Wrapping(0) {
pos = run(program, tape, pos);
},
Print => {
print!("{}", tape[pos].0 as char);
io::stdout().flush().unwrap() },
}
}
}
pos
}
fn parse<I: Iterator<Item=char>>(it: &mut I) -> Box<[Instr]> {
let mut buf = Vec::new();
while let Some(c) = it.next() {
buf.push( match c {
'+' => Inc(Wrapping(1)),
'-' => Inc(Wrapping(255)),
'<' => Move(-1),
'>' => Move(1),
'.' => Print,
'[' => Loop(parse(it)),
']' => break,
_ => continue,
} );
}
buf.into_boxed_slice()
}
fn main() {
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::env;
let arg1 = env::args().nth(1).unwrap();
let path = Path::new(&arg1);
let mut s = String::new();
let mut file = File::open(&path).unwrap();
file.read_to_string(&mut s).unwrap();
let program = parse(&mut s.chars());
run(&program, &mut vec![Wrapping(0); 30000], 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment