Skip to main content

tancore/
bool.rs

1use tan::{context::Context, error::Error, expr::Expr, util::module_util::require_module};
2
3// #insight `and` is short-circuting, cannot be implemented with a function, needs a macro or a special form.
4// #insight `or` is short-circuting, cannot be implemented with a function, needs a macro or a special form.
5
6// #todo introduce a way to have functions with lazily evaluated arguments, when you don't need full macro power.
7
8pub fn bool_not(args: &[Expr]) -> Result<Expr, Error> {
9    // #todo consider binary/bitmask version.
10    // #todo consider operator `~` (_not_ `!`)
11
12    let [value] = args else {
13        return Err(Error::invalid_arguments("expects one argument", None));
14    };
15
16    let Some(predicate) = value.as_bool() else {
17        return Err(Error::invalid_arguments(
18            "`not` argument should be boolean",
19            value.range(),
20        ));
21    };
22
23    Ok(Expr::Bool(!predicate))
24}
25
26pub fn setup_lib_bool(context: &mut Context) {
27    // #todo move to a 'bool' or 'boolean' module and import some functions to prelude.
28    let module = require_module("prelude", context);
29
30    // #todo better name?
31    module.insert_invocable("not", Expr::foreign_func(&bool_not));
32}