mod core;
use core::parser::Parser;
use core::program::Program;
use core::instruction::Instruction;
use core::error::Error;
use core::memory::Memory;
use std::io;
use std::io::prelude::*;
use std::path::Path;
pub struct Inter {
tape:Memory,
program:Program,
parser:Parser,
}
impl Inter {
pub fn new() -> Inter {
Inter {
tape: Memory::new(),
program: Program::new(),
parser: Parser::new(),
}
}
pub fn load<S: Into<String>>(&mut self, p:S) -> Result<(), Error> {
self.parser.load(p)
}
pub fn load_from_file<P: AsRef<Path>>(&mut self, src:P) -> Result<(), Error> {
self.parser.load_from_file(src)
}
pub fn parse(&mut self) -> Result<(), Error> {
match self.parser.parse() {
Ok(p) => {
self.program = p;
Ok(())
}
Err(e) => Result::Err(e),
}
}
pub fn run(&mut self) -> Result<(), Error> {
if self.program.get_size() == 0 {
return Result::Err(Error::EmptyProgram);
}
while let Some(instr) = self.program.get() {
match instr {
Instruction::IncPtr => { match self.inc_ptr() { Ok(_) => { } Err(e) => return Result::Err(e), } }
Instruction::DecPtr => { match self.dec_ptr() { Ok(_) => { } Err(e) => return Result::Err(e), } }
Instruction::IncVal => { match self.inc_val() { Ok(_) => { } Err(e) => return Result::Err(e), } }
Instruction::DecVal => { match self.dec_val() { Ok(_) => { } Err(e) => return Result::Err(e), } }
Instruction::Input => { self.input(); }
Instruction::Output => { self.output(); }
Instruction::OpenBracket(n) => { self.open_bracket(n); }
Instruction::CloseBracket(n) => { self.close_bracket(n); }
};
if !self.program.inc_ptr() {
break;
}
};
return Result::Ok(());
}
fn inc_val(&mut self) -> Result<(), Error> {
self.tape.inc_val()
}
fn dec_val(&mut self) -> Result<(), Error> {
self.tape.dec_val()
}
fn inc_ptr(&mut self) -> Result<(), Error> {
self.tape.inc_ptr()
}
fn dec_ptr(&mut self) -> Result<(), Error> {
self.tape.dec_ptr()
}
fn input(&mut self) {
match io::stdin().bytes().next() {
Some(v) => self.tape.set_val(v.unwrap()),
None => { }
}
}
fn output(&mut self) {
print!("{}", self.tape.get_val() as char);
}
fn open_bracket(&mut self, pos:usize) {
if self.tape.get_val() == 0 {
self.program.set_ptr(pos);
}
}
fn close_bracket(&mut self, pos:usize) {
if self.tape.get_val() != 0 {
self.program.set_ptr(pos);
}
}
}