use crate::ir::id::FunctionID;
use crate::ir::types::Location;
use crate::subiterator::function_subiterator::FuncSubIterator;
pub struct ModuleSubIterator {
pub(crate) curr_idx: usize,
metadata: Vec<(FunctionID, usize)>,
pub(crate) func_iterator: FuncSubIterator,
skip_funcs: Vec<FunctionID>,
}
impl ModuleSubIterator {
pub fn new(metadata: Vec<(FunctionID, usize)>, skip_funcs: Vec<FunctionID>) -> Self {
if metadata.is_empty() {
return ModuleSubIterator {
curr_idx: 0,
metadata,
func_iterator: FuncSubIterator::new(0),
skip_funcs,
};
}
let curr_idx = 0;
let (_curr_fid, curr_num_instrs) = metadata[curr_idx];
let mut mod_it = ModuleSubIterator {
curr_idx,
metadata,
func_iterator: FuncSubIterator::new(curr_num_instrs),
skip_funcs,
};
mod_it.handle_skips();
mod_it
}
pub fn has_curr(&self) -> bool {
self.curr_idx < self.metadata.len()
}
pub fn get_curr_func(&self) -> (FunctionID, usize) {
self.metadata[self.curr_idx]
}
pub fn curr_loc(&self) -> (Location, bool) {
let curr_instr = self.func_iterator.curr_instr;
(
Location::Module {
func_idx: self.get_curr_func().0,
instr_idx: curr_instr,
},
self.func_iterator.is_end(curr_instr),
)
}
pub(crate) fn reset_from_comp_iterator(&mut self, metadata: Vec<(FunctionID, usize)>) {
self.metadata = metadata;
self.reset();
}
pub fn reset(&mut self) {
self.curr_idx = 0;
self.handle_skips();
self.func_iterator.reset(self.get_curr_func().1);
}
fn handle_skips(&mut self) {
let mut curr_fid = self.get_curr_func().0;
while self.skip_funcs.contains(&curr_fid) {
self.curr_idx += 1;
if self.curr_idx >= self.metadata.len() {
break;
}
curr_fid = self.get_curr_func().0;
}
}
fn next_function(&mut self) -> bool {
if !self.has_next_function() {
return false;
}
self.curr_idx += 1;
self.handle_skips();
if self.curr_idx < self.metadata.len() {
self.func_iterator = FuncSubIterator::new(self.get_curr_func().1);
true
} else {
false
}
}
pub fn has_next_function(&self) -> bool {
self.curr_idx + 1 < self.metadata.len()
}
pub(crate) fn has_next(&self) -> bool {
self.func_iterator.has_next() || self.has_next_function()
}
pub(crate) fn next(&mut self) -> bool {
if self.func_iterator.has_next() {
self.func_iterator.next()
} else {
self.next_function()
}
}
}