talc/talc-std/src/exception.rs

41 lines
1.2 KiB
Rust

use talc_lang::{symbol::SYM_TYPE_ERROR, exception::{throw, Exception, Result}, value::Value, Vm};
use talc_macros::native_func;
use crate::{unpack_args, unpack_varargs};
#[native_func(1..)]
pub fn throw(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
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"),
})
}
#[native_func(1)]
pub fn rethrow(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
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")
}
pub fn load(vm: &mut Vm) {
vm.set_global_name("throw", throw().into());
vm.set_global_name("rethrow", rethrow().into());
}