@@ -318,14 +318,14 @@ STATIC void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int la
318318typedef enum { ASSIGN_STORE , ASSIGN_AUG_LOAD , ASSIGN_AUG_STORE } assign_kind_t ;
319319STATIC void c_assign (compiler_t * comp , mp_parse_node_t pn , assign_kind_t kind );
320320
321- STATIC void c_assign_power (compiler_t * comp , mp_parse_node_struct_t * pns , assign_kind_t assign_kind ) {
321+ STATIC void c_assign_atom_expr (compiler_t * comp , mp_parse_node_struct_t * pns , assign_kind_t assign_kind ) {
322322 if (assign_kind != ASSIGN_AUG_STORE ) {
323323 compile_node (comp , pns -> nodes [0 ]);
324324 }
325325
326326 if (MP_PARSE_NODE_IS_STRUCT (pns -> nodes [1 ])) {
327327 mp_parse_node_struct_t * pns1 = (mp_parse_node_struct_t * )pns -> nodes [1 ];
328- if (MP_PARSE_NODE_STRUCT_KIND (pns1 ) == PN_power_trailers ) {
328+ if (MP_PARSE_NODE_STRUCT_KIND (pns1 ) == PN_atom_expr_trailers ) {
329329 int n = MP_PARSE_NODE_STRUCT_NUM_NODES (pns1 );
330330 if (assign_kind != ASSIGN_AUG_STORE ) {
331331 for (int i = 0 ; i < n - 1 ; i ++ ) {
@@ -366,10 +366,6 @@ STATIC void c_assign_power(compiler_t *comp, mp_parse_node_struct_t *pns, assign
366366 goto cannot_assign ;
367367 }
368368
369- if (!MP_PARSE_NODE_IS_NULL (pns -> nodes [2 ])) {
370- goto cannot_assign ;
371- }
372-
373369 return ;
374370
375371cannot_assign :
@@ -440,9 +436,9 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_
440436 // pn must be a struct
441437 mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
442438 switch (MP_PARSE_NODE_STRUCT_KIND (pns )) {
443- case PN_power :
439+ case PN_atom_expr_normal :
444440 // lhs is an index or attribute
445- c_assign_power (comp , pns , assign_kind );
441+ c_assign_atom_expr (comp , pns , assign_kind );
446442 break ;
447443
448444 case PN_testlist_star_expr :
@@ -818,11 +814,19 @@ STATIC void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
818814 }
819815 }
820816
821- // compile the body (funcdef or classdef) and get its name
817+ // compile the body (funcdef, async funcdef or classdef) and get its name
822818 mp_parse_node_struct_t * pns_body = (mp_parse_node_struct_t * )pns -> nodes [1 ];
823819 qstr body_name = 0 ;
824820 if (MP_PARSE_NODE_STRUCT_KIND (pns_body ) == PN_funcdef ) {
825821 body_name = compile_funcdef_helper (comp , pns_body , emit_options );
822+ #if MICROPY_PY_ASYNC_AWAIT
823+ } else if (MP_PARSE_NODE_STRUCT_KIND (pns_body ) == PN_async_funcdef ) {
824+ assert (MP_PARSE_NODE_IS_STRUCT (pns_body -> nodes [0 ]));
825+ mp_parse_node_struct_t * pns0 = (mp_parse_node_struct_t * )pns_body -> nodes [0 ];
826+ body_name = compile_funcdef_helper (comp , pns0 , emit_options );
827+ scope_t * fscope = (scope_t * )pns0 -> nodes [4 ];
828+ fscope -> scope_flags |= MP_SCOPE_FLAG_GENERATOR ;
829+ #endif
826830 } else {
827831 assert (MP_PARSE_NODE_STRUCT_KIND (pns_body ) == PN_classdef ); // should be
828832 body_name = compile_classdef_helper (comp , pns_body , emit_options );
@@ -846,14 +850,14 @@ STATIC void compile_funcdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
846850STATIC void c_del_stmt (compiler_t * comp , mp_parse_node_t pn ) {
847851 if (MP_PARSE_NODE_IS_ID (pn )) {
848852 compile_delete_id (comp , MP_PARSE_NODE_LEAF_ARG (pn ));
849- } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pn , PN_power )) {
853+ } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pn , PN_atom_expr_normal )) {
850854 mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
851855
852- compile_node (comp , pns -> nodes [0 ]); // base of the power node
856+ compile_node (comp , pns -> nodes [0 ]); // base of the atom_expr_normal node
853857
854858 if (MP_PARSE_NODE_IS_STRUCT (pns -> nodes [1 ])) {
855859 mp_parse_node_struct_t * pns1 = (mp_parse_node_struct_t * )pns -> nodes [1 ];
856- if (MP_PARSE_NODE_STRUCT_KIND (pns1 ) == PN_power_trailers ) {
860+ if (MP_PARSE_NODE_STRUCT_KIND (pns1 ) == PN_atom_expr_trailers ) {
857861 int n = MP_PARSE_NODE_STRUCT_NUM_NODES (pns1 );
858862 for (int i = 0 ; i < n - 1 ; i ++ ) {
859863 compile_node (comp , pns1 -> nodes [i ]);
@@ -874,9 +878,6 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
874878 goto cannot_delete ;
875879 }
876880
877- if (!MP_PARSE_NODE_IS_NULL (pns -> nodes [2 ])) {
878- goto cannot_delete ;
879- }
880881 } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pn , PN_atom_paren )) {
881882 pn = ((mp_parse_node_struct_t * )pn )-> nodes [0 ];
882883 if (MP_PARSE_NODE_IS_NULL (pn )) {
@@ -1397,9 +1398,9 @@ STATIC void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
13971398 // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
13981399 // this is actually slower, but uses no heap memory
13991400 // for viper it will be much, much faster
1400- if (/*comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [1 ], PN_power )) {
1401+ if (/*comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [1 ], PN_atom_expr_normal )) {
14011402 mp_parse_node_struct_t * pns_it = (mp_parse_node_struct_t * )pns -> nodes [1 ];
1402- if (MP_PARSE_NODE_IS_ID (pns_it -> nodes [0 ])
1403+ if (MP_PARSE_NODE_IS_ID (pns_it -> nodes [0 ])
14031404 && MP_PARSE_NODE_LEAF_ARG (pns_it -> nodes [0 ]) == MP_QSTR_range
14041405 && MP_PARSE_NODE_IS_STRUCT_KIND (pns_it -> nodes [1 ], PN_trailer_paren )
14051406 && MP_PARSE_NODE_IS_NULL (pns_it -> nodes [2 ])) {
@@ -1661,6 +1662,177 @@ STATIC void compile_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
16611662 compile_with_stmt_helper (comp , n , nodes , pns -> nodes [1 ]);
16621663}
16631664
1665+ STATIC void compile_yield_from (compiler_t * comp ) {
1666+ EMIT (get_iter );
1667+ EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE );
1668+ EMIT (yield_from );
1669+ }
1670+
1671+ #if MICROPY_PY_ASYNC_AWAIT
1672+ STATIC void compile_await_object_method (compiler_t * comp , qstr method ) {
1673+ EMIT_ARG (load_method , method );
1674+ EMIT_ARG (call_method , 0 , 0 , 0 );
1675+ compile_yield_from (comp );
1676+ }
1677+
1678+ STATIC void compile_async_for_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
1679+ // comp->break_label |= MP_EMIT_BREAK_FROM_FOR;
1680+
1681+ qstr context = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [1 ]);
1682+ uint while_else_label = comp_next_label (comp );
1683+ uint try_exception_label = comp_next_label (comp );
1684+ uint try_else_label = comp_next_label (comp );
1685+ uint try_finally_label = comp_next_label (comp );
1686+
1687+ compile_node (comp , pns -> nodes [1 ]); // iterator
1688+ compile_await_object_method (comp , MP_QSTR___aiter__ );
1689+ compile_store_id (comp , context );
1690+
1691+ START_BREAK_CONTINUE_BLOCK
1692+
1693+ EMIT_ARG (label_assign , continue_label );
1694+
1695+ EMIT_ARG (setup_except , try_exception_label );
1696+ compile_increase_except_level (comp );
1697+
1698+ compile_load_id (comp , context );
1699+ compile_await_object_method (comp , MP_QSTR___anext__ );
1700+ c_assign (comp , pns -> nodes [0 ], ASSIGN_STORE ); // variable
1701+ EMIT (pop_block );
1702+ EMIT_ARG (jump , try_else_label );
1703+
1704+ EMIT_ARG (label_assign , try_exception_label );
1705+ EMIT (start_except_handler );
1706+ EMIT (dup_top );
1707+ EMIT_LOAD_GLOBAL (MP_QSTR_StopAsyncIteration );
1708+ EMIT_ARG (binary_op , MP_BINARY_OP_EXCEPTION_MATCH );
1709+ EMIT_ARG (pop_jump_if , false, try_finally_label );
1710+ EMIT (pop_top );
1711+ EMIT (pop_top );
1712+ EMIT (pop_top );
1713+ EMIT (pop_except );
1714+ EMIT_ARG (jump , while_else_label );
1715+
1716+ EMIT_ARG (label_assign , try_finally_label );
1717+ EMIT_ARG (adjust_stack_size , 3 );
1718+ compile_decrease_except_level (comp );
1719+ EMIT (end_finally );
1720+ EMIT (end_except_handler );
1721+
1722+ EMIT_ARG (label_assign , try_else_label );
1723+ compile_node (comp , pns -> nodes [2 ]); // body
1724+
1725+ EMIT_ARG (jump , continue_label );
1726+ // break/continue apply to outer loop (if any) in the else block
1727+ END_BREAK_CONTINUE_BLOCK
1728+
1729+ EMIT_ARG (label_assign , while_else_label );
1730+ compile_node (comp , pns -> nodes [3 ]); // else
1731+
1732+ EMIT_ARG (label_assign , break_label );
1733+ }
1734+
1735+ STATIC void compile_async_with_stmt_helper (compiler_t * comp , int n , mp_parse_node_t * nodes , mp_parse_node_t body ) {
1736+ if (n == 0 ) {
1737+ // no more pre-bits, compile the body of the with
1738+ compile_node (comp , body );
1739+ } else {
1740+ uint try_exception_label = comp_next_label (comp );
1741+ uint no_reraise_label = comp_next_label (comp );
1742+ uint try_else_label = comp_next_label (comp );
1743+ uint end_label = comp_next_label (comp );
1744+ qstr context ;
1745+
1746+ if (MP_PARSE_NODE_IS_STRUCT_KIND (nodes [0 ], PN_with_item )) {
1747+ // this pre-bit is of the form "a as b"
1748+ mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )nodes [0 ];
1749+ compile_node (comp , pns -> nodes [0 ]);
1750+ context = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
1751+ compile_store_id (comp , context );
1752+ compile_load_id (comp , context );
1753+ compile_await_object_method (comp , MP_QSTR___aenter__ );
1754+ c_assign (comp , pns -> nodes [1 ], ASSIGN_STORE );
1755+ } else {
1756+ // this pre-bit is just an expression
1757+ compile_node (comp , nodes [0 ]);
1758+ context = MP_PARSE_NODE_LEAF_ARG (nodes [0 ]);
1759+ compile_store_id (comp , context );
1760+ compile_load_id (comp , context );
1761+ compile_await_object_method (comp , MP_QSTR___aenter__ );
1762+ EMIT (pop_top );
1763+ }
1764+
1765+ compile_load_id (comp , context );
1766+ EMIT_ARG (load_method , MP_QSTR___aexit__ );
1767+
1768+ EMIT_ARG (setup_except , try_exception_label );
1769+ compile_increase_except_level (comp );
1770+ // compile additional pre-bits and the body
1771+ compile_async_with_stmt_helper (comp , n - 1 , nodes + 1 , body );
1772+ // finish this with block
1773+ EMIT (pop_block );
1774+ EMIT_ARG (jump , try_else_label ); // jump over exception handler
1775+
1776+ EMIT_ARG (label_assign , try_exception_label ); // start of exception handler
1777+ EMIT (start_except_handler );
1778+ EMIT (rot_three );
1779+ EMIT (rot_two );
1780+ EMIT_ARG (call_method , 3 , 0 , 0 );
1781+ compile_yield_from (comp );
1782+ EMIT_ARG (pop_jump_if , true, no_reraise_label );
1783+ EMIT_ARG (raise_varargs , 0 );
1784+
1785+ EMIT_ARG (label_assign , no_reraise_label );
1786+ EMIT (pop_except );
1787+ EMIT_ARG (jump , end_label );
1788+
1789+ EMIT_ARG (adjust_stack_size , 5 );
1790+ compile_decrease_except_level (comp );
1791+ EMIT (end_finally );
1792+ EMIT (end_except_handler );
1793+
1794+ EMIT_ARG (label_assign , try_else_label ); // start of try-else handler
1795+ EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE );
1796+ EMIT (dup_top );
1797+ EMIT (dup_top );
1798+ EMIT_ARG (call_method , 3 , 0 , 0 );
1799+ compile_yield_from (comp );
1800+ EMIT (pop_top );
1801+
1802+ EMIT_ARG (label_assign , end_label );
1803+
1804+ }
1805+ }
1806+
1807+ STATIC void compile_async_with_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
1808+ // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1809+ mp_parse_node_t * nodes ;
1810+ int n = mp_parse_node_extract_list (& pns -> nodes [0 ], PN_with_stmt_list , & nodes );
1811+ assert (n > 0 );
1812+
1813+ // compile in a nested fashion
1814+ compile_async_with_stmt_helper (comp , n , nodes , pns -> nodes [1 ]);
1815+ }
1816+
1817+ STATIC void compile_async_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
1818+ assert (MP_PARSE_NODE_IS_STRUCT (pns -> nodes [0 ]));
1819+ mp_parse_node_struct_t * pns0 = (mp_parse_node_struct_t * )pns -> nodes [0 ];
1820+ if (MP_PARSE_NODE_STRUCT_KIND (pns0 ) == PN_funcdef ) {
1821+ // async def
1822+ compile_funcdef (comp , pns0 );
1823+ scope_t * fscope = (scope_t * )pns0 -> nodes [4 ];
1824+ fscope -> scope_flags |= MP_SCOPE_FLAG_GENERATOR ;
1825+ } else if (MP_PARSE_NODE_STRUCT_KIND (pns0 ) == PN_for_stmt ) {
1826+ // async for
1827+ compile_async_for_stmt (comp , pns0 );
1828+ } else {
1829+ // async with
1830+ assert (MP_PARSE_NODE_STRUCT_KIND (pns0 ) == PN_with_stmt );
1831+ compile_async_with_stmt (comp , pns0 );
1832+ }
1833+ }
1834+ #endif
1835+
16641836STATIC void compile_expr_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
16651837 if (MP_PARSE_NODE_IS_NULL (pns -> nodes [1 ])) {
16661838 if (comp -> is_repl && comp -> scope_cur -> kind == SCOPE_MODULE ) {
@@ -1967,15 +2139,16 @@ STATIC void compile_factor_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
19672139 }
19682140}
19692141
1970- STATIC void compile_power (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2142+ STATIC void compile_atom_expr_normal (compiler_t * comp , mp_parse_node_struct_t * pns ) {
19712143 // this is to handle special super() call
19722144 comp -> func_arg_is_super = MP_PARSE_NODE_IS_ID (pns -> nodes [0 ]) && MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]) == MP_QSTR_super ;
19732145
19742146 compile_generic_all_nodes (comp , pns );
2147+ }
19752148
1976- if (! MP_PARSE_NODE_IS_NULL ( pns -> nodes [ 2 ]) ) {
1977- EMIT_ARG ( binary_op , MP_BINARY_OP_POWER );
1978- }
2149+ STATIC void compile_power ( compiler_t * comp , mp_parse_node_struct_t * pns ) {
2150+ compile_generic_all_nodes ( comp , pns ); // 2 nodes, arguments of power
2151+ EMIT_ARG ( binary_op , MP_BINARY_OP_POWER );
19792152}
19802153
19812154STATIC void compile_trailer_paren_helper (compiler_t * comp , mp_parse_node_t pn_arglist , bool is_method_call , int n_positional_extra ) {
@@ -2076,7 +2249,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
20762249 }
20772250}
20782251
2079- STATIC void compile_power_trailers (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2252+ STATIC void compile_atom_expr_trailers (compiler_t * comp , mp_parse_node_struct_t * pns ) {
20802253 int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
20812254 for (int i = 0 ; i < num_nodes ; i ++ ) {
20822255 if (i + 1 < num_nodes && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [i ], PN_trailer_period ) && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [i + 1 ], PN_trailer_paren )) {
@@ -2431,15 +2604,24 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
24312604 } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [0 ], PN_yield_arg_from )) {
24322605 pns = (mp_parse_node_struct_t * )pns -> nodes [0 ];
24332606 compile_node (comp , pns -> nodes [0 ]);
2434- EMIT (get_iter );
2435- EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE );
2436- EMIT (yield_from );
2607+ compile_yield_from (comp );
24372608 } else {
24382609 compile_node (comp , pns -> nodes [0 ]);
24392610 EMIT (yield_value );
24402611 }
24412612}
24422613
2614+ #if MICROPY_PY_ASYNC_AWAIT
2615+ STATIC void compile_atom_expr_await (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2616+ if (comp -> scope_cur -> kind != SCOPE_FUNCTION && comp -> scope_cur -> kind != SCOPE_LAMBDA ) {
2617+ compile_syntax_error (comp , (mp_parse_node_t )pns , "'await' outside function" );
2618+ return ;
2619+ }
2620+ compile_atom_expr_normal (comp , pns );
2621+ compile_yield_from (comp );
2622+ }
2623+ #endif
2624+
24432625STATIC void compile_string (compiler_t * comp , mp_parse_node_struct_t * pns ) {
24442626 // only create and load the actual str object on the last pass
24452627 if (comp -> pass != MP_PASS_EMIT ) {
@@ -2995,7 +3177,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
29953177 goto not_an_instruction ;
29963178 }
29973179 pns2 = (mp_parse_node_struct_t * )pns2 -> nodes [0 ];
2998- if (MP_PARSE_NODE_STRUCT_KIND (pns2 ) != PN_power ) {
3180+ if (MP_PARSE_NODE_STRUCT_KIND (pns2 ) != PN_atom_expr_normal ) {
29993181 goto not_an_instruction ;
30003182 }
30013183 if (!MP_PARSE_NODE_IS_ID (pns2 -> nodes [0 ])) {
0 commit comments