2024-03-30 16:21:09 +00:00
|
|
|
use talc_lang::{exception::{throw, Exception, Result}, symbol::SYM_TYPE_ERROR, value::Value, Vm};
|
2024-02-23 19:54:34 +00:00
|
|
|
use talc_macros::native_func;
|
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
use crate::{unpack_args, unpack_varargs};
|
|
|
|
|
|
|
|
#[native_func(1..)]
|
2024-02-23 19:54:34 +00:00
|
|
|
pub fn throw(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
2024-02-27 05:18:43 +00:00
|
|
|
let ([_, ty], varargs) = unpack_varargs!(args);
|
|
|
|
let Value::Symbol(ty) = ty else {
|
|
|
|
throw!(*SYM_TYPE_ERROR, "exception type must be a symbol")
|
|
|
|
};
|
|
|
|
Err(match &*varargs {
|
|
|
|
[] | [Value::Nil]
|
|
|
|
=> Exception::new(ty),
|
|
|
|
[Value::Nil, data]
|
|
|
|
=> Exception::new_with_data(ty, data.clone()),
|
|
|
|
[Value::String(s)]
|
|
|
|
=> Exception::new_with_msg(ty, s.clone()),
|
|
|
|
[Value::String(s), data]
|
|
|
|
=> Exception::new_with_msg_data(ty, s.clone(), data.clone()),
|
|
|
|
[_] | [_,_] => throw!(*SYM_TYPE_ERROR, "wrong arguments for throw"),
|
|
|
|
[_,_,_,..] => throw!(*SYM_TYPE_ERROR, "too many arguments for throw"),
|
|
|
|
})
|
2024-02-23 19:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[native_func(1)]
|
|
|
|
pub fn rethrow(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
2024-02-27 05:18:43 +00:00
|
|
|
let [_, table] = unpack_args!(args);
|
|
|
|
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")
|
2024-02-23 19:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn load(vm: &mut Vm) {
|
2024-02-27 05:18:43 +00:00
|
|
|
vm.set_global_name("throw", throw().into());
|
|
|
|
vm.set_global_name("rethrow", rethrow().into());
|
2024-02-23 19:54:34 +00:00
|
|
|
}
|