@@ -38,7 +38,7 @@ pub enum OpCode {
3838 In , NotIn , Is , IsNot , UnpackSequence , BuildTuple ,
3939 SetupWith , ExitWith , Yield , Del , Assert , Global ,
4040 Nonlocal , UnpackArgs , ListComp , SetComp , DictComp , BuildSet ,
41- RaiseFrom , UnpackEx
41+ RaiseFrom , UnpackEx , LoadEllipsis , GenExpr
4242}
4343
4444// ─── Builtin dispatch table (O(1) lookup) ───────────────────────────────────
@@ -96,6 +96,18 @@ impl SSAChunk {
9696 self . instructions . push ( Instruction { opcode : op, operand } ) ;
9797 }
9898
99+ fn snapshot ( & self ) -> ( usize , usize , usize ) {
100+ ( self . instructions . len ( ) , self . constants . len ( ) , self . names . len ( ) )
101+ }
102+
103+ fn restore ( & mut self , ( inst, consts, names) : ( usize , usize , usize ) ) {
104+ self . instructions . truncate ( inst) ;
105+ self . constants . truncate ( consts) ;
106+ for name in self . names . drain ( names..) {
107+ self . name_index . remove ( & name) ;
108+ }
109+ }
110+
99111 fn push_const ( & mut self , v : Value ) -> u16 {
100112 self . constants . push ( v) ;
101113 ( self . constants . len ( ) - 1 ) as u16
@@ -619,12 +631,15 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
619631
620632 fn with_stmt ( & mut self ) {
621633 self . advance ( ) ;
622- self . expr ( ) ;
623- self . chunk . emit ( OpCode :: SetupWith , 0 ) ;
624- if self . eat_if ( TokenType :: As ) {
625- let t = self . advance ( ) ;
626- let name = self . lexeme ( & t) . to_string ( ) ;
627- self . store_name ( name) ;
634+ loop {
635+ self . expr ( ) ;
636+ self . chunk . emit ( OpCode :: SetupWith , 0 ) ;
637+ if self . eat_if ( TokenType :: As ) {
638+ let t = self . advance ( ) ;
639+ let name = self . lexeme ( & t) . to_string ( ) ;
640+ self . store_name ( name) ;
641+ }
642+ if !self . eat_if ( TokenType :: Comma ) { break ; }
628643 }
629644 self . eat ( TokenType :: Colon ) ;
630645 self . compile_block ( ) ;
@@ -1051,17 +1066,32 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
10511066 let t = self . advance ( ) ;
10521067 match t. kind {
10531068 TokenType :: Name => self . name ( t) ,
1054- TokenType :: String => self . emit_const ( Value :: Str ( parse_string ( self . lexeme ( & t) ) ) ) ,
1069+ TokenType :: String => {
1070+ let mut s = parse_string ( self . lexeme ( & t) ) ;
1071+ while matches ! ( self . peek( ) , Some ( TokenType :: String ) ) {
1072+ let t = self . advance ( ) ;
1073+ s. push_str ( & parse_string ( self . lexeme ( & t) ) ) ;
1074+ }
1075+ self . emit_const ( Value :: Str ( s) ) ;
1076+ }
1077+ TokenType :: Complex => {
1078+ let raw = self . lexeme ( & t) . replace ( '_' , "" ) ;
1079+ let s = raw. trim_end_matches ( |c : char | c == 'j' || c == 'J' ) ;
1080+ self . emit_const ( Value :: Float ( s. parse ( ) . unwrap_or ( 0.0 ) ) ) ;
1081+ }
10551082 TokenType :: Int | TokenType :: Float => self . parse_number ( self . lexeme ( & t) , t. kind ) ,
10561083 TokenType :: True => self . chunk . emit ( OpCode :: LoadTrue , 0 ) ,
10571084 TokenType :: False => self . chunk . emit ( OpCode :: LoadFalse , 0 ) ,
10581085 TokenType :: None => self . chunk . emit ( OpCode :: LoadNone , 0 ) ,
1086+ TokenType :: Ellipsis => self . chunk . emit ( OpCode :: LoadEllipsis , 0 ) ,
10591087 TokenType :: FstringStart => self . fstring ( ) ,
10601088 TokenType :: Lbrace => self . brace_literal ( ) ,
10611089 TokenType :: Lsqb => self . list_literal ( ) ,
10621090 TokenType :: Lpar => {
10631091 self . expr ( ) ;
1064- if self . eat_if ( TokenType :: Comma ) {
1092+ if matches ! ( self . peek( ) , Some ( TokenType :: For ) ) {
1093+ self . comprehension ( OpCode :: GenExpr ) ;
1094+ } else if self . eat_if ( TokenType :: Comma ) {
10651095 let mut count = 1u16 ;
10661096 while !matches ! ( self . peek( ) , Some ( TokenType :: Rpar ) | None ) {
10671097 self . expr ( ) ;
@@ -1254,7 +1284,7 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
12541284 let t = self . advance ( ) ;
12551285 let var = self . lexeme ( & t) . to_string ( ) ;
12561286 self . eat ( TokenType :: In ) ;
1257- self . expr ( ) ;
1287+ self . parse_or ( ) ;
12581288 self . chunk . emit ( OpCode :: GetIter , 0 ) ;
12591289
12601290 let ls = self . chunk . instructions . len ( ) as u16 ;
@@ -1265,8 +1295,8 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
12651295 let idx = self . chunk . push_name ( & format ! ( "{}_{}" , var, ver) ) ;
12661296 self . chunk . emit ( OpCode :: StoreName , idx) ;
12671297
1268- if self . eat_if ( TokenType :: If ) {
1269- self . expr ( ) ;
1298+ while self . eat_if ( TokenType :: If ) {
1299+ self . parse_or ( ) ;
12701300 self . chunk . emit ( OpCode :: JumpIfFalse , ls) ;
12711301 }
12721302
@@ -1493,12 +1523,33 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
14931523 if self . eat_if ( TokenType :: Star ) {
14941524 let p = self . advance ( ) ;
14951525 params. push ( format ! ( "*{}" , self . lexeme( & p) ) ) ;
1526+ if self . eat_if ( TokenType :: Colon ) {
1527+ while !matches ! ( self . peek( ) , Some (
1528+ TokenType :: Equal | TokenType :: Comma | TokenType :: Rpar
1529+ ) | None ) {
1530+ self . advance ( ) ;
1531+ }
1532+ }
14961533 } else if self . eat_if ( TokenType :: DoubleStar ) {
14971534 let p = self . advance ( ) ;
14981535 params. push ( format ! ( "**{}" , self . lexeme( & p) ) ) ;
1536+ if self . eat_if ( TokenType :: Colon ) {
1537+ while !matches ! ( self . peek( ) , Some (
1538+ TokenType :: Equal | TokenType :: Comma | TokenType :: Rpar
1539+ ) | None ) {
1540+ self . advance ( ) ;
1541+ }
1542+ }
14991543 } else {
15001544 let p = self . advance ( ) ;
15011545 params. push ( self . lexeme ( & p) . to_string ( ) ) ;
1546+ if self . eat_if ( TokenType :: Colon ) {
1547+ while !matches ! ( self . peek( ) , Some (
1548+ TokenType :: Equal | TokenType :: Comma | TokenType :: Rpar
1549+ ) | None ) {
1550+ self . advance ( ) ;
1551+ }
1552+ }
15021553 if self . eat_if ( TokenType :: Equal ) {
15031554 self . expr ( ) ;
15041555 defaults += 1 ;
@@ -1507,6 +1558,11 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
15071558 if matches ! ( self . peek( ) , Some ( TokenType :: Comma ) ) { self . advance ( ) ; }
15081559 }
15091560 self . advance ( ) ;
1561+ if self . eat_if ( TokenType :: Rarrow ) {
1562+ while !matches ! ( self . peek( ) , Some ( TokenType :: Colon ) | None ) {
1563+ self . advance ( ) ;
1564+ }
1565+ }
15101566 if matches ! ( self . peek( ) , Some ( TokenType :: Colon ) ) { self . advance ( ) ; }
15111567 ( params, defaults)
15121568 }
0 commit comments