Files
orchid/orchid-std/src/std/number/num_lib.rs
Lawrence Bethlenfalvy f38193edcc
All checks were successful
Rust / build (push) Successful in 4m8s
Protocols and operators mostly
2026-01-21 22:22:58 +01:00

61 lines
1.8 KiB
Rust

use orchid_base::error::mk_errv;
use orchid_base::interner::is;
use orchid_base::number::Numeric;
use orchid_extension::func_atom::get_arg;
use orchid_extension::tree::{GenMember, fun, prefix};
use ordered_float::NotNan;
use rust_decimal::prelude::ToPrimitive;
use super::num_atom::{Float, HomoArray, Int, Num};
pub fn gen_num_lib() -> Vec<GenMember> {
prefix("std::number", [
fun(false, "add", async |a: Num, b: Num| {
Num(match HomoArray::new([a.0, b.0]) {
HomoArray::Int([a, b]) => Numeric::Int(a + b),
HomoArray::Float([a, b]) => Numeric::Float(a + b),
})
}),
fun(false, "sub", async |a: Num, b: Num| {
Num(match HomoArray::new([a.0, b.0]) {
HomoArray::Int([a, b]) => Numeric::Int(a - b),
HomoArray::Float([a, b]) => Numeric::Float(a - b),
})
}),
fun(false, "neg", async |a: Num| {
Num(match a.0 {
Numeric::Int(i) => Numeric::Int(-i),
Numeric::Float(f) => Numeric::Float(-f),
})
}),
fun(false, "mul", async |a: Num, b: Num| {
Num(match HomoArray::new([a.0, b.0]) {
HomoArray::Int([a, b]) => Numeric::Int(a * b),
HomoArray::Float([a, b]) => Numeric::Float(a * b),
})
}),
fun(false, "idiv", async |a: Int, b: Int| Int(a.0 / b.0)),
fun(false, "imod", async |a: Int, b: Int| Int(a.0 % b.0)),
fun(false, "fdiv", async |a: Float, b: Float| Float(a.0 / b.0)),
fun(false, "fmod", async |a: Float, b: Float| {
Float(a.0 - NotNan::new((a.0 / b.0).trunc()).unwrap() * b.0)
}),
fun(false, "to_i", async |a: Num| {
Ok(Int(match a.0 {
Numeric::Int(i) => i,
Numeric::Float(f) => match f.to_i64() {
Some(i) => i,
None => {
return Err(mk_errv(
is("Float out of range").await,
format!("{f} is not representable as an integer"),
[get_arg(0).pos().await],
));
},
},
}))
}),
fun(false, "to_f", async |a: Num| Float(a.0.to_f64())),
])
}