airlang 0.23.0

Air is a minimalist and universal programming language.
Documentation
use crate::cfg::lib::CoreLib;
use crate::semantics::val::ConstPrimFuncVal;
use crate::semantics::val::FreePrimFuncVal;
use crate::semantics::val::FuncVal;
use crate::semantics::val::MutPrimFuncVal;
use crate::semantics::val::Val;
use crate::type_::Key;
use crate::type_::Map;

#[derive(Clone)]
pub struct CorePrelude {
    pub not: FreePrimFuncVal,
    pub and: FreePrimFuncVal,
    pub or: FreePrimFuncVal,
    pub xor: FreePrimFuncVal,
    pub imply: FreePrimFuncVal,

    pub int_add: FreePrimFuncVal,
    pub int_subtract: FreePrimFuncVal,
    pub int_multiply: FreePrimFuncVal,
    pub int_divide: FreePrimFuncVal,
    pub int_less: FreePrimFuncVal,
    pub int_less_equal: FreePrimFuncVal,
    pub int_greater: FreePrimFuncVal,
    pub int_greater_equal: FreePrimFuncVal,
    pub int_less_greater: FreePrimFuncVal,

    pub decimal_add: FreePrimFuncVal,
    pub decimal_subtract: FreePrimFuncVal,
    pub decimal_multiply: FreePrimFuncVal,
    pub decimal_divide: FreePrimFuncVal,
    pub decimal_less: FreePrimFuncVal,
    pub decimal_less_equal: FreePrimFuncVal,
    pub decimal_greater: FreePrimFuncVal,
    pub decimal_greater_equal: FreePrimFuncVal,
    pub decimal_less_greater: FreePrimFuncVal,

    pub call: FreePrimFuncVal,

    pub move_: MutPrimFuncVal,

    pub exist: FreePrimFuncVal,
    pub import: FreePrimFuncVal,
    pub export: FreePrimFuncVal,
    pub with: MutPrimFuncVal,

    pub function: FreePrimFuncVal,
    pub apply: MutPrimFuncVal,

    pub get: ConstPrimFuncVal,
    pub set: MutPrimFuncVal,
    pub form: ConstPrimFuncVal,
    pub represent: MutPrimFuncVal,
    pub which: MutPrimFuncVal,

    pub do_: MutPrimFuncVal,
    pub test: MutPrimFuncVal,
    pub switch: MutPrimFuncVal,
    pub match_: MutPrimFuncVal,
    pub loop_: MutPrimFuncVal,
    pub iterate: MutPrimFuncVal,

    pub get_type: ConstPrimFuncVal,
    pub equal: FreePrimFuncVal,

    pub abort: FreePrimFuncVal,
    pub assert: FreePrimFuncVal,

    pub data: FreePrimFuncVal,
    pub id: FreePrimFuncVal,
    pub code: MutPrimFuncVal,
    pub eval: MutPrimFuncVal,
}

pub trait Prelude {
    fn extend(&self, map: &mut Map<Key, Val>);
}

impl CorePrelude {
    pub fn new(lib: &CoreLib) -> Self {
        Self {
            not: lib.bit.not.clone(),
            and: lib.bit.and.clone(),
            or: lib.bit.or.clone(),
            xor: lib.bit.xor.clone(),
            imply: lib.bit.imply.clone(),

            int_add: lib.int.add.clone(),
            int_subtract: lib.int.subtract.clone(),
            int_multiply: lib.int.multiply.clone(),
            int_divide: lib.int.divide.clone(),
            int_less: lib.int.less.clone(),
            int_less_equal: lib.int.less_equal.clone(),
            int_greater: lib.int.greater.clone(),
            int_greater_equal: lib.int.greater_equal.clone(),
            int_less_greater: lib.int.less_greater.clone(),

            decimal_add: lib.decimal.add.clone(),
            decimal_subtract: lib.decimal.subtract.clone(),
            decimal_multiply: lib.decimal.multiply.clone(),
            decimal_divide: lib.decimal.divide.clone(),
            decimal_less: lib.decimal.less.clone(),
            decimal_less_equal: lib.decimal.less_equal.clone(),
            decimal_greater: lib.decimal.greater.clone(),
            decimal_greater_equal: lib.decimal.greater_equal.clone(),
            decimal_less_greater: lib.decimal.less_greater.clone(),

            call: lib.call.new.clone(),

            move_: lib.map.move_.clone(),

            exist: lib.cfg.exist.clone(),
            import: lib.cfg.import.clone(),
            export: lib.cfg.export.clone(),
            with: lib.cfg.with.clone(),

            function: lib.func.new.clone(),
            apply: lib.func.apply.clone(),

            get: lib.ctx.get.clone(),
            set: lib.ctx.set.clone(),
            form: lib.ctx.form.clone(),
            represent: lib.ctx.represent.clone(),
            which: lib.ctx.which.clone(),

            do_: lib.ctrl.do_.clone(),
            test: lib.ctrl.test.clone(),
            switch: lib.ctrl.switch.clone(),
            match_: lib.ctrl.match_.clone(),
            loop_: lib.ctrl.loop_.clone(),
            iterate: lib.ctrl.iterate.clone(),

            get_type: lib.value.get_type.clone(),
            equal: lib.value.equal.clone(),

            abort: lib.error.abort.clone(),
            assert: lib.error.assert.clone(),

            data: lib.lang.data.clone(),
            id: lib.lang.id.clone(),
            code: lib.lang.code.clone(),
            eval: lib.lang.eval.clone(),
        }
    }
}

impl Prelude for CorePrelude {
    fn extend(&self, map: &mut Map<Key, Val>) {
        map_put_func(map, "not", &self.not);
        map_put_func(map, "and", &self.and);
        map_put_func(map, "or", &self.or);
        map_put_func(map, "xor", &self.xor);
        map_put_func(map, "imply", &self.imply);

        map_put_func(map, "+", &self.int_add);
        map_put_func(map, "-", &self.int_subtract);
        map_put_func(map, "*", &self.int_multiply);
        map_put_func(map, "/", &self.int_divide);
        map_put_func(map, "<", &self.int_less);
        map_put_func(map, "<=", &self.int_less_equal);
        map_put_func(map, ">", &self.int_greater);
        map_put_func(map, ">=", &self.int_greater_equal);
        map_put_func(map, "<>", &self.int_less_greater);

        map_put_func(map, "+.", &self.decimal_add);
        map_put_func(map, "-.", &self.decimal_subtract);
        map_put_func(map, "*.", &self.decimal_multiply);
        map_put_func(map, "/.", &self.decimal_divide);
        map_put_func(map, "<.", &self.decimal_less);
        map_put_func(map, "<=.", &self.decimal_less_equal);
        map_put_func(map, ">.", &self.decimal_greater);
        map_put_func(map, ">=.", &self.decimal_greater_equal);
        map_put_func(map, "<>.", &self.decimal_less_greater);

        map_put_func(map, "call", &self.call);

        map_put_func(map, "move", &self.move_);

        map_put_func(map, "exist", &self.exist);
        map_put_func(map, "import", &self.import);
        map_put_func(map, "export", &self.export);
        map_put_func(map, "with", &self.with);

        map_put_func(map, "function", &self.function);
        map_put_func(map, "apply", &self.apply);

        map_put_func(map, "get", &self.get);
        map_put_func(map, "set", &self.set);
        map_put_func(map, "form", &self.form);
        map_put_func(map, "=", &self.represent);
        map_put_func(map, "which", &self.which);

        map_put_func(map, "do", &self.do_);
        map_put_func(map, "test", &self.test);
        map_put_func(map, "switch", &self.switch);
        map_put_func(map, "match", &self.match_);
        map_put_func(map, "loop", &self.loop_);
        map_put_func(map, "iterate", &self.iterate);

        map_put_func(map, "get_type", &self.get_type);
        map_put_func(map, "==", &self.equal);

        map_put_func(map, "abort", &self.abort);
        map_put_func(map, "assert", &self.assert);

        map_put_func(map, "data", &self.data);
        map_put_func(map, "id", &self.id);
        map_put_func(map, "code", &self.code);
        map_put_func(map, "eval", &self.eval);
    }
}

pub fn map_put_func<V: Clone + Into<FuncVal>>(
    map: &mut Map<Key, Val>, name: &'static str, val: &V,
) {
    let name = Key::from_str_unchecked(name);
    let v = map.insert(name, Val::Func(val.clone().into()));
    assert!(v.is_none(), "names of preludes should be unique");
}

pub fn prelude_repr<T: Prelude>(t: T) -> Map<Key, Val> {
    let mut map = Map::default();
    t.extend(&mut map);
    map
}