Add math and random functions
Register `abs`, `min`, `max`, and `random` functions to the environment. This also includes adding `PartialOrd` implementation for `Value` to support comparisons for `min` and `max`.
This commit is contained in:
@@ -471,4 +471,70 @@ fn register_logic(env: &Environment) {
|
||||
_ => Value::Void,
|
||||
}
|
||||
});
|
||||
|
||||
register_math(env);
|
||||
}
|
||||
|
||||
fn register_math(env: &Environment) {
|
||||
let math_unary_ty = StaticType::Function(Box::new(Signature {
|
||||
params: StaticType::Tuple(vec![StaticType::Any]),
|
||||
ret: StaticType::Any,
|
||||
}));
|
||||
|
||||
env.register_native("abs", math_unary_ty, Purity::Pure, |args| {
|
||||
if args.len() != 1 {
|
||||
return Value::Void;
|
||||
}
|
||||
match args[0] {
|
||||
Value::Int(i) => Value::Int(i.abs()),
|
||||
Value::Float(f) => Value::Float(f.abs()),
|
||||
_ => Value::Void,
|
||||
}
|
||||
});
|
||||
|
||||
let math_variadic_ty = StaticType::Function(Box::new(Signature {
|
||||
params: StaticType::Any,
|
||||
ret: StaticType::Any,
|
||||
}));
|
||||
|
||||
env.register_native("min", math_variadic_ty.clone(), Purity::Pure, |args| {
|
||||
if args.is_empty() {
|
||||
return Value::Void;
|
||||
}
|
||||
let mut best = args[0].clone();
|
||||
for arg in &args[1..] {
|
||||
if *arg < best {
|
||||
best = arg.clone();
|
||||
}
|
||||
}
|
||||
best
|
||||
});
|
||||
|
||||
env.register_native("max", math_variadic_ty, Purity::Pure, |args| {
|
||||
if args.is_empty() {
|
||||
return Value::Void;
|
||||
}
|
||||
let mut best = args[0].clone();
|
||||
for arg in &args[1..] {
|
||||
if *arg > best {
|
||||
best = arg.clone();
|
||||
}
|
||||
}
|
||||
best
|
||||
});
|
||||
|
||||
let random_ty = StaticType::Function(Box::new(Signature {
|
||||
params: StaticType::Tuple(vec![]),
|
||||
ret: StaticType::Float,
|
||||
}));
|
||||
|
||||
// Simple LCG (no dependencies required)
|
||||
static mut SEED: u64 = 0x12345678;
|
||||
env.register_native("random", random_ty, Purity::SideEffectFree, |_| {
|
||||
unsafe {
|
||||
SEED = SEED.wrapping_mul(6364136223846793005).wrapping_add(1);
|
||||
let val = (SEED >> 32) as f64 / (u32::MAX as f64);
|
||||
Value::Float(val)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -117,6 +117,20 @@ impl PartialEq for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Value {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
match (self, other) {
|
||||
(Value::Int(a), Value::Int(b)) => a.partial_cmp(b),
|
||||
(Value::Float(a), Value::Float(b)) => a.partial_cmp(b),
|
||||
(Value::Int(a), Value::Float(b)) => (*a as f64).partial_cmp(b),
|
||||
(Value::Float(a), Value::Int(b)) => a.partial_cmp(&(*b as f64)),
|
||||
(Value::DateTime(a), Value::DateTime(b)) => a.partial_cmp(b),
|
||||
(Value::Text(a), Value::Text(b)) => a.partial_cmp(b),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Signature {
|
||||
pub params: StaticType,
|
||||
|
||||
Reference in New Issue
Block a user