airlang 0.28.0

Air is a universal, reliable, and lean programming language.
Documentation
use std::mem::swap;

use const_format::concatcp;

use crate::bug;
use crate::cfg::CfgMod;
use crate::cfg::export_func;
use crate::semantics::cfg::Cfg;
use crate::semantics::core::PREFIX_CELL;
use crate::semantics::func::ConstInputFreeFunc;
use crate::semantics::func::MutFunc;
use crate::semantics::val::CELL;
use crate::semantics::val::PrimFuncVal;
use crate::semantics::val::Val;
use crate::type_::Key;
use crate::type_::Map;

#[derive(Copy, Clone)]
pub struct CellLib {
    pub get_value: PrimFuncVal,
    pub set_value: PrimFuncVal,
}

pub const GET_VALUE: &str = concatcp!(PREFIX_CELL, CELL, ".get_value");
pub const SET_VALUE: &str = concatcp!(PREFIX_CELL, CELL, ".set_value");

impl Default for CellLib {
    fn default() -> Self {
        Self {
            get_value: ConstInputFreeFunc { fn_: get_value }.build(),
            set_value: MutFunc { fn_: set_value }.build(),
        }
    }
}

impl CfgMod for CellLib {
    fn export(self, cfg: &mut Map<Key, Val>) {
        export_func(cfg, GET_VALUE, self.get_value);
        export_func(cfg, SET_VALUE, self.set_value);
    }
}

pub fn get_value(cfg: &mut Cfg, ctx: &Val) -> Val {
    let Val::Cell(cell) = ctx else {
        return bug!(cfg, "{GET_VALUE}: expected context to be a cell, but got {ctx}");
    };
    cell.value.clone()
}

pub fn set_value(cfg: &mut Cfg, ctx: &mut Val, mut input: Val) -> Val {
    let Val::Cell(cell) = ctx else {
        return bug!(cfg, "{SET_VALUE}: expected context to be a cell, but got {ctx}");
    };
    swap(&mut cell.value, &mut input);
    input
}