use crate::evaluator::RuntimeError;
use crate::value::Value;
pub fn type_of(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
let type_name = match &args[0] {
Value::Number(_) => "Number",
Value::Fraction(_) => "Fraction",
Value::String(_) => "String",
Value::Boolean(_) => "Boolean",
Value::Null => "Null",
Value::Array(_) => "Array",
Value::Dict(_) => "Dict",
Value::Function { .. } => "Function",
Value::Generator { .. } => "Generator",
Value::Lazy { .. } => "Lazy",
Value::BuiltIn { .. } => "BuiltIn",
};
Ok(Value::String(type_name.to_string()))
}
pub fn to_string(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
Ok(Value::String(args[0].to_string()))
}
pub fn to_number(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
match &args[0] {
Value::Number(n) => Ok(Value::Number(*n)),
Value::String(s) => {
s.parse::<f64>()
.map(Value::Number)
.map_err(|_| RuntimeError::TypeErrorDetailed {
expected: "parseable string".to_string(),
got: format!("\"{}\"", s),
})
}
Value::Boolean(b) => Ok(Value::Number(if *b { 1.0 } else { 0.0 })),
Value::Null => Ok(Value::Number(0.0)),
other => Err(RuntimeError::TypeErrorDetailed {
expected: "Number, String, Boolean or Null".to_string(),
got: format!("{:?}", other),
}),
}
}
pub fn len(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
match &args[0] {
Value::String(s) => Ok(Value::Number(s.len() as f64)),
Value::Array(arr) => Ok(Value::Number(arr.len() as f64)),
Value::Dict(dict) => Ok(Value::Number(dict.len() as f64)),
other => Err(RuntimeError::TypeErrorDetailed {
expected: "String, Array or Dict".to_string(),
got: format!("{:?}", other),
}),
}
}
pub fn clone(args: &[Value]) -> Result<Value, RuntimeError> {
if args.len() != 1 {
return Err(RuntimeError::WrongArity {
expected: 1,
got: args.len(),
});
}
Ok(args[0].clone())
}