diff --git a/src/engine.rs b/src/engine.rs index de065023..ac747dfb 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1714,7 +1714,7 @@ impl Engine { // Statement block Expr::Stmt(x, _) => { - self.eval_statements(scope, mods, state, lib, this_ptr, x.as_ref(), level) + self.eval_stmt_block(scope, mods, state, lib, this_ptr, x.as_ref(), level) } // lhs[idx_expr] @@ -1848,8 +1848,8 @@ impl Engine { .map_err(|err| err.fill_position(expr.position())) } - /// Evaluate a list of statements. - pub(crate) fn eval_statements<'a>( + /// Evaluate a statements block. + pub(crate) fn eval_stmt_block<'a>( &self, scope: &mut Scope, mods: &mut Imports, @@ -1859,6 +1859,7 @@ impl Engine { statements: impl IntoIterator, level: usize, ) -> Result> { + let prev_always_search = state.always_search; let prev_scope_len = scope.len(); let prev_mods_len = mods.len(); state.scope_level += 1; @@ -1873,16 +1874,15 @@ impl Engine { mods.truncate(prev_mods_len); state.scope_level -= 1; - // The impact of an eval statement goes away at the end of a block + // The impact of new local variables goes away at the end of a block // because any new variables introduced will go out of scope - state.always_search = false; + state.always_search = prev_always_search; result } /// Evaluate a statement. /// - /// /// # Safety /// /// This method uses some unsafe code, mainly for avoiding cloning of local variable names via @@ -2062,7 +2062,7 @@ impl Engine { // Block scope Stmt::Block(statements, _) => { - self.eval_statements(scope, mods, state, lib, this_ptr, statements, level) + self.eval_stmt_block(scope, mods, state, lib, this_ptr, statements, level) } // If statement diff --git a/tests/eval.rs b/tests/eval.rs index 28618fc5..7732bd25 100644 --- a/tests/eval.rs +++ b/tests/eval.rs @@ -8,7 +8,7 @@ fn test_eval() -> Result<(), Box> { engine.eval::( r#" eval("40 + 2") - "# + "# )?, 42 ); @@ -16,6 +16,33 @@ fn test_eval() -> Result<(), Box> { Ok(()) } +#[test] +fn test_eval_blocks() -> Result<(), Box> { + let engine = Engine::new(); + + assert_eq!( + engine.eval::( + r#" + let x = 999; + + eval("let x = x + 123"); + + let y = if x > 0 { + eval("let x = 42"); + x + } else { + 0 + }; + + x + y + "# + )?, + 1164 + ); + + Ok(()) +} + #[test] #[cfg(not(feature = "no_function"))] fn test_eval_function() -> Result<(), Box> {