p101_is 1.0.0

Represent Olivetti Programma 101 programs
Documentation
use crate::Register;
use crate::Origin;
use crate::ConditionalOrigin;
use crate::JumpDestination;
use crate::{CaiSign, CaiOrder, CaiDigit, CaiComma};

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Instruction {
    /// Adds the selected register to the accumulator.
    Add(Register),

    /// Subtracts the selected register from the accumulator.
    Sub(Register),

    /// Multiply the accumulator by the selected register.
    Mul(Register),

    /// Divide the accumulator by the selected register.
    Div(Register),

    /// Compute the square root of M register content.
    Sqr(Register),

    /// A↕ instruction: set a register to its absolute value.
    Abs,

    /// x↑ instruction: copies m register to another register.
    CopyM(Register),

    /// x↓ instruction: copies operand value in A.
    CopyToA(Register),

    /// x↕ instruction: swaps a and operand register values.
    SwapA(Register),

    /// /↕ instruction: copies the decimal part of the accumulator to m register.
    CopyDecimal,

    /// Unconditional Jumps: jumps are executed whenever the instruction is read.
    Jump(Origin),
    
    /// Conditional jump: these jumps choose one of two alternatives by testing the
    /// contents of the A register for the following condition:
    /// GREATER THAN 0 the program jumps to the corresponding Reference Point.
    /// ZERO OR LESS - the program continues with the next instruction in sequence.
    ConditionalJump(ConditionalOrigin),

    /// Marks the address with a label in order to be referenced by jump instructions.
    Label(JumpDestination),

    /// x* instruction: set register value to 0
    Reset(Register),

    /// Diamond "⋄" (\u20DF) instruction: Print
    /// The print " " operation directs the computer to print the contents of the selected register
    /// while retaining them in the register. The number of decimal places in the printed result
    /// is controlled by the Decimal Wheel.
    /// EXAMPLE: A results 2.71828 A
    /// B/ results 1.77245 b
    Print(Register),
    
    /// S instruction: waits for user input
    Stop,

    /// Vertical Spacing. The instruction "/⋄" (/\u20DF) directs the computer to advance
    /// the tape one vertical space, without printing.
    NewLine,

    /// Constant as Instructions
    CaiStart,
    Cai(CaiSign, CaiOrder, CaiDigit, CaiComma),

    /// Swap D and R registers.
    DrExchange,
}

#[cfg(test)]
mod tests {
    use crate::instruction::*;

    #[test]
    pub fn instruction_equality() {
        assert_eq!(Instruction::Add(Register::B), Instruction::Add(Register::B));
    }
}