use tan::{
context::Context,
error::Error,
expr::Expr,
util::{
args::{unpack_bool_arg, unpack_float_arg, unpack_int_arg, unpack_stringable_arg},
module_util::require_module,
},
};
pub fn int_from_float(args: &[Expr]) -> Result<Expr, Error> {
let value = unpack_float_arg(args, 0, "value")?;
Ok(Expr::Int(value as i64))
}
pub fn int_from_bool(args: &[Expr]) -> Result<Expr, Error> {
let value = unpack_bool_arg(args, 0, "value")?;
Ok(Expr::Int(if value { 1 } else { 0 }))
}
pub fn int_from_string(args: &[Expr]) -> Result<Expr, Error> {
let string = unpack_stringable_arg(args, 0, "string")?;
let Ok(value) = string.parse::<i64>() else {
return Err(Error::invalid_arguments(
&format!("string=`{string}` is not a valid Int number"),
args[0].range(),
));
};
Ok(Expr::Int(value))
}
pub fn int_bitwise_and(args: &[Expr]) -> Result<Expr, Error> {
let n = unpack_int_arg(args, 0, "n")?;
let mask = unpack_int_arg(args, 1, "mask")?;
Ok(Expr::Int(n & mask))
}
pub fn int_bitwise_or(args: &[Expr]) -> Result<Expr, Error> {
let n = unpack_int_arg(args, 0, "n")?;
let mask = unpack_int_arg(args, 1, "mask")?;
Ok(Expr::Int(n | mask))
}
pub fn setup_lib_int(context: &mut Context) {
let module = require_module("prelude", context);
module.insert_invocable("Int$$Float", Expr::foreign_func(&int_from_float));
module.insert_invocable("Int$$Bool", Expr::foreign_func(&int_from_bool));
module.insert_invocable("Int$$String", Expr::foreign_func(&int_from_string));
module.insert_invocable("bit-and", Expr::foreign_func(&int_bitwise_and));
module.insert_invocable("bit-or", Expr::foreign_func(&int_bitwise_or));
}