/// Executes a single instruction.
///
/// This will return an error if the machine has been halted.
Executes a single instruction.
This will return an error if the machine has been halted.
Executes a single instruction . This will return an error if the machine has been halted .
fn execute(&mut self, ins: Instruction) -> Result<()> {
        if self.halted {
            return Err(ErrorKind::Halted.into());
        }
        match ins {
            Instruction::Halt => {
                self.halted = true;
            }
            Instruction::Io(IoOp::ReadHex) => {
                self.acc = self.read_hex()? as i16;
            }
            Instruction::Io(IoOp::ReadChar) => {
                self.acc = self.read_u8()? as i16;
            }
            Instruction::Io(IoOp::WriteHex) => {
                writeln!(&mut self.output, "{:04x}", self.acc).chain_err(|| ErrorKind::Io("could not write to output".into()))?;
            }
            Instruction::Io(IoOp::WriteChar) => {
                writeln!(&mut self.output, "{}", self.acc as u8 as char).chain_err(|| ErrorKind::Io("could not write to output".into()))?;
            }
            Instruction::Shift(ShiftOp::ShiftLeft, n) => {
                self.acc <<= n;
            }
            Instruction::Shift(ShiftOp::ShiftRight, n) => {
                // Appears to be an unsigned shift in the canonical source code
                self.acc = ((self.acc as u16) >> n) as i16;
            }
            Instruction::Shift(ShiftOp::RotateLeft, n) => {
                self.acc = self.acc.rotate_left(n as u32);
            }
            Instruction::Shift(ShiftOp::RotateRight, n) => {
                self.acc = self.acc.rotate_right(n as u32);
            }
            Instruction::Load(addr) => {
                self.acc = self.memory[addr as usize] as i16;
            }
            Instruction::Store(addr) => {
                self.memory[addr as usize] = self.acc as u16;
            }
            Instruction::Add(addr) => {
                self.acc = self.acc.wrapping_add(self.memory[addr as usize] as i16);
            }
            Instruction::Sub(addr) => {
                self.acc = self.acc.wrapping_sub(self.memory[addr as usize] as i16);
            }
            Instruction::And(addr) => {
                self.acc &= self.memory[addr as usize] as i16;
            }
            Instruction::Or(addr) => {
                self.acc |= self.memory[addr as usize] as i16;
            }
            Instruction::Xor(addr) => {
                self.acc ^= self.memory[addr as usize] as i16;
            }
            Instruction::Not => {
                self.acc = !self.acc;
            }
            Instruction::Nop => {}
            Instruction::Jmp(addr) => {
                self.pc = addr;
            }
            Instruction::Jmpe(addr) => {
                if self.acc == 0 {
                    self.pc = addr;
                }
            }
            Instruction::Jmpl(addr) => {
                if self.acc < 0 {
                    self.pc = addr;
                }
            }
            Instruction::Brl(addr) => {
                self.acc = self.pc as i16;
                self.pc = addr;
            }
        }
        Ok(())
    }
fn execute ( & mut self , ins : Instruction ) -> Result < ( ) > { if self . halted { return Err ( ErrorKind :: Halted . into ( ) ) ; } match ins { Instruction :: Halt => { self . halted = true ; } Instruction :: Io ( IoOp :: ReadHex ) => { self . acc = self . read_hex ( ) ? as i16 ; } Instruction :: Io ( IoOp :: ReadChar ) => { self . acc = self . read_u8 ( ) ? as i16 ; } Instruction :: Io ( IoOp :: WriteHex ) => { writeln ! ( mut self output " " self acc ) . chain_err ( | | ErrorKind :: Io ( " " . into ( ) ) ) ? ; } Instruction :: Io ( IoOp :: WriteChar ) => { writeln ! ( mut self output " " self acc as u8 as char ) . chain_err ( | | ErrorKind :: Io ( " " . into ( ) ) ) ? ; } Instruction :: Shift ( ShiftOp :: ShiftLeft , n ) => { self . acc <<= n ; } Instruction :: Shift ( ShiftOp :: ShiftRight , n ) => { // Appears to be an unsigned shift in the canonical source code self . acc = ( ( self . acc as u16 ) >> n ) as i16 ; } Instruction :: Shift ( ShiftOp :: RotateLeft , n ) => { self . acc = self . acc . rotate_left ( n as u32 ) ; } Instruction :: Shift ( ShiftOp :: RotateRight , n ) => { self . acc = self . acc . rotate_right ( n as u32 ) ; } Instruction :: Load ( addr ) => { self . acc = self . memory [ addr as usize ] as i16 ; } Instruction :: Store ( addr ) => { self . memory [ addr as usize ] = self . acc as u16 ; } Instruction :: Add ( addr ) => { self . acc = self . acc . wrapping_add ( self . memory [ addr as usize ] as i16 ) ; } Instruction :: Sub ( addr ) => { self . acc = self . acc . wrapping_sub ( self . memory [ addr as usize ] as i16 ) ; } Instruction :: And ( addr ) => { self . acc &= self . memory [ addr as usize ] as i16 ; } Instruction :: Or ( addr ) => { self . acc |= self . memory [ addr as usize ] as i16 ; } Instruction :: Xor ( addr ) => { self . acc ^= self . memory [ addr as usize ] as i16 ; } Instruction :: Not => { self . acc = ! self . acc ; } Instruction :: Nop => { } Instruction :: Jmp ( addr ) => { self . pc = addr ; } Instruction :: Jmpe ( addr ) => { if self . acc == 0 { self . pc = addr ; } } Instruction :: Jmpl ( addr ) => { if self . acc < 0 { self . pc = addr ; } } Instruction :: Brl ( addr ) => { self . acc = self . pc as i16 ; self . pc = addr ; } } Ok ( ( ) ) }
Executes a single instruction.
Executes a single instruction .
&mut self
ins
Instruction