use crate::ast::{Type, Value};
use crate::error::NbclError;
use crate::registry::Registry;
pub(crate) fn register_builtin_functions(registry: &mut Registry) {
registry.add_native_fn("print", vec![Type::Any], Type::Null, |args| {
crate::print(format!("{}", args[0]));
Ok(Value::Null)
});
registry.add_native_fn("to_string", vec![Type::Any], Type::Str, |args| {
Ok(Value::Str(args[0].to_string()))
});
registry.add_native_fn("type_of", vec![Type::Any], Type::Str, |args| {
Ok(Value::Str(args[0].type_name().to_string()))
});
registry.add_native_fn("len", vec![Type::Any], Type::Int, |args| {
let length = match &args[0] {
Value::Str(s) => s.len() as i64,
Value::List(l) => l.len() as i64,
Value::Map(m) => m.len() as i64,
_ => {
return Err(NbclError::Runtime {
message: format!("len() not supported for type {}", args[0].type_name()),
hint: None,
span: None,
});
}
};
Ok(Value::Int(length))
});
registry.add_native_fn("assert", vec![Type::Bool, Type::Str], Type::Null, |args| {
let condition = match args[0] {
Value::Bool(b) => b,
_ => unreachable!(),
};
let msg = match &args[1] {
Value::Str(s) => s,
_ => unreachable!(),
};
if !condition {
return Err(NbclError::Runtime {
message: format!("assertion Failed: {}", msg),
hint: None,
span: None,
});
}
Ok(Value::Null)
});
}