use std::{cell::RefCell, option::Option, rc::Rc};
use crate::program::AlpacaProgram;
use crate::exprs::prelude::*;
pub struct AlpacaBuilder {
program: AlpacaProgram,
pointer: Option<Rc<RefCell<AlpacaBasicBlock>>>,
}
impl AlpacaBuilder {
pub fn new() -> Self {
Self {
program: AlpacaProgram::new(),
pointer: None,
}
}
pub fn create_function(
&mut self,
name: &'static str,
ty: AlpacaBasicType,
) -> AlpacaFunctionBuilder {
let function_index = self.program.add_func(AlpacaFunction {
name,
ty,
body: Vec::new(),
});
AlpacaFunctionBuilder::new(self.program[function_index].clone())
}
pub fn set_pointer(&mut self, block: Option<Rc<RefCell<AlpacaBasicBlock>>>) {
self.pointer = block;
}
pub fn add_instruction(&mut self, inst: AlpacaInst) {
if let Some(block) = &self.pointer {
let mut block = block.borrow_mut();
block.insts.push(inst);
} else {
log::error!("pointer is not set!");
}
}
pub fn get_program(self) -> AlpacaProgram {
self.program
}
}
pub struct AlpacaFunctionBuilder {
function: Rc<RefCell<AlpacaFunction>>,
}
impl AlpacaFunctionBuilder {
fn new(function: Rc<RefCell<AlpacaFunction>>) -> Self {
Self { function }
}
pub fn add_block(&mut self, name: &'static str) -> Rc<RefCell<AlpacaBasicBlock>> {
let mut function = self.function.borrow_mut();
let block = Rc::new(RefCell::new(AlpacaBasicBlock {
name,
insts: Vec::new(),
}));
function.body.push(block.clone());
block
}
}