@@ -82,8 +82,7 @@ impl SSAChunk {
8282}
8383
8484struct JoinNode {
85- phis : Vec < Phi > ,
86- backup : HashMap < String , u32 > ,
85+ backup : HashMap < String , u32 >
8786}
8887
8988pub struct Parser < ' src , I : Iterator < Item = Token > > {
@@ -148,14 +147,25 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
148147 self . chunk . emit ( OpCode :: LoadName , i) ;
149148 }
150149
151- fn enter_block ( & mut self ) { self . join_stack . push ( JoinNode { phis : Vec :: new ( ) , backup : self . ssa_versions . clone ( ) } ) ; }
150+ fn enter_block ( & mut self ) {
151+ self . join_stack . push ( JoinNode { backup : self . ssa_versions . clone ( ) } ) ;
152+ }
153+
152154 fn commit_block ( & mut self ) {
153- if let Some ( mut j) = self . join_stack . pop ( ) {
154- for phi in j. phis {
155- let i = self . chunk . push_name ( & phi. target ) ;
156- self . chunk . emit ( OpCode :: Phi , i) ;
157- }
155+ if let Some ( j) = self . join_stack . pop ( ) {
156+ let post = self . ssa_versions . clone ( ) ;
158157 self . ssa_versions = j. backup ;
158+ for ( name, post_ver) in & post {
159+ let pre_ver = self . ssa_versions . get ( name) . copied ( ) . unwrap_or ( 0 ) ;
160+ if * post_ver != pre_ver {
161+ // parte desde post_ver, no desde backup, evita colisión
162+ self . ssa_versions . insert ( name. to_string ( ) , * post_ver) ;
163+ let new_ver = self . increment_version ( name) ;
164+ let ssa = format ! ( "{}_{}" , name, new_ver) ;
165+ let i = self . chunk . push_name ( & ssa) ;
166+ self . chunk . emit ( OpCode :: Phi , i) ;
167+ }
168+ }
159169 }
160170 }
161171
@@ -175,17 +185,24 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
175185
176186 fn stmt ( & mut self ) {
177187 match self . peek ( ) {
178- Some ( TokenType :: If ) => self . if_stmt ( ) ,
188+ Some ( TokenType :: If ) => self . if_stmt ( ) ,
179189 Some ( TokenType :: While ) => self . while_stmt ( ) ,
180190 Some ( TokenType :: For ) => self . for_stmt ( ) ,
191+ Some ( TokenType :: Name ) => { let t = self . advance ( ) ; self . name_stmt ( t) ; }
181192 _ => self . expr ( )
182193 }
183194 }
184195
185196 fn while_stmt ( & mut self ) { self . advance ( ) ; self . enter_block ( ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: PopTop , 0 ) ; if matches ! ( self . peek( ) , Some ( TokenType :: Colon ) ) { self . advance ( ) ; } self . stmt ( ) ; self . commit_block ( ) ; }
186197
187198 fn if_stmt ( & mut self ) {
188- self . advance ( ) ; // consume 'if' o 'elif'
199+ self . advance ( ) ; // consume 'if'
200+ self . enter_block ( ) ; // un solo bloque para toda la cadena
201+ self . if_body ( ) ; // parsea if / elif* / else?
202+ self . commit_block ( ) ; // un solo join point al final
203+ }
204+
205+ fn if_body ( & mut self ) {
189206 self . expr ( ) ;
190207 self . chunk . emit ( OpCode :: JumpIfFalse , 0 ) ;
191208 let jf = self . chunk . instructions . len ( ) - 1 ;
@@ -194,9 +211,25 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
194211 self . chunk . emit ( OpCode :: PopTop , 0 ) ;
195212
196213 match self . peek ( ) {
197- Some ( TokenType :: Elif ) => { self . chunk . emit ( OpCode :: Jump , 0 ) ; let jmp = self . chunk . instructions . len ( ) - 1 ; self . patch ( jf) ; self . if_stmt ( ) ; self . patch ( jmp) ; }
198- Some ( TokenType :: Else ) => { self . advance ( ) ; self . chunk . emit ( OpCode :: Jump , 0 ) ; let jmp = self . chunk . instructions . len ( ) - 1 ; self . patch ( jf) ; self . eat ( TokenType :: Colon ) ; self . stmt ( ) ; self . chunk . emit ( OpCode :: PopTop , 0 ) ; self . patch ( jmp) ; }
199- _ => { self . patch ( jf) ; }
214+ Some ( TokenType :: Elif ) => {
215+ self . advance ( ) ; // consume 'elif'
216+ self . chunk . emit ( OpCode :: Jump , 0 ) ;
217+ let jmp = self . chunk . instructions . len ( ) - 1 ;
218+ self . patch ( jf) ;
219+ self . if_body ( ) ; // recursivo SIN enter/commit
220+ self . patch ( jmp) ;
221+ }
222+ Some ( TokenType :: Else ) => {
223+ self . advance ( ) ;
224+ self . chunk . emit ( OpCode :: Jump , 0 ) ;
225+ let jmp = self . chunk . instructions . len ( ) - 1 ;
226+ self . patch ( jf) ;
227+ self . eat ( TokenType :: Colon ) ;
228+ self . stmt ( ) ;
229+ self . chunk . emit ( OpCode :: PopTop , 0 ) ;
230+ self . patch ( jmp) ;
231+ }
232+ _ => { self . patch ( jf) ; }
200233 }
201234 }
202235
@@ -313,14 +346,21 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
313346 self . chunk . emit ( OpCode :: LoadConst , i) ;
314347 }
315348
316- fn name ( & mut self , t : Token ) {
349+ fn name_stmt ( & mut self , t : Token ) { // solo desde stmt()
317350 let name = self . lexeme ( & t) . to_string ( ) ;
318-
319351 if self . eat_if ( TokenType :: Colon ) {
320- let ann = { let t = self . advance ( ) ; self . lexeme ( & t) . to_string ( ) } ;
321- self . chunk . annotations . insert ( name. clone ( ) , ann) ;
352+ if matches ! ( self . peek( ) , Some ( TokenType :: Name ) ) {
353+ let ann = { let t = self . advance ( ) ; self . lexeme ( & t) . to_string ( ) } ;
354+ self . chunk . annotations . insert ( name. clone ( ) , ann) ;
355+ }
356+ if !matches ! ( self . peek( ) , Some ( TokenType :: Equal ) ) { return ; }
322357 }
358+ self . name ( t) ; // delega: lógica en un solo lugar
359+ self . binary_op ( ) ;
360+ }
323361
362+ fn name ( & mut self , t : Token ) { // solo desde expr()
363+ let name = self . lexeme ( & t) . to_string ( ) ;
324364 match self . peek ( ) {
325365 Some ( TokenType :: Equal ) => self . assign ( name) ,
326366 Some ( TokenType :: Lpar ) => self . call ( name) ,
0 commit comments