quickscript 0.5.5

A quick programming language with a compiler implemented in Rust.
Documentation
use std::collections::HashMap;

use anyhow::Result;
use cranelift_codegen::{entity::EntityRef, ir::AbiParam};
use cranelift_frontend::{FunctionBuilder, Variable};
use cranelift_module::Module;

use crate::{
    ast::expr::{Definition, Expression},
    translator::func::FunctionTranslator,
    types::{clif::IntoClifType, Type},
};

use super::backend::CraneliftBackend;

impl<T> CraneliftBackend<T>
where
    T: Module,
{
    pub fn translate_fn(
        &mut self,
        args: Vec<Box<Definition>>,
        ret: Type,
        content: Vec<Box<Expression>>,
        is_entry: bool,
    ) -> Result<()> {
        let mut args_map = HashMap::new();

        for arg in args.clone() {
            if let Definition::Argument(name, ty) = *arg {
                let idx = self.ctx.func.signature.params.len();

                self.ctx
                    .func
                    .signature
                    .params
                    .push(AbiParam::new(ty.into_clif_type().unwrap()));

                args_map.insert(name, idx);
            }
        }

        self.ctx
            .func
            .signature
            .returns
            .push(AbiParam::new(ret.into_clif_type().unwrap()));

        let mut builder = FunctionBuilder::new(&mut self.ctx.func, &mut self.builder_ctx);
        let entry = builder.create_block();

        builder.append_block_params_for_function_params(entry);
        builder.switch_to_block(entry);
        builder.seal_block(entry);

        let mut vars = HashMap::new();
        let mut var_idx = 0;

        for (idx, arg) in args.iter().enumerate() {
            if let Definition::Argument(name, ty) = *arg.clone() {
                let val = builder.block_params(entry)[idx];
                let var = Variable::new(var_idx);

                builder.declare_var(var, ty.into_clif_type().unwrap());
                builder.def_var(var, val);
                vars.insert(name, var);

                var_idx += 1;
            }
        }

        let mut translator = FunctionTranslator::new(
            builder,
            &mut self.module,
            &mut self.data_desc,
            ret,
            vars,
            var_idx,
            is_entry,
        );

        for expr in content {
            translator.translate(*expr, self.watch_mode)?;
        }

        translator.builder.finalize();

        Ok(())
    }
}