@@ -29,6 +29,7 @@ struct Compiler<O: OutputStream = BasicOutputStream> {
2929 current_qualified_path : Option < String > ,
3030 in_loop : bool ,
3131 in_function_def : bool ,
32+ in_async_func : bool ,
3233 optimize : u8 ,
3334}
3435
@@ -126,6 +127,7 @@ impl<O: OutputStream> Compiler<O> {
126127 current_qualified_path : None ,
127128 in_loop : false ,
128129 in_function_def : false ,
130+ in_async_func : false ,
129131 optimize,
130132 }
131133 }
@@ -451,11 +453,7 @@ impl<O: OutputStream> Compiler<O> {
451453 decorator_list,
452454 returns,
453455 } => {
454- if * is_async {
455- unimplemented ! ( "async def" ) ;
456- } else {
457- self . compile_function_def ( name, args, body, decorator_list, returns) ?
458- }
456+ self . compile_function_def ( name, args, body, decorator_list, returns, * is_async) ?;
459457 }
460458 ClassDef {
461459 name,
@@ -797,11 +795,15 @@ impl<O: OutputStream> Compiler<O> {
797795 body : & [ ast:: Statement ] ,
798796 decorator_list : & [ ast:: Expression ] ,
799797 returns : & Option < ast:: Expression > , // TODO: use type hint somehow..
798+ is_async : bool ,
800799 ) -> Result < ( ) , CompileError > {
801800 // Create bytecode for this function:
802801 // remember to restore self.in_loop to the original after the function is compiled
803802 let was_in_loop = self . in_loop ;
804803 let was_in_function_def = self . in_function_def ;
804+
805+ let was_in_async_func = self . in_async_func ;
806+ self . in_async_func = is_async;
805807 self . in_loop = false ;
806808 self . in_function_def = true ;
807809
@@ -870,6 +872,10 @@ impl<O: OutputStream> Compiler<O> {
870872 } ) ;
871873 }
872874
875+ if is_async {
876+ code. flags |= bytecode:: CodeFlags :: IS_COROUTINE ;
877+ }
878+
873879 self . emit ( Instruction :: LoadConst {
874880 value : bytecode:: Constant :: Code {
875881 code : Box :: new ( code) ,
@@ -891,6 +897,7 @@ impl<O: OutputStream> Compiler<O> {
891897 self . current_qualified_path = old_qualified_path;
892898 self . in_loop = was_in_loop;
893899 self . in_function_def = was_in_function_def;
900+ self . in_async_func = was_in_async_func;
894901 Ok ( ( ) )
895902 }
896903
@@ -1551,7 +1558,7 @@ impl<O: OutputStream> Compiler<O> {
15511558 self . emit ( Instruction :: BuildSlice { size } ) ;
15521559 }
15531560 Yield { value } => {
1554- if !self . in_function_def {
1561+ if !self . in_function_def || self . in_async_func {
15551562 return Err ( CompileError {
15561563 error : CompileErrorType :: InvalidYield ,
15571564 location : self . current_source_location . clone ( ) ,
@@ -1566,8 +1573,13 @@ impl<O: OutputStream> Compiler<O> {
15661573 } ;
15671574 self . emit ( Instruction :: YieldValue ) ;
15681575 }
1569- Await { .. } => {
1570- unimplemented ! ( "await" ) ;
1576+ Await { value } => {
1577+ self . compile_expression ( value) ?;
1578+ self . emit ( Instruction :: GetAwaitable ) ;
1579+ self . emit ( Instruction :: LoadConst {
1580+ value : bytecode:: Constant :: None ,
1581+ } ) ;
1582+ self . emit ( Instruction :: YieldFrom ) ;
15711583 }
15721584 YieldFrom { value } => {
15731585 self . mark_generator ( ) ;
@@ -1612,8 +1624,14 @@ impl<O: OutputStream> Compiler<O> {
16121624 self . load_name ( name) ;
16131625 }
16141626 Lambda { args, body } => {
1627+ let was_in_loop = self . in_loop ;
1628+ let was_in_function_def = self . in_function_def ;
1629+ let was_in_async_func = self . in_async_func ;
1630+ self . in_async_func = false ;
1631+ self . in_loop = false ;
1632+ self . in_function_def = true ;
1633+
16151634 let name = "<lambda>" . to_string ( ) ;
1616- // no need to worry about the self.loop_depth because there are no loops in lambda expressions
16171635 self . enter_function ( & name, args) ?;
16181636 self . compile_expression ( body) ?;
16191637 self . emit ( Instruction :: ReturnValue ) ;
@@ -1629,6 +1647,10 @@ impl<O: OutputStream> Compiler<O> {
16291647 } ) ;
16301648 // Turn code object into function object:
16311649 self . emit ( Instruction :: MakeFunction ) ;
1650+
1651+ self . in_loop = was_in_loop;
1652+ self . in_function_def = was_in_function_def;
1653+ self . in_async_func = was_in_async_func;
16321654 }
16331655 Comprehension { kind, generators } => {
16341656 self . compile_comprehension ( kind, generators) ?;
0 commit comments