use std::usize;
use smallvec::SmallVec;
use {Area,Function,StrRef,Value};
#[derive(Clone,Debug,PartialEq,Eq)]
pub struct Mnemonic {
pub area: Area,
pub opcode: StrRef,
pub operands: SmallVec<[Value; 3]>,
pub statement_count: usize,
}
impl Mnemonic {
pub fn new(a: Area, s: StrRef) -> Mnemonic {
Mnemonic{
area: a,
opcode: s,
operands: SmallVec::default(),
statement_count: 0,
}
}
}
#[derive(Clone,Copy,Debug,PartialOrd,Ord,PartialEq,Eq)]
pub struct MnemonicIndex {
index: usize
}
impl MnemonicIndex {
pub fn new(i: usize) -> MnemonicIndex { MnemonicIndex{ index: i } }
pub fn index(&self) -> usize { self.index }
}
#[derive(Clone)]
pub struct MnemonicIterator<'a> {
function: &'a Function,
index: usize,
max: usize,
}
impl<'a> MnemonicIterator<'a> {
pub fn new(function: &'a Function,index: usize, max: usize) -> MnemonicIterator<'a> {
MnemonicIterator{
function: function,
index: index,
max: max,
}
}
}
impl<'a> Iterator for MnemonicIterator<'a> {
type Item = (MnemonicIndex,&'a Mnemonic);
fn next(&mut self) -> Option<(MnemonicIndex,&'a Mnemonic)> {
if self.index <= self.max {
let idx = MnemonicIndex::new(self.index);
let mne = self.function.mnemonic(idx);
self.index += 1;
Some((idx,mne))
} else {
None
}
}
}
impl<'a> ExactSizeIterator for MnemonicIterator<'a> {
fn len(&self) -> usize {
self.max - self.index + 1
}
}
impl<'a> DoubleEndedIterator for MnemonicIterator<'a> {
fn next_back(&mut self) -> Option<(MnemonicIndex,&'a Mnemonic)> {
if self.index <= self.max {
let idx = MnemonicIndex::new(self.max);
let mne = self.function.mnemonic(idx);
if self.max == self.index {
self.index = self.max + 1;
} else {
self.max -= 1;
}
Some((idx,mne))
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use ron_uuid::UUID;
#[test]
fn mnemonic_iter() {
use {Region, TestArch};
let _ = simple_logger::init();
let data = b"MixJ9xxxxMisR".to_vec();
let reg = Region::from_buf("", 16, data, 0, None);
let func = Function::new::<TestArch>((), 0, ®, UUID::now()).unwrap();
let (bb0_idx, bb0) = func.basic_blocks().next().unwrap();
let (bb1_idx, bb1) = func.basic_blocks().skip(1).next().unwrap();
assert_eq!(bb0.mnemonics, MnemonicIndex::new(0)..MnemonicIndex::new(2));
assert_eq!(bb1.mnemonics, MnemonicIndex::new(2)..MnemonicIndex::new(4));
assert_eq!(func.mnemonics(bb0_idx).count(), 2);
assert_eq!(func.mnemonics(bb0_idx).len(), 2);
assert_eq!(func.mnemonics(bb1_idx).count(), 2);
assert_eq!(func.mnemonics(bb1_idx).len(), 2);
assert_eq!(func.mnemonics(bb0_idx).rev().count(), 2);
assert_eq!(func.mnemonics(bb1_idx).rev().count(), 2);
}
}