use std::rc::Rc;
use crate::{Environment, RuntimeError, RuntimeErrorKind};
use super::{CatchType, Expression, eval::State};
use common_macros::b_tree_map;
pub fn catch_error(
e: RuntimeError,
typ: &CatchType,
deeling: &Option<Rc<Expression>>,
state: &mut State,
env: &mut Environment,
depth: usize,
) -> Result<Expression, RuntimeError> {
match typ {
CatchType::OnError => match deeling {
Some(deel) => match deel.as_ref() {
Expression::Symbol(..) | Expression::Lambda(..) | Expression::Function(..) => {
deel.as_ref()
.apply(vec![Expression::from(b_tree_map! {
String::from("code") => Expression::from(e.code()),
String::from("msg") => Expression::String(e.kind.to_string()),
String::from("expr") => Expression::String(e.context.to_string()),
String::from("ast") => Expression::String(format!("{:?}",e.context)),
String::from("type") => Expression::String(e.context.type_name().to_string()),
String::from("depth") => Expression::Integer(e.depth as i64),
})])
.eval_mut(state, env, depth + 1)
}
_ => deel.as_ref().eval_mut(state, env, depth + 1),
},
_ => Ok(Expression::None),
},
CatchType::Ignore => Ok(Expression::None),
CatchType::ToBoolean => Ok(Expression::Boolean(false)),
CatchType::OnSuccess => Err(e), CatchType::OnEmpty => Err(e), CatchType::PrintStd => {
println!("{e:?}");
Ok(Expression::None)
}
CatchType::PrintErr => {
eprintln!("\x1b[38;5;9m{e:?}\x1b[0m");
Ok(Expression::None)
}
CatchType::PrintOver => Ok(Expression::from(b_tree_map! {
String::from("code") => Expression::from(e.code()),
String::from("msg") => Expression::String(e.kind.to_string()),
String::from("expr") => Expression::String(e.context.to_string()),
String::from("ast") => Expression::String(format!("{:?}",e.context)),
String::from("type") => Expression::String(e.context.type_name().to_string()),
String::from("depth") => Expression::Integer(e.depth as i64),
})),
CatchType::TerminateOnErr | CatchType::TerminateOnEmpty => Err(RuntimeError::new(
RuntimeErrorKind::Terminated,
e.context,
e.depth,
)),
}
}