@@ -79,12 +79,12 @@ pub fn execute(stmt: Statement, env: &Environment<Expression>) -> Result<Computa
7979
8080 match value {
8181 Expression :: CTrue => match * stmt_then {
82- Statement :: Block ( stmts) => execute_block ( stmts, & new_env) ,
82+ Statement :: Block ( stmts) => execute_if_block ( stmts, & new_env) ,
8383 _ => execute ( * stmt_then, & new_env) ,
8484 } ,
8585 Expression :: CFalse => match stmt_else {
8686 Some ( else_stmt) => match * else_stmt {
87- Statement :: Block ( stmts) => execute_block ( stmts, & new_env) ,
87+ Statement :: Block ( stmts) => execute_if_block ( stmts, & new_env) ,
8888 _ => execute ( * else_stmt, & new_env) ,
8989 } ,
9090 None => Ok ( Computation :: Continue ( new_env) ) ,
@@ -94,9 +94,14 @@ pub fn execute(stmt: Statement, env: &Environment<Expression>) -> Result<Computa
9494 }
9595
9696 Statement :: Block ( stmts) => {
97- new_env. push ( ) ;
97+ // new_env.push(); <- removing push()
9898 let result = execute_block ( stmts, & new_env) ;
99- new_env. pop ( ) ;
99+ // new_env.pop(); <- removing pop()
100+ // `result` already encapsulates the updated environment,
101+ // So popping would have no effect on the final outcome
102+ // Therefore, push and pop operations will be handled in function 'execute_block'
103+ // A new function `execute_if_block` will be created specifically for executing blocks
104+ // without performing push/pop operations
100105 result
101106 }
102107
@@ -201,13 +206,38 @@ pub fn execute_block(
201206 env : & Environment < Expression > ,
202207) -> Result < Computation , String > {
203208 let mut current_env = env. clone ( ) ;
209+ current_env. push ( ) ;
204210
205211 for stmt in stmts {
206212 match execute ( stmt, & current_env) ? {
207213 Computation :: Continue ( new_env) => current_env = new_env,
208- Computation :: Return ( expr, env) => return Ok ( Computation :: Return ( expr, env) ) ,
209- Computation :: PropagateError ( expr, env) => {
210- return Ok ( Computation :: PropagateError ( expr, env) )
214+ Computation :: Return ( expr, mut new_env) => {
215+ new_env. pop ( ) ; //expr has already been evaluated, so it is safe to pop here
216+ return Ok ( Computation :: Return ( expr, new_env) ) ;
217+ }
218+ Computation :: PropagateError ( expr, new_env) => {
219+ return Ok ( Computation :: PropagateError ( expr, new_env) )
220+ }
221+ }
222+ }
223+ current_env. pop ( ) ;
224+ Ok ( Computation :: Continue ( current_env) )
225+ }
226+
227+ pub fn execute_if_block (
228+ stmts : Vec < Statement > ,
229+ env : & Environment < Expression > ,
230+ ) -> Result < Computation , String > {
231+ let mut current_env = env. clone ( ) ;
232+
233+ for stmt in stmts {
234+ match execute ( stmt, & current_env) ? {
235+ Computation :: Continue ( new_env) => current_env = new_env,
236+ Computation :: Return ( expr, new_env) => {
237+ return Ok ( Computation :: Return ( expr, new_env) ) ;
238+ }
239+ Computation :: PropagateError ( expr, new_env) => {
240+ return Ok ( Computation :: PropagateError ( expr, new_env) )
211241 }
212242 }
213243 }
0 commit comments