alpaca_ir 0.0.0

AlpacaIR is a intermediate represenation meant to make making compilers easier.
Documentation
use std::{cell::RefCell, rc::Rc, option::Option};

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
    }
}