Skip to main content

mailang_stdlib/stdlib/
math.rs

1//! Math built-in functions
2
3use mailang_bytecode::Value;
4
5fn to_f64(v: &Value) -> Result<f64, String> {
6    match v {
7        Value::Int(n) => Ok(*n as f64),
8        Value::Float(n) => Ok(*n),
9        _ => Err("Expected a number".to_string()),
10    }
11}
12
13pub fn builtin_sqrt(args: &[Value]) -> Result<Value, String> {
14    match &args[0] {
15        Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
16        Value::Float(n) => Ok(Value::Float(n.sqrt())),
17        _ => Err("sqrt expects a number".to_string()),
18    }
19}
20
21pub fn builtin_abs(args: &[Value]) -> Result<Value, String> {
22    match &args[0] {
23        Value::Int(n) => Ok(Value::Int(n.abs())),
24        Value::Float(n) => Ok(Value::Float(n.abs())),
25        _ => Err("abs expects a number".to_string()),
26    }
27}
28
29pub fn builtin_sin(args: &[Value]) -> Result<Value, String> {
30    let n = to_f64(&args[0])?;
31    Ok(Value::Float(n.sin()))
32}
33
34pub fn builtin_cos(args: &[Value]) -> Result<Value, String> {
35    let n = to_f64(&args[0])?;
36    Ok(Value::Float(n.cos()))
37}
38
39pub fn builtin_floor(args: &[Value]) -> Result<Value, String> {
40    let n = to_f64(&args[0])?;
41    Ok(Value::Int(n.floor() as i64))
42}
43
44pub fn builtin_ceil(args: &[Value]) -> Result<Value, String> {
45    let n = to_f64(&args[0])?;
46    Ok(Value::Int(n.ceil() as i64))
47}
48
49pub fn builtin_round(args: &[Value]) -> Result<Value, String> {
50    let n = to_f64(&args[0])?;
51    Ok(Value::Int(n.round() as i64))
52}
53
54pub fn builtin_min(args: &[Value]) -> Result<Value, String> {
55    match (&args[0], &args[1]) {
56        (Value::Int(a), Value::Int(b)) => Ok(Value::Int(*a.min(b))),
57        (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a.min(*b))),
58        (Value::Int(a), Value::Float(b)) => Ok(Value::Float((*a as f64).min(*b))),
59        (Value::Float(a), Value::Int(b)) => Ok(Value::Float(a.min(*b as f64))),
60        _ => Err("min expects numbers".to_string()),
61    }
62}
63
64pub fn builtin_max(args: &[Value]) -> Result<Value, String> {
65    match (&args[0], &args[1]) {
66        (Value::Int(a), Value::Int(b)) => Ok(Value::Int(*a.max(b))),
67        (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a.max(*b))),
68        (Value::Int(a), Value::Float(b)) => Ok(Value::Float((*a as f64).max(*b))),
69        (Value::Float(a), Value::Int(b)) => Ok(Value::Float(a.max(*b as f64))),
70        _ => Err("max expects numbers".to_string()),
71    }
72}