isbfc 0.0.1

Brainfuck compiler for x86_64
Documentation
// NOTE: This may not work properly/at all. The compiler
// is the focus. It exist mainly for debugging: since it uses
// the same parser, it can separate parser/optimizer bugs from compiler
// bugs.

use std::env;
use std::io;
use std::io::prelude::*;
use std::fs::File;

extern crate isbfc;
use isbfc::Token;
use isbfc::Token::*;
use isbfc::parse;
use isbfc::optimize;

const BUFSIZE: usize = 8192;

fn interp_iter(mem: &mut [i32; BUFSIZE],
               cur: &mut usize,
               outbuff: &mut String,
               tokens: &Vec<Token>) {
    for token in tokens {
        match *token {
            Add(offset, value) => mem[(*cur as i32 + offset) as usize] += value,
            MulCopy(src, dest, mul) => {
                mem[(*cur as i32 + dest) as usize] += mem[(*cur as i32 + src) as usize] * mul
            }
            Set(offset, value) => mem[(*cur as i32 + offset) as usize] = value,
            Move(offset) => *cur = (*cur as i32 + offset) as usize,
            Loop(ref content) => {
                while mem[*cur] != 0 {
                    interp_iter(mem, cur, outbuff, content);
                }
            }
            If(offset, ref content) => {
                if mem[(*cur as i32 + offset) as usize] != 0 {
                    interp_iter(mem, cur, outbuff, content);
                }
            }
            Scan(offset) => {
                while mem[*cur] != 0 {
                    *cur = (*cur as i32 + offset) as usize;
                }
            }
            Input => {
                let mut buffer = [0; 1];
                io::stdin().take(1).read(&mut buffer).unwrap();
                mem[*cur] = buffer[0] as i32;
            }
            LoadOut(offset, add) => {
                outbuff.push((mem[(*cur as i32 + offset) as usize] + add) as u8 as char)
            }
            LoadOutSet(value) => outbuff.push(value as u8 as char),
            Output => {
                io::stdout().write(outbuff.as_bytes()).unwrap();
                io::stdout().flush().unwrap();
                outbuff.clear();
            }
        }
    }
}

fn main() {
    let path = env::args().nth(1).unwrap();
    let mut file = File::open(&path).unwrap();
    let mut code = String::new();
    file.read_to_string(&mut code).unwrap();

    let tokens = parse(code.as_str());
    let tokens = optimize(tokens);

    let mut mem: [i32; BUFSIZE] = [0; BUFSIZE];
    let mut cur = BUFSIZE / 2;
    let mut outbuff = String::new();

    interp_iter(&mut mem, &mut cur, &mut outbuff, &tokens);
}