use crate::ir::id::{FunctionID, ModuleID};
use crate::ir::types::Location;
use crate::subiterator::module_subiterator::ModuleSubIterator;
use std::collections::HashMap;
pub struct ComponentSubIterator {
curr_mod: ModuleID,
num_mods: usize,
pub(crate) mod_iterator: ModuleSubIterator,
metadata: HashMap<ModuleID, Vec<(FunctionID, usize)>>,
skip_funcs: HashMap<ModuleID, Vec<FunctionID>>,
}
impl ComponentSubIterator {
pub fn new(
curr_mod: ModuleID,
num_mods: usize,
metadata: HashMap<ModuleID, Vec<(FunctionID, usize)>>,
skip_funcs: HashMap<ModuleID, Vec<FunctionID>>,
) -> Self {
if num_mods == 0 {
return ComponentSubIterator {
curr_mod,
num_mods,
metadata,
mod_iterator: ModuleSubIterator::new(vec![], vec![]),
skip_funcs,
};
}
ComponentSubIterator {
curr_mod,
num_mods,
metadata: metadata.clone(),
mod_iterator: ModuleSubIterator::new(
(*metadata.get(&curr_mod).unwrap()).clone(),
match skip_funcs.contains_key(&curr_mod) {
true => skip_funcs.get(&curr_mod).unwrap().clone(),
false => vec![],
},
),
skip_funcs,
}
}
pub fn reset(&mut self) {
*self.curr_mod = 0;
self.mod_iterator
.reset_from_comp_iterator((*self.metadata.get(&self.curr_mod).unwrap()).clone());
}
fn next_module(&mut self) -> bool {
*self.curr_mod += 1;
if *self.curr_mod < self.num_mods as u32 {
let met = self.metadata.get(&self.curr_mod).unwrap().clone();
self.mod_iterator = ModuleSubIterator::new(
met,
match self.skip_funcs.contains_key(&self.curr_mod) {
true => self.skip_funcs.get(&self.curr_mod).unwrap().clone(),
false => vec![],
},
);
true
} else {
false
}
}
pub fn curr_mod_idx(&self) -> ModuleID {
self.curr_mod
}
pub fn curr_func_idx(&self) -> FunctionID {
self.mod_iterator.get_curr_func().0
}
pub fn curr_instr_idx(&self) -> usize {
self.mod_iterator.func_iterator.curr_instr
}
pub fn end(&self) -> bool {
*self.curr_mod as usize == self.num_mods
}
pub fn has_curr(&self) -> bool {
!self.end() && self.mod_iterator.has_curr()
}
pub fn curr_loc(&self) -> (Location, bool) {
if let (
Location::Module {
func_idx,
instr_idx,
},
is_end,
) = self.mod_iterator.curr_loc()
{
(
Location::Component {
mod_idx: self.curr_mod,
func_idx,
instr_idx,
},
is_end,
)
} else {
panic!("Internal error: Should have gotten Module Location!")
}
}
pub(crate) fn curr_loc_indices(&self) -> (usize, FunctionID, usize) {
match self.curr_loc() {
(
Location::Component {
mod_idx,
func_idx,
instr_idx,
..
},
..,
) => (*mod_idx as usize, func_idx, instr_idx),
_ => panic!("Internal error: Should have gotten component location!"),
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> bool {
if self.mod_iterator.has_next() {
self.mod_iterator.next()
} else {
self.next_module()
}
}
}