roan_engine/interpreter/
errors.rs

1use crate::{context::Context, module::Module, value::Value, vm::VM};
2use anyhow::Result;
3use roan_ast::{Throw, Try};
4use roan_error::error::RoanError;
5use tracing::debug;
6
7impl Module {
8    /// Interpret TryCatch expression.
9    ///
10    /// # Arguments
11    /// * `try_catch` - TryCatch expression to interpret.
12    /// * `ctx` - The context in which to interpret the TryCatch expression.
13    ///
14    /// # Returns
15    /// The result of the TryCatch expression.
16    pub fn interpret_try(&mut self, try_stmt: Try, ctx: &mut Context, vm: &mut VM) -> Result<()> {
17        debug!("Interpreting try");
18
19        let try_result = self.execute_block(try_stmt.try_block.clone(), ctx, vm);
20
21        match try_result {
22            Ok(_) => return Ok(()),
23            Err(e) => match e.downcast_ref::<RoanError>() {
24                Some(RoanError::Throw(msg, _)) => {
25                    self.enter_scope();
26
27                    let var_name = try_stmt.error_ident.literal();
28                    self.declare_variable(var_name, Value::String(msg.clone()));
29                    let result = self.execute_block(try_stmt.catch_block, ctx, vm);
30                    self.exit_scope();
31
32                    result?
33                }
34                _ => return Err(e),
35            },
36        }
37
38        Ok(())
39    }
40
41    /// Interpret a throw statement.
42    ///
43    /// # Arguments
44    /// * `throw_stmt` - The throw statement to interpret.
45    /// * `ctx` - The context in which to interpret the statement.
46    ///
47    /// # Returns
48    /// The result of the throw statement.
49    pub fn interpret_throw(&mut self, throw: Throw, ctx: &mut Context, vm: &mut VM) -> Result<()> {
50        debug!("Interpreting throw");
51
52        self.interpret_expr(&throw.value, ctx, vm)?;
53        let val = vm.pop().unwrap();
54
55        return Err(RoanError::Throw(val.to_string(), Vec::from(vm.frames())).into());
56    }
57}