airlang 0.26.0

Air is a minimalist and universal programming language.
Documentation
use crate::semantics::cfg::Cfg;
use crate::semantics::core::form::CellForm;
use crate::semantics::core::form::ListForm;
use crate::semantics::core::form::MapForm;
use crate::semantics::core::form::PairForm;
use crate::semantics::core::key::KeyEval;
use crate::semantics::func::DynFunc;
use crate::semantics::val::CallVal;
use crate::semantics::val::CellVal;
use crate::semantics::val::ListVal;
use crate::semantics::val::MapVal;
use crate::semantics::val::PairVal;
use crate::semantics::val::QuoteVal;
use crate::semantics::val::SolveVal;
use crate::semantics::val::Val;
use crate::type_::Call;
use crate::type_::Key;
use crate::type_::Quote;
use crate::type_::Solve;

pub(crate) struct QuoteEval;

impl DynFunc<Cfg, Val, QuoteVal, Val> for QuoteEval {
    fn call(&self, _cfg: &mut Cfg, _ctx: &mut Val, quote: QuoteVal) -> Val {
        let quote = Quote::from(quote);
        quote.value
    }
}

pub(crate) struct CallEval<'a, Func, Input> {
    pub(crate) func: &'a Func,
    pub(crate) input: &'a Input,
}

impl<'a, Func, Input> DynFunc<Cfg, Val, CallVal, Val> for CallEval<'a, Func, Input>
where
    Func: DynFunc<Cfg, Val, Val, Val>,
    Input: DynFunc<Cfg, Val, Val, Val>,
{
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, call: CallVal) -> Val {
        let call = Call::from(call);
        let func = self.func.call(cfg, ctx, call.func);
        let Val::Func(func) = func else {
            cfg.abort();
            return Val::default();
        };
        let input = self.input.call(cfg, ctx, call.input);
        if cfg.is_aborted() {
            return Val::default();
        }
        func.call(cfg, ctx, input)
    }
}

pub(crate) struct SolveEval<'a, Func, Output> {
    pub(crate) func: &'a Func,
    pub(crate) output: &'a Output,
}

impl<'a, Func, Output> DynFunc<Cfg, Val, SolveVal, Val> for SolveEval<'a, Func, Output>
where
    Func: DynFunc<Cfg, Val, Val, Val>,
    Output: DynFunc<Cfg, Val, Val, Val>,
{
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, solve: SolveVal) -> Val {
        let solve = Solve::from(solve);
        let func = self.func.call(cfg, ctx, solve.func);
        let Val::Func(func) = func else {
            cfg.abort();
            return Val::default();
        };
        let output = self.output.call(cfg, ctx, solve.output);
        if cfg.is_aborted() {
            return Val::default();
        }
        let Some(input) = cfg.fact_solve(func, output) else {
            cfg.abort();
            return Val::default();
        };
        input
    }
}

#[derive(Default, Copy, Clone)]
pub struct Eval;

impl DynFunc<Cfg, Val, Val, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, val: Val) -> Val {
        if cfg.is_aborted() {
            return Val::default();
        }
        match val {
            Val::Key(key) => self.call(cfg, ctx, key),
            Val::Cell(cell) => self.call(cfg, ctx, cell),
            Val::Pair(pair) => self.call(cfg, ctx, pair),
            Val::List(list) => self.call(cfg, ctx, list),
            Val::Map(map) => self.call(cfg, ctx, map),
            Val::Quote(quote) => self.call(cfg, ctx, quote),
            Val::Call(call) => self.call(cfg, ctx, call),
            Val::Solve(solve) => self.call(cfg, ctx, solve),
            v => v,
        }
    }
}

impl DynFunc<Cfg, Val, Key, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, key: Key) -> Val {
        KeyEval.call(cfg, ctx, key)
    }
}

impl DynFunc<Cfg, Val, CellVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, cell: CellVal) -> Val {
        Val::Cell(CellForm { value: self }.call(cfg, ctx, cell))
    }
}

impl DynFunc<Cfg, Val, PairVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, pair: PairVal) -> Val {
        Val::Pair(PairForm { left: self, right: self }.call(cfg, ctx, pair))
    }
}

impl DynFunc<Cfg, Val, ListVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, list: ListVal) -> Val {
        Val::List(ListForm { item: self }.call(cfg, ctx, list))
    }
}

impl DynFunc<Cfg, Val, MapVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, map: MapVal) -> Val {
        Val::Map(MapForm { value: self }.call(cfg, ctx, map))
    }
}

impl DynFunc<Cfg, Val, QuoteVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, quote: QuoteVal) -> Val {
        QuoteEval.call(cfg, ctx, quote)
    }
}

impl DynFunc<Cfg, Val, CallVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, call: CallVal) -> Val {
        CallEval { func: self, input: self }.call(cfg, ctx, call)
    }
}

impl DynFunc<Cfg, Val, SolveVal, Val> for Eval {
    fn call(&self, cfg: &mut Cfg, ctx: &mut Val, solve: SolveVal) -> Val {
        SolveEval { func: self, output: self }.call(cfg, ctx, solve)
    }
}