use std::sync::Arc; use rust_decimal::{Decimal, MathematicalOps}; use crate::interpreter::{Interpreter, Value}; use super::{NIL, delsh_bool}; pub fn is_number(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let arg = interpreter.eval(args[0].clone()); delsh_bool(arg.number().is_some()) } pub fn is_int(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let arg = interpreter.eval(args[0].clone()); delsh_bool(arg.number().is_some_and(|num| num.is_integer())) } pub fn is_equal(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let a = interpreter.eval(args[0].clone()); let b = interpreter.eval(args[1].clone()); delsh_bool(a == b) } pub fn is_less(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let a = *interpreter .eval(args[0].clone()) .number() .expect("two numbers"); let b = *interpreter .eval(args[1].clone()) .number() .expect("two numbers"); delsh_bool(a < b) } pub fn is_greater(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let a = *interpreter .eval(args[0].clone()) .number() .expect("two numbers"); let b = *interpreter .eval(args[1].clone()) .number() .expect("two numbers"); delsh_bool(a > b) } pub fn is_zero(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let arg = interpreter.eval(args[0].clone()); delsh_bool(arg.number().is_some_and(|num| *num == Decimal::ZERO)) } pub fn is_one(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let arg = interpreter.eval(args[0].clone()); delsh_bool(arg.number().is_some_and(|num| *num == Decimal::ONE)) } pub fn is_negative(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let arg = interpreter.eval(args[0].clone()); delsh_bool(arg.number().is_some_and(|num| num.is_sign_negative())) } pub fn plus(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let mut total = Decimal::ZERO; for arg in args { let arg = interpreter.eval(arg.clone()); match &*arg { Value::Number(num) => total += num, _ => panic!("Expected a number"), } } Arc::new(Value::Number(total)) } pub fn minus(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { if args.len() == 1 { let Value::Number(arg) = &*interpreter.eval(args[0].clone()) else { panic!("expected a number") }; Arc::new(Value::Number(-arg)) } else if args.len() == 2 { let Value::Number(a) = &*interpreter.eval(args[0].clone()) else { panic!("expected a number") }; let Value::Number(b) = &*interpreter.eval(args[1].clone()) else { panic!("expected a number") }; return Arc::new(Value::Number(a - b)); } else { panic!("expected one or two arguments") } } pub fn negate(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let Value::Number(arg) = &*interpreter.eval(args[0].clone()) else { panic!("expected a number") }; Arc::new(Value::Number(-arg)) } pub fn times(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let mut total = Decimal::ONE; for arg in args { let Value::Number(arg) = &*interpreter.eval(arg.clone()) else { panic!("expected a number") }; total *= arg; } Arc::new(Value::Number(total)) } pub fn divide(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let Value::Number(arg1) = &*interpreter.eval(args[0].clone()) else { panic!("expected a number") }; let Value::Number(arg2) = &*interpreter.eval(args[1].clone()) else { panic!("expected a number") }; Arc::new(Value::Number(arg1 / arg2)) } pub fn quotient(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let numerator = interpreter.eval(args[0].clone()); let numerator = numerator.number().expect("two numbers"); let denominator = interpreter.eval(args[1].clone()); let denominator = denominator.number().expect("two numbers"); Arc::new(Value::Number((numerator / denominator).floor())) } pub fn remainder(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let Value::Number(arg1) = &*interpreter.eval(args[0].clone()) else { panic!("expected a number") }; let Value::Number(arg2) = &*interpreter.eval(args[1].clone()) else { panic!("expected a number") }; Arc::new(Value::Number(arg1 % arg2)) } pub fn add1(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { Arc::new(Value::Number( interpreter .eval(args[0].clone()) .number() .expect("a number") + Decimal::ONE, )) } pub fn sub1(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { Arc::new(Value::Number( interpreter .eval(args[0].clone()) .number() .expect("a number") - Decimal::ONE, )) } pub fn max(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let max = interpreter.eval(args[0].clone()); let mut max = *max.number().expect("all args to be numbers"); for arg in &args[1..] { let arg = interpreter.eval(arg.clone()); let arg = arg.number().expect("all args to be numbers"); max = max.max(*arg); } Arc::new(Value::Number(max)) } pub fn min(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let min = interpreter.eval(args[0].clone()); let mut min = *min.number().expect("all args to be numbers"); for arg in &args[1..] { let arg = interpreter.eval(arg.clone()); let arg = arg.number().expect("all args to be numbers"); min = min.min(*arg); } Arc::new(Value::Number(min)) } pub fn recip(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let number = interpreter.eval(args[0].clone()); let number = number.number().expect("a number"); Arc::new(Value::Number(Decimal::ONE / number)) } pub fn expt(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let x = *interpreter .eval(args[0].clone()) .number() .expect("two numbers"); let y = *interpreter .eval(args[0].clone()) .number() .expect("two numbers"); Arc::new(Value::Number(x.powd(y))) } pub fn sqrt(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { let Value::Number(arg) = &*interpreter.eval(args[0].clone()) else { panic!("expected a number") }; let Some(sqrt) = arg.sqrt() else { return NIL.clone(); }; Arc::new(Value::Number(sqrt)) }