add machine logic, first draft
This commit is contained in:
@@ -2,10 +2,10 @@ use std::io::{BufReader, BufWriter, Read, Write};
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InstructionType {
|
pub enum InstructionType {
|
||||||
Plus,
|
Increment,
|
||||||
Minus,
|
Decrement,
|
||||||
Left,
|
Leftshift,
|
||||||
Right,
|
Rightshift,
|
||||||
PutChar,
|
PutChar,
|
||||||
GetChar,
|
GetChar,
|
||||||
JumpIfZero,
|
JumpIfZero,
|
||||||
@@ -14,18 +14,18 @@ pub enum InstructionType {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Instruction {
|
pub struct Instruction {
|
||||||
pub ins_type: InstructionType,
|
pub itype: InstructionType,
|
||||||
pub argument: usize,
|
pub argument: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Machine<'a> {
|
pub struct Machine<'a> {
|
||||||
ip: usize,
|
ip: usize,
|
||||||
mp: usize,
|
mp: usize,
|
||||||
code: Vec<Instruction>,
|
buf: [u8; 1],
|
||||||
memory: [u32; 50000],
|
memory: [u32; 50000],
|
||||||
|
code: Vec<Instruction>,
|
||||||
input: &'a mut BufReader<Box<dyn Read>>,
|
input: &'a mut BufReader<Box<dyn Read>>,
|
||||||
output: &'a mut BufWriter<Box<dyn Write>>,
|
output: &'a mut BufWriter<Box<dyn Write>>,
|
||||||
buf: [u8; 1],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Machine<'a> {
|
impl<'a> Machine<'a> {
|
||||||
@@ -33,23 +33,84 @@ impl<'a> Machine<'a> {
|
|||||||
Machine {
|
Machine {
|
||||||
ip: 0,
|
ip: 0,
|
||||||
mp: 0,
|
mp: 0,
|
||||||
code,
|
buf: [0;1],
|
||||||
memory: [0; 50000],
|
memory: [0; 50000],
|
||||||
|
code,
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
buf: [0;1],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&mut self){
|
pub fn execute(&mut self){
|
||||||
return;
|
// prevent ip from getting out of bounds
|
||||||
|
while self.ip < self.code.len() {
|
||||||
|
// get current instruction
|
||||||
|
let instruction = &self.code[self.ip];
|
||||||
|
// match type and execute
|
||||||
|
match instruction.itype {
|
||||||
|
InstructionType::Increment => {
|
||||||
|
self.memory[self.mp] += instruction.argument as u32
|
||||||
|
}
|
||||||
|
InstructionType::Decrement => {
|
||||||
|
self.memory[self.mp] -= instruction.argument as u32
|
||||||
|
}
|
||||||
|
InstructionType::Leftshift => {
|
||||||
|
self.mp += instruction.argument
|
||||||
|
}
|
||||||
|
InstructionType::Rightshift => {
|
||||||
|
self.mp -= instruction.argument
|
||||||
|
}
|
||||||
|
InstructionType::PutChar => {
|
||||||
|
for _ in 0..instruction.argument {
|
||||||
|
self.put_char()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InstructionType::GetChar => {
|
||||||
|
for _ in 0..instruction.argument {
|
||||||
|
self.get_char()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InstructionType::JumpIfZero => {
|
||||||
|
if self.memory[self.mp] == 0 {
|
||||||
|
self.ip = instruction.argument;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InstructionType::JumpIfNotZero => {
|
||||||
|
if self.memory[self.mp] != 0 {
|
||||||
|
self.ip = instruction.argument;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_char(&mut self){
|
pub fn get_char(&mut self){
|
||||||
return;
|
let byte_input = match self.input.read(&mut self.buf) {
|
||||||
|
Ok(byte_input) => byte_input,
|
||||||
|
Err(e) => panic!(e),
|
||||||
|
};
|
||||||
|
|
||||||
|
if byte_input != 1 {
|
||||||
|
panic!("input read error")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.memory[self.mp] = self.buf[0] as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_char(&mut self){
|
pub fn put_char(&mut self){
|
||||||
return;
|
self.buf[0] = self.memory[self.mp] as u8;
|
||||||
|
|
||||||
|
let byte_write = match self.output.write(&self.buf) {
|
||||||
|
Ok(byte_write) => byte_write,
|
||||||
|
Err(e) => panic!(e),
|
||||||
|
};
|
||||||
|
|
||||||
|
if byte_write != 1 {
|
||||||
|
panic!("output write error")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.output.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user