airlang 0.26.0

Air is a minimalist and universal programming language.
Documentation
use crate::cfg::prim::lib::BasePrimLib;
use crate::semantics::val::PrimFuncVal;
use crate::semantics::val::Val;
use crate::type_::Key;
use crate::type_::Map;

#[derive(Copy, Clone)]
pub struct BasePrimPrelude {
    pub not: PrimFuncVal,
    pub and: PrimFuncVal,
    pub or: PrimFuncVal,
    pub xor: PrimFuncVal,
    pub imply: PrimFuncVal,

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

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

    pub move_: PrimFuncVal,

    pub quote: PrimFuncVal,

    pub call: PrimFuncVal,

    pub solve: PrimFuncVal,

    pub exist: PrimFuncVal,
    pub import: PrimFuncVal,
    pub export: PrimFuncVal,
    pub with: PrimFuncVal,

    pub function: PrimFuncVal,

    pub get: PrimFuncVal,
    pub set: PrimFuncVal,
    pub represent: PrimFuncVal,
    pub which: PrimFuncVal,

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

    pub get_type: PrimFuncVal,
    pub equal: PrimFuncVal,

    pub abort: PrimFuncVal,
    pub assert: PrimFuncVal,

    pub fact: PrimFuncVal,

    pub eval: PrimFuncVal,
}

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

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

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

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

            move_: lib.map.move_,

            quote: lib.quote.make,

            call: lib.call.make,

            solve: lib.solve.make,

            exist: lib.cfg.exist,
            import: lib.cfg.import,
            export: lib.cfg.export,
            with: lib.cfg.with,

            function: lib.func.make,

            get: lib.ctx.get,
            set: lib.ctx.set,
            represent: lib.ctx.represent,
            which: lib.ctx.which,

            do_: lib.ctrl.do_,
            test: lib.ctrl.test,
            switch: lib.ctrl.switch,
            match_: lib.ctrl.match_,
            loop_: lib.ctrl.loop_,
            iterate: lib.ctrl.iterate,

            get_type: lib.value.get_type,
            equal: lib.value.equal,

            abort: lib.error.abort,
            assert: lib.error.assert,

            fact: lib.fact.put,

            eval: lib.lang.semantics_eval,
        }
    }
}

impl Prelude for BasePrimPrelude {
    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, "move", self.move_);

        map_put_func(map, "quote", self.quote);

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

        map_put_func(map, "solve", self.solve);

        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, "get", self.get);
        map_put_func(map, "set", self.set);
        map_put_func(map, "represent", 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, "fact", self.fact);

        map_put_func(map, "eval", self.eval);
    }
}

pub fn map_put_func(map: &mut Map<Key, Val>, name: &'static str, val: PrimFuncVal) {
    let name = Key::from_str_unchecked(name);
    let v = map.insert(name, Val::Func(val.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
}