@@ -55,7 +55,8 @@ pub enum OpCode {
5555 CallSorted , CallEnumerate , CallZip , CallList , CallTuple , CallDict ,
5656 CallIsInstance , CallSet , CallInput , CallOrd , BuildDict , BuildList ,
5757 NotEq , Lt , Gt , LtEq , GtEq , And ,
58- Or , Not , JumpIfFalse , Jump , GetIter , ForIter
58+ Or , Not , JumpIfFalse , Jump , GetIter , ForIter ,
59+ GetItem
5960}
6061
6162#[ derive( Debug ) ] pub struct Instruction { pub opcode : OpCode , pub operand : u16 }
@@ -89,6 +90,8 @@ pub struct Parser<'src, I: Iterator<Item = Token>> {
8990 chunk : SSAChunk ,
9091 ssa_versions : HashMap < String , u32 > ,
9192 join_stack : Vec < JoinNode > ,
93+ loop_starts : Vec < u16 > , // continue salta aquí
94+ loop_breaks : Vec < Vec < usize > > // break: posiciones a patchear
9295}
9396
9497fn parse_string ( s : & str ) -> String {
@@ -116,7 +119,7 @@ fn unescape(s: &str) -> String {
116119
117120impl < ' src , I : Iterator < Item = Token > > Parser < ' src , I > {
118121 pub fn new ( source : & ' src str , iter : I ) -> Self {
119- Self { source, tokens : iter. peekable ( ) , chunk : SSAChunk :: default ( ) , ssa_versions : HashMap :: new ( ) , join_stack : Vec :: new ( ) }
122+ Self { source, tokens : iter. peekable ( ) , chunk : SSAChunk :: default ( ) , ssa_versions : HashMap :: new ( ) , join_stack : Vec :: new ( ) , loop_starts : Vec :: new ( ) , loop_breaks : Vec :: new ( ) }
120123 }
121124
122125 pub fn parse ( mut self ) -> SSAChunk {
@@ -181,13 +184,29 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
181184 fn at_end ( & mut self ) -> bool { self . peek ( ) . is_none ( ) }
182185 fn lexeme ( & self , t : & Token ) -> & ' src str { & self . source [ t. start ..t. end ] }
183186
187+ fn store_name ( & mut self , name : String ) {
188+ let ver = self . increment_version ( & name) ;
189+ let i = self . chunk . push_name ( & format ! ( "{}_{}" , name, ver) ) ;
190+ self . chunk . emit ( OpCode :: StoreName , i) ;
191+ }
192+
184193 fn stmt ( & mut self ) {
185194 match self . peek ( ) {
186195 Some ( TokenType :: If ) => self . if_stmt ( ) ,
187196 Some ( TokenType :: While ) => self . while_stmt ( ) ,
188197 Some ( TokenType :: For ) => self . for_stmt ( ) ,
189198 Some ( TokenType :: Name ) => { let t = self . advance ( ) ; self . name_stmt ( t) ; }
190199 Some ( TokenType :: Def ) => { self . advance ( ) ; self . func_def ( ) ; }
200+ Some ( TokenType :: Break ) => {
201+ self . advance ( ) ;
202+ self . chunk . emit ( OpCode :: Jump , 0 ) ;
203+ self . loop_breaks . last_mut ( ) . unwrap ( ) . push ( self . chunk . instructions . len ( ) - 1 ) ;
204+ }
205+ Some ( TokenType :: Continue ) => {
206+ self . advance ( ) ;
207+ let start = * self . loop_starts . last ( ) . unwrap ( ) ;
208+ self . chunk . emit ( OpCode :: Jump , start) ;
209+ }
191210 Some ( TokenType :: Return ) => {
192211 self . advance ( ) ;
193212 if matches ! ( self . peek( ) , Some ( TokenType :: Newline | TokenType :: Endmarker ) ) {
@@ -205,13 +224,17 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
205224 self . advance ( ) ;
206225 self . enter_block ( ) ;
207226 let loop_start = self . chunk . instructions . len ( ) as u16 ;
227+ self . loop_starts . push ( loop_start) ;
228+ self . loop_breaks . push ( vec ! [ ] ) ;
208229 self . expr ( ) ;
209230 self . chunk . emit ( OpCode :: JumpIfFalse , 0 ) ;
210231 let jf = self . chunk . instructions . len ( ) - 1 ;
211232 self . eat ( TokenType :: Colon ) ;
212233 self . stmt ( ) ;
213234 self . chunk . emit ( OpCode :: Jump , loop_start) ;
214235 self . patch ( jf) ;
236+ self . loop_starts . pop ( ) ;
237+ for pos in self . loop_breaks . pop ( ) . unwrap_or_default ( ) { self . patch ( pos) ; }
215238 self . commit_block ( ) ;
216239 }
217240
@@ -261,6 +284,8 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
261284 self . chunk . emit ( OpCode :: GetIter , 0 ) ;
262285
263286 let loop_start = self . chunk . instructions . len ( ) as u16 ;
287+ self . loop_starts . push ( loop_start) ;
288+ self . loop_breaks . push ( vec ! [ ] ) ;
264289 self . chunk . emit ( OpCode :: ForIter , 0 ) ;
265290 let fi = self . chunk . instructions . len ( ) - 1 ;
266291
@@ -270,9 +295,11 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
270295
271296 self . eat ( TokenType :: Colon ) ;
272297 self . stmt ( ) ;
273- self . chunk . emit ( OpCode :: PopTop , 0 ) ; // ← nuevo
298+ self . chunk . emit ( OpCode :: PopTop , 0 ) ;
274299 self . chunk . emit ( OpCode :: Jump , loop_start) ;
275300 self . patch ( fi) ;
301+ self . loop_starts . pop ( ) ;
302+ for pos in self . loop_breaks . pop ( ) . unwrap_or_default ( ) { self . patch ( pos) ; }
276303 }
277304
278305 // helpers
@@ -342,8 +369,12 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
342369
343370 // assign y call no necesitan la cadena de precedencia
344371 match self . peek ( ) {
345- Some ( TokenType :: Equal ) => { self . assign ( name) ; return ; }
346- Some ( TokenType :: Lpar ) => { self . call ( name) ; return ; }
372+ Some ( TokenType :: Equal ) => { self . assign ( name) ; return ; }
373+ Some ( TokenType :: PlusEqual ) => { self . advance ( ) ; self . emit_load_ssa ( name. clone ( ) ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Add , 0 ) ; self . store_name ( name) ; return ; }
374+ Some ( TokenType :: MinEqual ) => { self . advance ( ) ; self . emit_load_ssa ( name. clone ( ) ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Sub , 0 ) ; self . store_name ( name) ; return ; }
375+ Some ( TokenType :: StarEqual ) => { self . advance ( ) ; self . emit_load_ssa ( name. clone ( ) ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Mul , 0 ) ; self . store_name ( name) ; return ; }
376+ Some ( TokenType :: SlashEqual ) => { self . advance ( ) ; self . emit_load_ssa ( name. clone ( ) ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Div , 0 ) ; self . store_name ( name) ; return ; }
377+ Some ( TokenType :: Lpar ) => { self . call ( name) ; return ; }
347378 _ => { }
348379 }
349380
@@ -434,6 +465,12 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
434465 TokenType :: Lpar => { self . expr ( ) ; self . eat ( TokenType :: Rpar ) ; }
435466 _ => { }
436467 }
468+ while matches ! ( self . peek( ) , Some ( TokenType :: Lsqb ) ) {
469+ self . advance ( ) ;
470+ self . expr ( ) ;
471+ self . eat ( TokenType :: Rsqb ) ;
472+ self . chunk . emit ( OpCode :: GetItem , 0 ) ;
473+ }
437474 }
438475
439476 fn name ( & mut self , t : Token ) { // solo desde expr()
@@ -445,13 +482,10 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
445482 }
446483 }
447484
448- fn assign ( & mut self , name : String ) {
485+ fn assign ( & mut self , name : String ) {
449486 self . advance ( ) ;
450487 self . expr ( ) ;
451- let ver = self . increment_version ( & name) ;
452- let ssa = format ! ( "{}_{}" , name, ver) ;
453- let i = self . chunk . push_name ( & ssa) ;
454- self . chunk . emit ( OpCode :: StoreName , i) ;
488+ self . store_name ( name) ;
455489 }
456490
457491 fn parse_args ( & mut self ) -> u16 {
0 commit comments