use crate::{
builtins::{
function::NativeFunctionData,
value::{from_value, to_value, ResultValue, Value, ValueData},
},
exec::Interpreter,
};
use rand::random;
use std::f64;
pub fn abs(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.abs()
}))
}
pub fn acos(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.acos()
}))
}
pub fn asin(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.asin()
}))
}
pub fn atan(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.atan()
}))
}
pub fn atan2(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.atan2(args.get(1).expect("Could not get argument").to_num())
}))
}
pub fn cbrt(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.cbrt()
}))
}
pub fn ceil(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.ceil()
}))
}
pub fn cos(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.cos()
}))
}
pub fn exp(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.exp()
}))
}
pub fn floor(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.floor()
}))
}
pub fn log(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.log(f64::consts::E)
}))
}
pub fn max(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let mut max = f64::NEG_INFINITY;
for arg in args {
let num = arg.to_num();
max = max.max(num);
}
Ok(to_value(max))
}
pub fn min(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let mut max = f64::INFINITY;
for arg in args {
let num = arg.to_num();
max = max.min(num);
}
Ok(to_value(max))
}
pub fn pow(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.len() >= 2 {
let num: f64 = from_value(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64");
let power: f64 = from_value(args.get(1).expect("Could not get argument").clone())
.expect("Could not convert argument to f64");
num.powf(power)
} else {
f64::NAN
}))
}
pub fn _random(_: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(random::<f64>()))
}
pub fn round(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.round()
}))
}
pub fn sin(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.sin()
}))
}
pub fn sqrt(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.sqrt()
}))
}
pub fn tan(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(to_value(if args.is_empty() {
f64::NAN
} else {
from_value::<f64>(args.get(0).expect("Could not get argument").clone())
.expect("Could not convert argument to f64")
.tan()
}))
}
pub fn create_constructor(global: &Value) -> Value {
let math = ValueData::new_obj(Some(global));
math.set_field_slice("E", to_value(f64::consts::E));
math.set_field_slice("LN2", to_value(f64::consts::LN_2));
math.set_field_slice("LN10", to_value(f64::consts::LN_10));
math.set_field_slice("LOG2E", to_value(f64::consts::LOG2_E));
math.set_field_slice("LOG10E", to_value(f64::consts::LOG10_E));
math.set_field_slice("SQRT1_2", to_value(0.5_f64.sqrt()));
math.set_field_slice("SQRT2", to_value(f64::consts::SQRT_2));
math.set_field_slice("PI", to_value(f64::consts::PI));
make_builtin_fn!(abs, named "abs", with length 1, of math);
make_builtin_fn!(acos, named "acos", with length 1, of math);
make_builtin_fn!(asin, named "asin", with length 1, of math);
make_builtin_fn!(atan, named "atan", with length 1, of math);
make_builtin_fn!(atan2, named "atan2", with length 2, of math);
make_builtin_fn!(cbrt, named "cbrt", with length 1, of math);
make_builtin_fn!(ceil, named "ceil", with length 1, of math);
make_builtin_fn!(cos, named "cos", with length 1, of math);
make_builtin_fn!(exp, named "exp", with length 1, of math);
make_builtin_fn!(floor, named "floor", with length 1, of math);
make_builtin_fn!(log, named "log", with length 1, of math);
make_builtin_fn!(max, named "max", with length 2, of math);
make_builtin_fn!(min, named "min", with length 2, of math);
make_builtin_fn!(pow, named "pow", with length 2, of math);
make_builtin_fn!(_random, named "random", of math);
make_builtin_fn!(round, named "round", with length 1, of math);
make_builtin_fn!(sin, named "sin", with length 1, of math);
make_builtin_fn!(sqrt, named "sqrt", with length 1, of math);
make_builtin_fn!(tan, named "tan", with length 1, of math);
math
}