locrian 0.2.2

A simple embeddable functional programming language.
Documentation
use lazy_static::lazy_static;

use crate::{
    eval::EvalContext,
    parser::ExprValue,
    stdlib::{
        array::reduce,
        pipe::{do_, pipe},
    },
};

mod array;
mod bool;
mod object;
mod option;
mod result;
#[macro_use]
pub(crate) mod func;
mod num;
mod pipe;
mod pkg;
pub(crate) mod quote;
mod string;

lazy_static! {
    pub static ref STDLIB: EvalContext<'static> = EvalContext::new()
        .with_fn("bool:if", bool::if_)
        .with_fn("bool:not", bool::not)
        .with_fn("bool:eq", bool::eq)
        .with_fn("bool:gt", bool::gt)
        .with_fn("bool:lt", bool::lt)
        .with_fn("call", quote::call)
        .with_fn("let", quote::let_)
        .with_fn("use", pkg::use_)
        .with_fn("pipe", pipe)
        .with_fn("do", do_)
        .with_fn("string:concat", string::concat)
        .with_fn("string:split", string::split)
        .with_fn("string:replace", string::replace)
        .with_fn("string:ify", string::ify)
        .with_fn("string:format", string::format)
        .with_fn("string:escape", string::escape)
        .with_var("string:lf", ExprValue::String("\n".to_string()))
        .with_var("string:tab", ExprValue::String("\t".to_string()))
        .with_var("string:esc", ExprValue::String("\x1b".to_string()))
        .with_fn("num:add", num::add)
        .with_fn("num:sub", num::sub)
        .with_fn("num:mul", num::mul)
        .with_fn("num:div", num::div)
        .with_fn("num:pow", num::pow)
        .with_fn("array:map", array::map)
        .with_fn("array:merge", array::merge)
        .with_fn("array:append", array::append)
        .with_fn("array:at", array::at)
        .with_fn("array:reduce", array::reduce)
        .with_fn("array:length", array::length)
        .with_fn("array:slice", array::slice)
        .with_fn("array:head", array::head)
        .with_fn("array:tail", array::tail)
        .with_fn("array:last", array::last)
        .with_fn("array:filter", array::filter)
        .with_fn("array:find", array::find)
        .with_var("$use", ExprValue::Array(vec![]));
}

#[cfg(test)]
mod tests {

    use crate::{eval::EvalResult, eval_str, stdlib::STDLIB};

    #[test]
    fn test_add() {
        assert_eq!(
            eval_str("num:add(1.1, 2.2, 3.3)", STDLIB.clone()).unwrap(),
            EvalResult::Number(6.6)
        );
    }

    #[test]
    fn test_readme() {
        assert_eq!(
            eval_str(
                r#"
            use(["num", "bool"], '[
                let(
                {
                    "myFn": 'add($0, $1)
                },
                'myFn(2, 2)
                ), // 4
                if(eq(1, 1), 'add(6, 4), 'add(2, 2)) // 10
            ])
            "#,
                STDLIB.clone()
            )
            .unwrap(),
            EvalResult::Array(vec![EvalResult::Number(4_f64), EvalResult::Number(10_f64)])
        )
    }
}