robinpath 0.2.0

RobinPath - A lightweight, fast scripting language interpreter for automation and data processing
Documentation
use crate::executor::Environment;
use crate::value::Value;

pub fn register(env: &mut Environment) {
    env.register_builtin("math.add", |args, _| {
        let sum: f64 = args.iter().map(|v| v.to_number()).sum();
        Ok(Value::Number(sum))
    });

    env.register_builtin("math.subtract", |args, _| {
        if args.is_empty() {
            return Ok(Value::Number(0.0));
        }
        let mut result = args[0].to_number();
        for arg in &args[1..] {
            result -= arg.to_number();
        }
        Ok(Value::Number(result))
    });

    env.register_builtin("math.multiply", |args, _| {
        let product: f64 = args.iter().map(|v| v.to_number()).product();
        Ok(Value::Number(product))
    });

    env.register_builtin("math.divide", |args, _| {
        if args.len() < 2 {
            return Ok(Value::Number(f64::NAN));
        }
        let a = args[0].to_number();
        let b = args[1].to_number();
        if b == 0.0 {
            Ok(Value::Number(f64::INFINITY))
        } else {
            Ok(Value::Number(a / b))
        }
    });

    env.register_builtin("math.modulo", |args, _| {
        if args.len() < 2 {
            return Ok(Value::Number(f64::NAN));
        }
        Ok(Value::Number(args[0].to_number() % args[1].to_number()))
    });

    env.register_builtin("math.abs", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().abs()),
        ))
    });

    env.register_builtin("math.round", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().round()),
        ))
    });

    env.register_builtin("math.floor", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().floor()),
        ))
    });

    env.register_builtin("math.ceil", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().ceil()),
        ))
    });

    env.register_builtin("math.min", |args, _| {
        let mut min = f64::INFINITY;
        for arg in args {
            let n = arg.to_number();
            if n < min {
                min = n;
            }
        }
        Ok(Value::Number(min))
    });

    env.register_builtin("math.max", |args, _| {
        let mut max = f64::NEG_INFINITY;
        for arg in args {
            let n = arg.to_number();
            if n > max {
                max = n;
            }
        }
        Ok(Value::Number(max))
    });

    env.register_builtin("math.pow", |args, _| {
        if args.len() < 2 {
            return Ok(Value::Number(f64::NAN));
        }
        Ok(Value::Number(
            args[0].to_number().powf(args[1].to_number()),
        ))
    });

    env.register_builtin("math.sqrt", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().sqrt()),
        ))
    });

    env.register_builtin("math.sin", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().sin()),
        ))
    });

    env.register_builtin("math.cos", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().cos()),
        ))
    });

    env.register_builtin("math.tan", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().tan()),
        ))
    });

    env.register_builtin("math.pi", |_args, _| {
        Ok(Value::Number(std::f64::consts::PI))
    });

    env.register_builtin("math.e", |_args, _| {
        Ok(Value::Number(std::f64::consts::E))
    });

    env.register_builtin("math.power", |args, _| {
        if args.len() < 2 {
            return Ok(Value::Number(f64::NAN));
        }
        Ok(Value::Number(
            args[0].to_number().powf(args[1].to_number()),
        ))
    });

    env.register_builtin("math.log", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().ln()),
        ))
    });

    env.register_builtin("math.log10", |args, _| {
        Ok(Value::Number(
            args.first().map_or(0.0, |v| v.to_number().log10()),
        ))
    });

    // Shorthand aliases (available when `use math`)
    env.register_builtin("add", |args, _| {
        let sum: f64 = args.iter().map(|v| v.to_number()).sum();
        Ok(Value::Number(sum))
    });

    env.register_builtin("subtract", |args, _| {
        if args.is_empty() {
            return Ok(Value::Number(0.0));
        }
        let mut result = args[0].to_number();
        for arg in &args[1..] {
            result -= arg.to_number();
        }
        Ok(Value::Number(result))
    });

    env.register_builtin("multiply", |args, _| {
        let product: f64 = args.iter().map(|v| v.to_number()).product();
        Ok(Value::Number(product))
    });

    env.register_builtin("divide", |args, _| {
        if args.len() < 2 {
            return Ok(Value::Number(f64::NAN));
        }
        let a = args[0].to_number();
        let b = args[1].to_number();
        if b == 0.0 {
            Ok(Value::Number(f64::INFINITY))
        } else {
            Ok(Value::Number(a / b))
        }
    });
}