talc/talc-std/src/exception.rs

56 lines
1.5 KiB
Rust
Raw Normal View History

2024-11-04 18:25:31 +00:00
use talc_lang::{
exception::{throw, Exception, Result},
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
value::Value,
Vm,
};
2024-02-23 19:54:34 +00:00
use talc_macros::native_func;
use crate::unpack_args;
2024-02-27 05:18:43 +00:00
#[native_func(1)]
2024-02-23 19:54:34 +00:00
pub fn throw(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
let [_, arg] = unpack_args!(args);
2024-11-04 18:25:31 +00:00
let exc = match arg {
Value::Symbol(ty) => Exception::new(ty),
Value::List(l) => match l.borrow().as_slice() {
[Value::Symbol(ty)] | [Value::Symbol(ty), Value::Nil] => Exception::new(*ty),
2024-11-04 18:31:53 +00:00
[Value::Symbol(ty), Value::Nil, data] => {
Exception::new_with_data(*ty, data.clone())
}
[Value::Symbol(ty), Value::String(s)] => {
Exception::new_with_msg(*ty, s.clone())
}
2024-11-04 18:25:31 +00:00
[Value::Symbol(ty), Value::String(s), data] => {
Exception::new_with_msg_data(*ty, s.clone(), data.clone())
}
2024-11-04 18:31:53 +00:00
[] | [_] | [_, _] | [_, _, _] => {
throw!(*SYM_TYPE_ERROR, "wrong argument for throw")
}
2024-11-04 18:25:31 +00:00
[_, _, _, _, ..] => throw!(
*SYM_VALUE_ERROR,
"too many elements in list argument for throw"
),
},
_ => throw!(*SYM_TYPE_ERROR, "throw expected symbol or list"),
};
Err(exc)
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)
}
2024-11-04 18:25:31 +00:00
throw!(*SYM_VALUE_ERROR, "argument not a valid exception")
2024-02-27 05:18:43 +00:00
}
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
}