use talc_lang::{symbol::SYM_TYPE_ERROR, value::{exception::{throw, Exception, Result}, Value}, Vm}; use talc_macros::native_func; #[native_func(2)] pub fn throw(_: &mut Vm, args: Vec) -> Result { let [_, ty, msg] = args.try_into().expect("bypassed arity check"); let Value::Symbol(ty) = ty else { throw!(*SYM_TYPE_ERROR, "exception type must be a symbol") }; match msg { Value::String(msg) => Err(Exception::new_with_msg(ty, msg)), Value::Nil => Err(Exception::new(ty)), _ => throw!(*SYM_TYPE_ERROR, "exception message must be a string") } } #[native_func(1)] pub fn rethrow(_: &mut Vm, args: Vec) -> Result { let [_, table] = args.try_into().expect("bypassed arity check"); if let Value::Table(table) = table { if let Some(e) = Exception::from_table(&table) { return Err(e) } } throw!(*SYM_TYPE_ERROR, "argument not a valid exception") } pub fn load(vm: &mut Vm) { vm.set_global_name("throw", throw().into()); vm.set_global_name("rethrow", rethrow().into()); }