p101_enc 0.11.0

Library to convert Olivetti P101 program to and from different encodings
Documentation
use p101_is::*;

pub trait Annotator {
    fn comment(&self, i: &Instruction) -> String;
}

#[derive(Default)]
pub struct DefaultAnnotator;

impl Annotator for DefaultAnnotator {
    fn comment(&self, i: &Instruction) -> String {
        match i {
            Instruction::Abs => "Store absolute value of A register in A".into(),
            Instruction::Add(o) => format!("Add register {} to the accumulator", o),
            Instruction::CaiStart => "Start of a constant as instruction".into(),
            Instruction::Cai(sign, order, digit, comma) => {
                let prefix = match order {
                    CaiOrder::High => "last",
                    CaiOrder::Low => "a",
                };

                format!("Prepend {} digit {}{}{}", prefix, sign, digit, comma)
            },
            Instruction::ConditionalJump(o) => format!("If accumulator is not zero jump to {}", o),
            Instruction::CopyDecimal => "Copy the decimal part of the accumulator to register M".into(),
            Instruction::CopyM(o) => {
                match o {
                    Register::M => "Inoperative".into(),
                    Register::R => "Inoperative".into(),
                    Register::A => "Start defining a Constant As Instruction".into(),
                    _ => format!("Copy the value of register M to register {}", o)
                }
            },
            Instruction::CopyToA(o) => format!("Copy the value of register {} to the accumulator", o),
            Instruction::Div(o) => format!("Divide the accumulator by register {}", o),
            Instruction::DrExchange => "Exchange R and D registers".into(),
            Instruction::Jump(o) => format!("Jump to {}", o),
            Instruction::Label(d) => format!("Label {}", d),
            Instruction::Mul(o) => format!("Multiply register {} by the accumulator", o),
            Instruction::NewLine => "Print a new line".into(),
            Instruction::Print(o) => format!("Print register {} value", o),
            Instruction::Reset(o) => format!("Clear register {}",  o),
            Instruction::Sqr(o) => format!("Calculate the square root of register {}", o),
            Instruction::Stop => "Suspend computing to allow user input".into(),
            Instruction::Sub(o) => format!("Subtract register {} from the accumulator", o),
            Instruction::SwapA(o) => {
                match o {
                    Register::R => "Copy register M value to the accumulator".into(),
                    Register::A => "Absolute value of the accumulator".into(),
                    _ => format!("Exchange accumulator value with register {}", o)
                }
            },
        }
    }
}

#[derive(Default)]
pub struct NullAnnotator;

impl Annotator for NullAnnotator {
    fn comment(&self, _i: &Instruction) -> String {
        "".into()
    }
}