airlang 0.23.0

Air is a minimalist and universal programming language.
Documentation
use std::rc::Rc;

use crate::semantics::cfg::Cfg;
use crate::semantics::val::Val;

pub trait FreeFn<Cfg, I, O> {
    fn free_call(&self, cfg: &mut Cfg, input: I) -> O;
}

impl<Cfg, I, O, T> FreeFn<Cfg, I, O> for &T
where T: FreeFn<Cfg, I, O>
{
    fn free_call(&self, cfg: &mut Cfg, input: I) -> O {
        (**self).free_call(cfg, input)
    }
}

impl<Cfg, I, O, T> FreeFn<Cfg, I, O> for &mut T
where T: FreeFn<Cfg, I, O>
{
    fn free_call(&self, cfg: &mut Cfg, input: I) -> O {
        (**self).free_call(cfg, input)
    }
}

#[derive(Clone)]
pub struct FreePrimFunc {
    pub(crate) raw_input: bool,
    pub(crate) fn_: Rc<dyn FreeFn<Cfg, Val, Val>>,
}

impl FreeFn<Cfg, Val, Val> for FreePrimFunc {
    fn free_call(&self, cfg: &mut Cfg, input: Val) -> Val {
        self.fn_.free_call(cfg, input)
    }
}

impl Default for FreePrimFunc {
    fn default() -> Self {
        struct F;
        impl FreeFn<Cfg, Val, Val> for F {
            fn free_call(&self, _cfg: &mut Cfg, _input: Val) -> Val {
                Val::default()
            }
        }
        Self { fn_: Rc::new(F), raw_input: false }
    }
}

impl PartialEq for FreePrimFunc {
    fn eq(&self, other: &FreePrimFunc) -> bool {
        self.raw_input == other.raw_input && Rc::ptr_eq(&self.fn_, &other.fn_)
    }
}

impl Eq for FreePrimFunc {}