fn eval_block_expression(
        &mut self,
        block: &BlockExpression,
        with_premade_env: Option<Rc<RefCell<Environment>>>,
    ) -> EvalResult<Rc<Object>> {
        // Open new block scope
        let outer_env = Rc::clone(&self.env);
        let inner_env = match with_premade_env {
            Some(env) => env,
            None => Rc::new(RefCell::new(Environment::new_enclosed(Rc::clone(
                &self.env,
            )))),
        };
        self.env = inner_env;

        let mut result = Rc::new(Object::Nil);

        for stmt in &block.statements {
            let val = self.eval_statement(stmt)?;

            match val.as_ref() {
                // If a return value is found, immediately return and stop evaluating statements
                // Don't unwrap the return value, we might be in a nested block which also needs to return
                Object::ReturnValue(_) => return Ok(val),
                _ => result = val,
            }
        }

        // Exit block scope
        self.env = outer_env;

        Ok(result)
    }
// Similar to eval (for programs) but doesn't unwrap return values
Similar to eval (for programs) but doesn't unwrap return values
Similar to eval ( for programs ) but doesn ' t unwrap return values
fn eval_block_expression(
        &mut self,
        block: &BlockExpression,
        with_premade_env: Option<Rc<RefCell<Environment>>>,
    ) -> EvalResult<Rc<Object>> {
        // Open new block scope
        let outer_env = Rc::clone(&self.env);
        let inner_env = match with_premade_env {
            Some(env) => env,
            None => Rc::new(RefCell::new(Environment::new_enclosed(Rc::clone(
                &self.env,
            )))),
        };
        self.env = inner_env;
        let mut result = Rc::new(Object::Nil);
        for stmt in &block.statements {
            let val = self.eval_statement(stmt)?;
            match val.as_ref() {
                // If a return value is found, immediately return and stop evaluating statements
                // Don't unwrap the return value, we might be in a nested block which also needs to return
                Object::ReturnValue(_) => return Ok(val),
                _ => result = val,
            }
        }
        // Exit block scope
        self.env = outer_env;
        Ok(result)
    }
fn eval_block_expression ( & mut self , block : & BlockExpression , with_premade_env : Option < Rc < RefCell < Environment > > > , ) -> EvalResult < Rc < Object > > { // Open new block scope let outer_env = Rc :: clone ( & self . env ) ; let inner_env = match with_premade_env { Some ( env ) => env , None => Rc :: new ( RefCell :: new ( Environment :: new_enclosed ( Rc :: clone ( & self . env , ) ) ) ) , } ; self . env = inner_env ; let mut result = Rc :: new ( Object :: Nil ) ; for stmt in & block . statements { let val = self . eval_statement ( stmt ) ? ; match val . as_ref ( ) { // If a return value is found, immediately return and stop evaluating statements // Don't unwrap the return value, we might be in a nested block which also needs to return Object :: ReturnValue ( _ ) => return Ok ( val ) , _ => result = val , } } // Exit block scope self . env = outer_env ; Ok ( result ) }
Similar to eval (for programs) but doesn't unwrap return values
Similar to eval ( for programs ) but doesn ' t unwrap return values
&mut self
block
&BlockExpression
with_premade_env
Option<Rc<RefCell<Environment>>>