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<Value>]) -> Arc<Value> {
let arg = interpreter.eval(args[0].clone());
delsh_bool(arg.number().is_some())
}
pub fn is_int(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
Arc::new(Value::Number(
interpreter
.eval(args[0].clone())
.number()
.expect("a number")
+ Decimal::ONE,
))
}
pub fn sub1(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
Arc::new(Value::Number(
interpreter
.eval(args[0].clone())
.number()
.expect("a number")
- Decimal::ONE,
))
}
pub fn max(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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<Value>]) -> Arc<Value> {
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))
}
|