32 lines
1.1 KiB
Rust
32 lines
1.1 KiB
Rust
|
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<Value>) -> Result<Value> {
|
||
|
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<Value>) -> Result<Value> {
|
||
|
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());
|
||
|
}
|