mod annotator;
pub use annotator::*;
use p101_is::instruction::*;
use crate::encoding::*;
pub struct Encoder<E: Encoding, A: Annotator> {
encoding: E,
annotator: A
}
impl<E, A> Encoder<E, A> where E: Encoding + Default, A: Annotator + Default {
const DEFAULT_SEPARATOR: &'static str = "#";
pub fn new() -> Self {
Encoder {
encoding: Default::default(),
annotator: Default::default()
}
}
pub fn encode(&self, _program: &Vec<Instruction>) -> String {
let mut text = String::new();
for i in _program.iter() {
text += &self.encode_instruction(i);
}
text
}
fn encode_instruction(&self, i: &Instruction) -> String {
let code = self.encoding.encode(i);
let comment = self.annotator.comment(i);
if comment.is_empty() {
code + "\n"
} else {
format!("{} {} {}\n", code, Self::DEFAULT_SEPARATOR, &comment)
}
}
}
impl<E, A> Default for Encoder<E, A> where E: Encoding + Default, A: Annotator + Default {
fn default() -> Self {
Self::new()
}
}