use crate::context::Context; use crate::env::Env; use crate::ir::IR; use crate::stable::StringIdx; use crate::ty::TyIdx; use std::slice::IterMut; /// A basic block. /// /// A basic block is a collection of #[derive(Debug, Default, PartialEq, Clone)] pub struct Block { env: Env, ir: Vec, } impl Block { /// Perform IR-wise improvement. /// /// See `IR.improve` for more information. pub fn improve_ir( &mut self, mut context: &mut Context, improver: F, ) { for ir in self.ir.iter_mut() { improver(ir, &mut context); } } /// Consumes the block and returns the IR data. pub fn ir(self) -> Vec { self.ir } pub fn is_empty(&self) -> bool { self.ir.is_empty() } pub fn iter_mut(&mut self) -> IterMut { self.ir.iter_mut() } pub fn new(env: Env) -> Block { Block { env, ir: Vec::default(), } } pub fn pop(&mut self) -> Option { self.ir.pop() } pub fn push(&mut self, ir: IR) { self.ir.push(ir); } pub fn env(&self) -> &Env { &self.env } pub fn env_get(&self, name: StringIdx) -> Option<&TyIdx> { self.env.get(name) } pub fn env_set(&mut self, name: StringIdx, ty: TyIdx) { self.env.set(name, ty) } } #[derive(Debug, Clone, PartialEq)] pub struct BlockIdx(usize); impl From for BlockIdx { fn from(i: usize) -> BlockIdx { BlockIdx(i) } } impl From for usize { fn from(i: BlockIdx) -> usize { i.0 } } impl From<&BlockIdx> for usize { fn from(i: &BlockIdx) -> usize { i.0 } }