improve machine and make arguments work
This commit is contained in:
@@ -33,28 +33,12 @@ impl<'a> Machine<'a> {
|
|||||||
println!("{:?}", instruction);
|
println!("{:?}", instruction);
|
||||||
// match type and execute
|
// match type and execute
|
||||||
match instruction.itype {
|
match instruction.itype {
|
||||||
InstructionType::Increment => {
|
InstructionType::Increment => self.do_increment(instruction.argument),
|
||||||
self.memory[self.mp] += instruction.argument as u32
|
InstructionType::Decrement => self.do_decrement(instruction.argument),
|
||||||
}
|
InstructionType::Leftshift => self.do_leftshift(instruction.argument),
|
||||||
InstructionType::Decrement => {
|
InstructionType::Rightshift => self.do_rightshift(instruction.argument),
|
||||||
self.memory[self.mp] -= instruction.argument as u32
|
InstructionType::PutChar => self.do_put_char(instruction.argument),
|
||||||
}
|
InstructionType::GetChar => self.do_get_char(instruction.argument),
|
||||||
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 => {
|
InstructionType::JumpIfZero => {
|
||||||
if self.memory[self.mp] == 0 {
|
if self.memory[self.mp] == 0 {
|
||||||
self.ip = instruction.argument;
|
self.ip = instruction.argument;
|
||||||
@@ -68,12 +52,28 @@ impl<'a> Machine<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_char(&mut self){
|
pub fn do_increment(&mut self, argument: usize){
|
||||||
|
self.memory[self.mp] += argument as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_decrement(&mut self, argument: usize){
|
||||||
|
self.memory[self.mp] -= argument as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_leftshift(&mut self, argument: usize){
|
||||||
|
self.mp += argument
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_rightshift(&mut self, argument: usize){
|
||||||
|
self.mp -= argument
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_get_char(&mut self, argument: usize){
|
||||||
|
for _ in 0..argument {
|
||||||
let byte_input = match self.input.read(&mut self.buf) {
|
let byte_input = match self.input.read(&mut self.buf) {
|
||||||
Ok(byte_input) => byte_input,
|
Ok(byte_input) => byte_input,
|
||||||
Err(e) => panic!(e),
|
Err(e) => panic!(e),
|
||||||
@@ -85,8 +85,10 @@ impl<'a> Machine<'a> {
|
|||||||
|
|
||||||
self.memory[self.mp] = self.buf[0] as u32;
|
self.memory[self.mp] = self.buf[0] as u32;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn put_char(&mut self){
|
pub fn do_put_char(&mut self, argument: usize){
|
||||||
|
for _ in 0..argument {
|
||||||
self.buf[0] = self.memory[self.mp] as u8;
|
self.buf[0] = self.memory[self.mp] as u8;
|
||||||
|
|
||||||
let byte_write = match self.output.write(&self.buf) {
|
let byte_write = match self.output.write(&self.buf) {
|
||||||
@@ -101,3 +103,4 @@ impl<'a> Machine<'a> {
|
|||||||
self.output.flush();
|
self.output.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ impl Parser {
|
|||||||
while self.position < self.code_length {
|
while self.position < self.code_length {
|
||||||
let current = self.code[self.position];
|
let current = self.code[self.position];
|
||||||
match current {
|
match current {
|
||||||
'+' => self.load_instruction(Increment),
|
'+' => self.load_instruction(Increment, 1),
|
||||||
'-' => self.load_instruction(Decrement),
|
'-' => self.load_instruction(Decrement, 1),
|
||||||
'<' => self.load_instruction(Leftshift),
|
'<' => self.load_instruction(Leftshift, 1),
|
||||||
'>' => self.load_instruction(Rightshift),
|
'>' => self.load_instruction(Rightshift, 1),
|
||||||
'.' => self.load_instruction(PutChar),
|
'.' => self.load_instruction(PutChar, 1),
|
||||||
',' => self.load_instruction(GetChar),
|
',' => self.load_instruction(GetChar, 1),
|
||||||
'[' => self.load_instruction(JumpIfZero),
|
'[' => self.load_instruction(JumpIfZero, 1),
|
||||||
']' => self.load_instruction(JumpIfNotZero),
|
']' => self.load_instruction(JumpIfNotZero, 1),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,10 +40,13 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_instruction(&mut self, itype: InstructionType) {
|
// ToDo: Write a wrapper function for this to optimize the code by
|
||||||
|
// counting the number of similar consecutive instructions and setting
|
||||||
|
// the argument accordingly.
|
||||||
|
fn load_instruction(&mut self, itype: InstructionType, arg: usize) {
|
||||||
let instruction = Instruction {
|
let instruction = Instruction {
|
||||||
itype,
|
itype,
|
||||||
argument: 1,
|
argument: arg,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.instructions.push(instruction);
|
self.instructions.push(instruction);
|
||||||
|
|||||||
Reference in New Issue
Block a user