@@ -158,16 +158,22 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
158158 if let Some ( j) = self . join_stack . pop ( ) {
159159 let post = self . ssa_versions . clone ( ) ;
160160 self . ssa_versions = j. backup ;
161- for ( name, post_ver) in & post {
162- let pre_ver = self . ssa_versions . get ( name) . copied ( ) . unwrap_or ( 0 ) ;
163- if * post_ver != pre_ver {
164- // parte desde post_ver, no desde backup, evita colisión
165- self . ssa_versions . insert ( name. to_string ( ) , * post_ver) ;
166- let new_ver = self . increment_version ( name) ;
167- let ssa = format ! ( "{}_{}" , name, new_ver) ;
168- let i = self . chunk . push_name ( & ssa) ;
169- self . chunk . emit ( OpCode :: Phi , i) ;
170- }
161+
162+ let mut diffs: Vec < ( String , u32 ) > = post
163+ . into_iter ( )
164+ . filter ( |( name, post_ver) | {
165+ self . ssa_versions . get ( name) . copied ( ) . unwrap_or ( 0 ) != * post_ver
166+ } )
167+ . collect ( ) ;
168+
169+ diffs. sort_by ( |( a, _) , ( b, _) | a. cmp ( b) ) ;
170+
171+ for ( name, post_ver) in diffs {
172+ self . ssa_versions . insert ( name. clone ( ) , post_ver) ;
173+ let new_ver = self . increment_version ( & name) ;
174+ let ssa = format ! ( "{}_{}" , name, new_ver) ;
175+ let i = self . chunk . push_name ( & ssa) ;
176+ self . chunk . emit ( OpCode :: Phi , i) ;
171177 }
172178 }
173179 }
@@ -283,6 +289,8 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
283289 self . expr ( ) ;
284290 self . chunk . emit ( OpCode :: GetIter , 0 ) ;
285291
292+ self . enter_block ( ) ; // ← snapshot pre-loop
293+
286294 let loop_start = self . chunk . instructions . len ( ) as u16 ;
287295 self . loop_starts . push ( loop_start) ;
288296 self . loop_breaks . push ( vec ! [ ] ) ;
@@ -294,12 +302,14 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
294302 self . chunk . emit ( OpCode :: StoreName , idx) ;
295303
296304 self . eat ( TokenType :: Colon ) ;
297- self . compile_block ( ) ; // ← correcto
305+ self . compile_block ( ) ;
298306
299307 self . chunk . emit ( OpCode :: Jump , loop_start) ;
300308 self . patch ( fi) ;
301309 self . loop_starts . pop ( ) ;
302310 for pos in self . loop_breaks . pop ( ) . unwrap_or_default ( ) { self . patch ( pos) ; }
311+
312+ self . commit_block ( ) ; // ← phi-nodes al salir
303313 }
304314
305315 // helpers
@@ -314,27 +324,24 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
314324 }
315325
316326 fn compile_block ( & mut self ) {
317- self . eat_if ( TokenType :: Indent ) ;
327+ let indented = self . eat_if ( TokenType :: Indent ) ;
318328
319329 while !self . at_end ( ) {
320330 if matches ! ( self . peek( ) , Some ( TokenType :: Dedent ) ) {
321331 self . advance ( ) ;
322332 break ;
323333 }
324-
325334 if matches ! ( self . peek( ) , Some ( TokenType :: Newline | TokenType :: Nl ) ) {
326335 self . advance ( ) ;
327336 continue ;
328337 }
329-
330338 let is_compound = matches ! ( self . peek( ) ,
331339 Some ( TokenType :: For | TokenType :: If | TokenType :: While | TokenType :: Def ) ) ;
332-
333- self . stmt ( ) ; // ← ya lo tienes, perfecto
334-
340+ self . stmt ( ) ;
335341 if !self . at_end ( ) && !is_compound {
336342 self . chunk . emit ( OpCode :: PopTop , 0 ) ;
337343 }
344+ if !indented { break ; } // ← única línea que cambia
338345 }
339346 }
340347
0 commit comments