@@ -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 , LoadEllipsis , GenExpr
41+ RaiseFrom , UnpackEx , LoadEllipsis , GenExpr , Await , MakeCoroutine
4242}
4343
4444// ─── Builtin dispatch table (O(1) lookup) ───────────────────────────────────
@@ -334,16 +334,41 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
334334 Some ( TokenType :: For ) => { self . for_stmt ( ) ; false }
335335 Some ( TokenType :: Def ) => { self . advance ( ) ; self . func_def ( 0 ) ; false }
336336 Some ( TokenType :: Match ) => { self . match_stmt ( ) ; false }
337+ Some ( TokenType :: Async ) => {
338+ self . advance ( ) ;
339+ match self . peek ( ) {
340+ Some ( TokenType :: Def ) => {
341+ self . advance ( ) ;
342+ self . async_func_def ( 0 ) ;
343+ }
344+ Some ( TokenType :: For ) => { self . for_stmt ( ) ; }
345+ Some ( TokenType :: With ) => { self . with_stmt ( ) ; }
346+ _ => { }
347+ }
348+ false
349+ }
350+ Some ( TokenType :: Await ) => {
351+ self . advance ( ) ;
352+ self . expr ( ) ;
353+ self . chunk . emit ( OpCode :: Await , 0 ) ;
354+ true
355+ }
337356 Some ( TokenType :: At ) => {
338357 let mut count = 0u16 ;
339358 while self . eat_if ( TokenType :: At ) {
340359 self . expr ( ) ;
341360 count += 1 ;
342361 }
343- self . advance ( ) ;
344- self . func_def ( count) ;
362+ if self . eat_if ( TokenType :: Async ) {
363+ self . advance ( ) ;
364+ self . async_func_def ( count) ;
365+ } else {
366+ self . advance ( ) ;
367+ self . func_def ( count) ;
368+ }
345369 false
346- } Some ( TokenType :: Class ) => { self . advance ( ) ; self . class_def ( ) ; false }
370+ }
371+ Some ( TokenType :: Class ) => { self . advance ( ) ; self . class_def ( ) ; false }
347372 Some ( TokenType :: Pass ) => { self . advance ( ) ; false }
348373 Some ( TokenType :: Try ) => { self . try_stmt ( ) ; false }
349374 Some ( TokenType :: Import ) => { self . import_stmt ( ) ; false }
@@ -960,10 +985,29 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
960985 Some ( TokenType :: Minus ) => { self . advance ( ) ; self . parse_unary ( ) ; self . chunk . emit ( OpCode :: Minus , 0 ) ; }
961986 Some ( TokenType :: Not ) => { self . advance ( ) ; self . parse_unary ( ) ; self . chunk . emit ( OpCode :: Not , 0 ) ; }
962987 Some ( TokenType :: Tilde ) => { self . advance ( ) ; self . parse_unary ( ) ; self . chunk . emit ( OpCode :: BitNot , 0 ) ; }
988+ Some ( TokenType :: Await ) => { self . advance ( ) ; self . parse_unary ( ) ; self . chunk . emit ( OpCode :: Await , 0 ) ; }
963989 _ => self . parse_atom ( ) ,
964990 }
965991 }
966992
993+ fn async_func_def ( & mut self , decorators : u16 ) {
994+ let fname = { let n = self . advance ( ) ; self . lexeme ( & n) . to_string ( ) } ;
995+ let ( params, defaults) = self . parse_params ( ) ;
996+ let body = self . compile_body ( & params) ;
997+
998+ let fi = self . chunk . functions . len ( ) as u16 ;
999+ self . chunk . functions . push ( ( params, body, defaults) ) ;
1000+ self . chunk . emit ( OpCode :: MakeCoroutine , fi) ;
1001+
1002+ for _ in 0 ..decorators {
1003+ self . chunk . emit ( OpCode :: Call , 1 ) ;
1004+ }
1005+
1006+ let ver = self . increment_version ( & fname) ;
1007+ let i = self . chunk . push_name ( & format ! ( "{}_{}" , fname, ver) ) ;
1008+ self . chunk . emit ( OpCode :: StoreName , i) ;
1009+ }
1010+
9671011 fn parse_not ( & mut self ) {
9681012 if matches ! ( self . peek( ) , Some ( TokenType :: Not ) ) {
9691013 self . advance ( ) ; self . parse_not ( ) ; self . chunk . emit ( OpCode :: Not , 0 ) ;
0 commit comments