add machine logic, first draft
This commit is contained in:
@@ -2,10 +2,10 @@ use std::io::{BufReader, BufWriter, Read, Write};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InstructionType {
|
||||
Plus,
|
||||
Minus,
|
||||
Left,
|
||||
Right,
|
||||
Increment,
|
||||
Decrement,
|
||||
Leftshift,
|
||||
Rightshift,
|
||||
PutChar,
|
||||
GetChar,
|
||||
JumpIfZero,
|
||||
@@ -14,18 +14,18 @@ pub enum InstructionType {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Instruction {
|
||||
pub ins_type: InstructionType,
|
||||
pub itype: InstructionType,
|
||||
pub argument: usize,
|
||||
}
|
||||
|
||||
pub struct Machine<'a> {
|
||||
ip: usize,
|
||||
mp: usize,
|
||||
code: Vec<Instruction>,
|
||||
buf: [u8; 1],
|
||||
memory: [u32; 50000],
|
||||
code: Vec<Instruction>,
|
||||
input: &'a mut BufReader<Box<dyn Read>>,
|
||||
output: &'a mut BufWriter<Box<dyn Write>>,
|
||||
buf: [u8; 1],
|
||||
}
|
||||
|
||||
impl<'a> Machine<'a> {
|
||||
@@ -33,23 +33,84 @@ impl<'a> Machine<'a> {
|
||||
Machine {
|
||||
ip: 0,
|
||||
mp: 0,
|
||||
code,
|
||||
buf: [0;1],
|
||||
memory: [0; 50000],
|
||||
code,
|
||||
input,
|
||||
output,
|
||||
buf: [0;1],
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
return;
|
||||
pub fn get_char(&mut self){
|
||||
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){
|
||||
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