@@ -248,7 +248,25 @@ pub fn execute(stmt: Statement, env: &Environment<Expression>) -> Result<Computa
248248 return Ok ( Computation :: PropagateError ( expr, new_env) )
249249 }
250250 } ;
251- new_env. map_variable ( name, true , value) ;
251+ // Respect existing mutability; if variable exists and is immutable, propagate error
252+ match new_env. lookup ( & name) {
253+ Some ( ( is_mut, _) ) => {
254+ if !is_mut {
255+ return Ok ( Computation :: PropagateError (
256+ Expression :: CString ( format ! (
257+ "Cannot assign to immutable variable '{}'" ,
258+ name
259+ ) ) ,
260+ new_env,
261+ ) ) ;
262+ }
263+ let _ = new_env. update_existing_variable ( & name, value) ;
264+ }
265+ None => {
266+ // If not previously declared, create as mutable (back-compat with tests)
267+ new_env. map_variable ( name, true , value) ;
268+ }
269+ }
252270 Ok ( Computation :: Continue ( new_env) )
253271 }
254272
@@ -316,18 +334,68 @@ pub fn execute(stmt: Statement, env: &Environment<Expression>) -> Result<Computa
316334 }
317335 }
318336
319- Statement :: For ( var, list , stmt) => {
320- let values = match eval ( * list . clone ( ) , & new_env) ? {
337+ Statement :: For ( var, expr , stmt) => {
338+ let coll = match eval ( * expr . clone ( ) , & new_env) ? {
321339 ExpressionResult :: Value ( expr) => expr,
322340 ExpressionResult :: Propagate ( expr) => {
323341 return Ok ( Computation :: PropagateError ( expr, new_env) )
324342 }
325343 } ;
326344
327- match values {
328- Expression :: ListValue ( expressions) => {
329- for exp in expressions {
330- new_env. map_variable ( var. clone ( ) , false , exp) ;
345+ match coll {
346+ // List of values
347+ Expression :: ListValue ( items) => {
348+ for item in items {
349+ // Bind loop variable in a transient manner: shadow during iteration
350+ // Save previous binding (if any)
351+ let prev = new_env. lookup ( & var. clone ( ) ) ;
352+ new_env. map_variable ( var. clone ( ) , false , item) ;
353+ match execute ( * stmt. clone ( ) , & new_env) ? {
354+ Computation :: Continue ( env) => new_env = env,
355+ Computation :: Return ( expr, env) => {
356+ return Ok ( Computation :: Return ( expr, env) )
357+ }
358+ Computation :: PropagateError ( expr, env) => {
359+ return Ok ( Computation :: PropagateError ( expr, env) )
360+ }
361+ }
362+ // Restore previous binding after each iteration
363+ let _ = new_env. remove_variable ( & var. clone ( ) ) ;
364+ if let Some ( ( was_mut, old_val) ) = prev {
365+ new_env. map_variable ( var. clone ( ) , was_mut, old_val) ;
366+ }
367+ }
368+ Ok ( Computation :: Continue ( new_env) )
369+ }
370+
371+ // String - itera sobre caracteres
372+ Expression :: CString ( s) => {
373+ for ch in s. chars ( ) {
374+ let char_value = Expression :: CString ( ch. to_string ( ) ) ;
375+ let prev = new_env. lookup ( & var. clone ( ) ) ;
376+ new_env. map_variable ( var. clone ( ) , false , char_value) ;
377+ match execute ( * stmt. clone ( ) , & new_env) ? {
378+ Computation :: Continue ( env) => new_env = env,
379+ Computation :: Return ( expr, env) => {
380+ return Ok ( Computation :: Return ( expr, env) )
381+ }
382+ Computation :: PropagateError ( expr, env) => {
383+ return Ok ( Computation :: PropagateError ( expr, env) )
384+ }
385+ }
386+ let _ = new_env. remove_variable ( & var. clone ( ) ) ;
387+ if let Some ( ( was_mut, old_val) ) = prev {
388+ new_env. map_variable ( var. clone ( ) , was_mut, old_val) ;
389+ }
390+ }
391+ Ok ( Computation :: Continue ( new_env) )
392+ }
393+
394+ // Tupla (assumindo que você tem Expression::Tuple)
395+ Expression :: Tuple ( items) => {
396+ for item in items {
397+ let prev = new_env. lookup ( & var. clone ( ) ) ;
398+ new_env. map_variable ( var. clone ( ) , false , item) ;
331399 match execute ( * stmt. clone ( ) , & new_env) ? {
332400 Computation :: Continue ( env) => new_env = env,
333401 Computation :: Return ( expr, env) => {
@@ -337,10 +405,38 @@ pub fn execute(stmt: Statement, env: &Environment<Expression>) -> Result<Computa
337405 return Ok ( Computation :: PropagateError ( expr, env) )
338406 }
339407 }
408+ let _ = new_env. remove_variable ( & var. clone ( ) ) ;
409+ if let Some ( ( was_mut, old_val) ) = prev {
410+ new_env. map_variable ( var. clone ( ) , was_mut, old_val) ;
411+ }
340412 }
341- return Ok ( Computation :: Continue ( new_env) ) ;
413+ Ok ( Computation :: Continue ( new_env) )
342414 }
343- _ => unreachable ! ( ) ,
415+
416+ // Constructor (já existia)
417+ Expression :: Constructor ( _, items) => {
418+ for item_expr in items {
419+ let item_value = * item_expr. clone ( ) ;
420+ let prev = new_env. lookup ( & var. clone ( ) ) ;
421+ new_env. map_variable ( var. clone ( ) , false , item_value) ;
422+ match execute ( * stmt. clone ( ) , & new_env) ? {
423+ Computation :: Continue ( env) => new_env = env,
424+ Computation :: Return ( expr, env) => {
425+ return Ok ( Computation :: Return ( expr, env) )
426+ }
427+ Computation :: PropagateError ( expr, env) => {
428+ return Ok ( Computation :: PropagateError ( expr, env) )
429+ }
430+ }
431+ let _ = new_env. remove_variable ( & var. clone ( ) ) ;
432+ if let Some ( ( was_mut, old_val) ) = prev {
433+ new_env. map_variable ( var. clone ( ) , was_mut, old_val) ;
434+ }
435+ }
436+ Ok ( Computation :: Continue ( new_env) )
437+ }
438+
439+ _ => Err ( String :: from ( "Cannot iterate over provided expression" ) ) ,
344440 }
345441 }
346442
@@ -859,11 +955,9 @@ mod tests {
859955 let ( _, result_expr) = result_value. unwrap ( ) ;
860956 assert_eq ! ( result_expr, Expression :: CInt ( 42 ) ) ;
861957
862- // Check that loop variable i is still accessible with the last value
958+ // With isolated loop scope, the iterator variable should NOT leak outside the loop
863959 let i_value = final_env. lookup ( & "i" . to_string ( ) ) ;
864- assert ! ( i_value. is_some( ) ) ;
865- let ( _, i_expr) = i_value. unwrap ( ) ;
866- assert_eq ! ( i_expr, Expression :: CInt ( 42 ) ) ;
960+ assert ! ( i_value. is_none( ) ) ;
867961 }
868962
869963 #[ test]
0 commit comments