49 lines
1.3 KiB
Rust
49 lines
1.3 KiB
Rust
use talc_lang::{
|
|
exception::{throw, Exception, Result},
|
|
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
|
value::Value,
|
|
vm::Vm,
|
|
};
|
|
use talc_macros::native_func;
|
|
|
|
use crate::unpack_args;
|
|
|
|
#[native_func(1)]
|
|
pub fn throw(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
|
|
let [_, arg] = unpack_args!(args);
|
|
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),
|
|
[Value::Symbol(ty), Value::String(s)] => {
|
|
Exception::new_with_msg(*ty, s.clone())
|
|
}
|
|
[] | [_] | [_, _] => {
|
|
throw!(*SYM_TYPE_ERROR, "wrong argument for throw")
|
|
}
|
|
[_, _, _, ..] => throw!(
|
|
*SYM_VALUE_ERROR,
|
|
"too many elements in list argument for throw"
|
|
),
|
|
},
|
|
_ => throw!(*SYM_TYPE_ERROR, "throw expected symbol or list"),
|
|
};
|
|
Err(exc)
|
|
}
|
|
|
|
#[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_VALUE_ERROR, "argument not a valid exception")
|
|
}
|
|
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());
|
|
}
|