talc/talc-std/src/exception.rs

50 lines
1.3 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,
2024-11-14 19:16:33 +00:00
vm::Vm,
2024-11-04 18:25:31 +00:00
};
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::String(s)] => {
Exception::new_with_msg(*ty, s.clone())
}
2024-11-12 20:40:51 +00:00
[] | [_] | [_, _] => {
2024-11-04 18:31:53 +00:00
throw!(*SYM_TYPE_ERROR, "wrong argument for throw")
}
2024-11-12 20:40:51 +00:00
[_, _, _, ..] => throw!(
2024-11-04 18:25:31 +00:00
*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
}