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}