use crate::eval::{evaluate_expr, functions::{check_arity_len, EvalCtx}};
use crate::parser::ast::Expr;
use crate::types::{ErrorKind, Value};
pub fn error_type_fn(args: &[Expr], ctx: &mut EvalCtx<'_>) -> Value {
if check_arity_len(args.len(), 1, 1).is_some() {
return Value::Error(ErrorKind::NA);
}
let val = evaluate_expr(&args[0], ctx);
match val {
Value::Error(ErrorKind::Null) => Value::Number(1.0),
Value::Error(ErrorKind::DivByZero) => Value::Number(2.0),
Value::Error(ErrorKind::Value) => Value::Number(3.0),
Value::Error(ErrorKind::Ref) => Value::Number(4.0),
Value::Error(ErrorKind::Name) => Value::Number(5.0),
Value::Error(ErrorKind::Num) => Value::Number(6.0),
Value::Error(ErrorKind::NA) => Value::Number(7.0),
_ => Value::Error(ErrorKind::NA),
}
}
pub fn n_fn(args: &[Expr], ctx: &mut EvalCtx<'_>) -> Value {
if check_arity_len(args.len(), 1, 1).is_some() {
return Value::Error(ErrorKind::NA);
}
let val = evaluate_expr(&args[0], ctx);
match val {
Value::Number(n) | Value::Date(n) => Value::Number(n),
Value::Bool(b) => Value::Number(if b { 1.0 } else { 0.0 }),
Value::Empty | Value::Text(_) | Value::Array(_) => Value::Number(0.0),
Value::Error(_) => val,
}
}
pub fn type_fn(args: &[Expr], ctx: &mut EvalCtx<'_>) -> Value {
if let Some(err) = check_arity_len(args.len(), 1, 1) {
return err;
}
let val = evaluate_expr(&args[0], ctx);
let code = match val {
Value::Number(_) | Value::Date(_) => 1.0,
Value::Text(_) => 2.0,
Value::Bool(_) => 4.0,
Value::Error(_) => 16.0,
Value::Array(_) => 64.0,
Value::Empty => 1.0, };
Value::Number(code)
}