use std::{cell::RefCell, rc::Rc};
use std::ops::Index;
use index_vec::{Idx, IndexVec};
use crate::exprs::core::{AlpacaBasicBlock, AlpacaFunction};
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct AlpacaProgramIndex {
index: usize,
}
impl Idx for AlpacaProgramIndex {
fn index(self) -> usize { self.index }
fn from_usize(idx: usize) -> Self {
Self { index: idx, }
}
}
#[derive(Debug)]
pub struct AlpacaProgram {
program: IndexVec<AlpacaProgramIndex, Rc<RefCell<AlpacaFunction>>>,
}
impl Index<AlpacaProgramIndex> for AlpacaProgram {
type Output = Rc<RefCell<AlpacaFunction>>;
fn index(&self, index: AlpacaProgramIndex) -> &Self::Output { &self.program[index] }
}
impl AlpacaProgram {
pub fn new() -> Self {
Self { program: IndexVec::new() }
}
pub fn add_func(&mut self, expr: AlpacaFunction) -> AlpacaProgramIndex { self.program.push(Rc::new(RefCell::new(expr))) }
pub fn get_functions(&self) -> impl Iterator<Item = &Rc<RefCell<AlpacaFunction>>> { self.program.iter() }
pub fn find_function(&self, name: &str) -> Option<AlpacaProgramIndex> {
self.program.iter().position(|func| func.borrow().name == name).map(AlpacaProgramIndex::from_usize)
}
pub fn get_blocks_ref(&self, func: AlpacaProgramIndex) -> Vec<Rc<RefCell<AlpacaBasicBlock>>> {
self.program[func].borrow().body.clone()
}
pub fn get_blocks_mut(&self, func: AlpacaProgramIndex) -> Vec<Rc<RefCell<AlpacaBasicBlock>>> {
self.program[func].borrow_mut().body.clone()
}
pub fn remove(&mut self, index: AlpacaProgramIndex) -> Rc<RefCell<AlpacaFunction>> { self.program.remove(index) }
pub fn swap(&mut self, index1: AlpacaProgramIndex, index2: AlpacaProgramIndex) {
let temp = self.program[index1].clone();
self.program[index1] = self.program[index2].clone();
self.program[index2] = temp;
}
}