@@ -115,7 +115,6 @@ typedef struct _compiler_t {
115115
116116 uint8_t is_repl ;
117117 uint8_t pass ; // holds enum type pass_kind_t
118- uint8_t func_arg_is_super ; // used to compile special case of super() function call
119118 uint8_t have_star ;
120119
121120 // try to keep compiler clean from nlr
@@ -762,7 +761,6 @@ STATIC qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pn
762761 if (MP_PARSE_NODE_IS_STRUCT_KIND (parents , PN_classdef_2 )) {
763762 parents = MP_PARSE_NODE_NULL ;
764763 }
765- comp -> func_arg_is_super = false;
766764 compile_trailer_paren_helper (comp , parents , false, 2 );
767765
768766 // return its name (the 'C' in class C(...):")
@@ -836,7 +834,6 @@ STATIC void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
836834 // nodes[1] contains arguments to the decorator function, if any
837835 if (!MP_PARSE_NODE_IS_NULL (pns_decorator -> nodes [1 ])) {
838836 // call the decorator function with the arguments in nodes[1]
839- comp -> func_arg_is_super = false;
840837 compile_node (comp , pns_decorator -> nodes [1 ]);
841838 }
842839 }
@@ -2175,36 +2172,83 @@ STATIC void compile_factor_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
21752172}
21762173
21772174STATIC void compile_atom_expr_normal (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2178- // this is to handle special super() call
2179- comp -> func_arg_is_super = MP_PARSE_NODE_IS_ID ( pns -> nodes [0 ]) && MP_PARSE_NODE_LEAF_ARG ( pns -> nodes [ 0 ]) == MP_QSTR_super ;
2175+ // compile the subject of the expression
2176+ compile_node ( comp , pns -> nodes [0 ]);
21802177
2181- compile_generic_all_nodes (comp , pns );
2182- }
2178+ // compile_atom_expr_await may call us with a NULL node
2179+ if (MP_PARSE_NODE_IS_NULL (pns -> nodes [1 ])) {
2180+ return ;
2181+ }
21832182
2184- STATIC void compile_power (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2185- compile_generic_all_nodes (comp , pns ); // 2 nodes, arguments of power
2186- EMIT_ARG (binary_op , MP_BINARY_OP_POWER );
2187- }
2183+ // get the array of trailers (known to be an array of PARSE_NODE_STRUCT)
2184+ size_t num_trail = 1 ;
2185+ mp_parse_node_struct_t * * pns_trail = (mp_parse_node_struct_t * * )& pns -> nodes [1 ];
2186+ if (MP_PARSE_NODE_STRUCT_KIND (pns_trail [0 ]) == PN_atom_expr_trailers ) {
2187+ num_trail = MP_PARSE_NODE_STRUCT_NUM_NODES (pns_trail [0 ]);
2188+ pns_trail = (mp_parse_node_struct_t * * )& pns_trail [0 ]-> nodes [0 ];
2189+ }
21882190
2189- STATIC void compile_trailer_paren_helper ( compiler_t * comp , mp_parse_node_t pn_arglist , bool is_method_call , int n_positional_extra ) {
2190- // function to call is on top of stack
2191+ // the current index into the array of trailers
2192+ size_t i = 0 ;
21912193
2192- // this is to handle special super() call
2193- if (MP_PARSE_NODE_IS_NULL (pn_arglist ) && comp -> func_arg_is_super && comp -> scope_cur -> kind == SCOPE_FUNCTION ) {
2194+ // handle special super() call
2195+ if (comp -> scope_cur -> kind == SCOPE_FUNCTION
2196+ && MP_PARSE_NODE_IS_ID (pns -> nodes [0 ])
2197+ && MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]) == MP_QSTR_super
2198+ && MP_PARSE_NODE_STRUCT_KIND (pns_trail [0 ]) == PN_trailer_paren
2199+ && MP_PARSE_NODE_IS_NULL (pns_trail [0 ]-> nodes [0 ])) {
2200+ // at this point we have matched "super()" within a function
2201+
2202+ // load the class for super to search for a parent
21942203 compile_load_id (comp , MP_QSTR___class__ );
2204+
21952205 // look for first argument to function (assumes it's "self")
2196- for (int i = 0 ; i < comp -> scope_cur -> id_info_len ; i ++ ) {
2197- id_info_t * id = & comp -> scope_cur -> id_info [i ];
2206+ bool found = false;
2207+ id_info_t * id = & comp -> scope_cur -> id_info [0 ];
2208+ for (size_t n = comp -> scope_cur -> id_info_len ; n > 0 ; -- n , ++ id ) {
21982209 if (id -> flags & ID_FLAG_IS_PARAM ) {
2199- // first argument found; load it and call super
2210+ // first argument found; load it
22002211 compile_load_id (comp , id -> qst );
2201- EMIT_ARG ( call_function , 2 , 0 , 0 ) ;
2202- return ;
2212+ found = true ;
2213+ break ;
22032214 }
22042215 }
2205- compile_syntax_error (comp , MP_PARSE_NODE_NULL , "super() call cannot find self" ); // really a TypeError
2206- return ;
2216+ if (!found ) {
2217+ compile_syntax_error (comp , (mp_parse_node_t )pns_trail [0 ],
2218+ "super() can't find self" ); // really a TypeError
2219+ return ;
2220+ }
2221+
2222+ // a super() call
2223+ EMIT_ARG (call_function , 2 , 0 , 0 );
2224+ i = 1 ;
2225+ }
2226+
2227+ // compile the remaining trailers
2228+ for (; i < num_trail ; i ++ ) {
2229+ if (i + 1 < num_trail
2230+ && MP_PARSE_NODE_STRUCT_KIND (pns_trail [i ]) == PN_trailer_period
2231+ && MP_PARSE_NODE_STRUCT_KIND (pns_trail [i + 1 ]) == PN_trailer_paren ) {
2232+ // optimisation for method calls a.f(...), following PyPy
2233+ mp_parse_node_struct_t * pns_period = pns_trail [i ];
2234+ mp_parse_node_struct_t * pns_paren = pns_trail [i + 1 ];
2235+ EMIT_ARG (load_method , MP_PARSE_NODE_LEAF_ARG (pns_period -> nodes [0 ]));
2236+ compile_trailer_paren_helper (comp , pns_paren -> nodes [0 ], true, 0 );
2237+ i += 1 ;
2238+ } else {
2239+ // node is one of: trailer_paren, trailer_bracket, trailer_period
2240+ compile_node (comp , (mp_parse_node_t )pns_trail [i ]);
2241+ }
22072242 }
2243+ }
2244+
2245+ STATIC void compile_power (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2246+ compile_generic_all_nodes (comp , pns ); // 2 nodes, arguments of power
2247+ EMIT_ARG (binary_op , MP_BINARY_OP_POWER );
2248+ }
2249+
2250+ STATIC void compile_trailer_paren_helper (compiler_t * comp , mp_parse_node_t pn_arglist , bool is_method_call , int n_positional_extra ) {
2251+ // function to call is on top of stack
22082252
22092253 // get the list of arguments
22102254 mp_parse_node_t * args ;
@@ -2285,23 +2329,6 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
22852329 }
22862330}
22872331
2288- STATIC void compile_atom_expr_trailers (compiler_t * comp , mp_parse_node_struct_t * pns ) {
2289- int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
2290- for (int i = 0 ; i < num_nodes ; i ++ ) {
2291- 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 )) {
2292- // optimisation for method calls a.f(...), following PyPy
2293- mp_parse_node_struct_t * pns_period = (mp_parse_node_struct_t * )pns -> nodes [i ];
2294- mp_parse_node_struct_t * pns_paren = (mp_parse_node_struct_t * )pns -> nodes [i + 1 ];
2295- EMIT_ARG (load_method , MP_PARSE_NODE_LEAF_ARG (pns_period -> nodes [0 ])); // get the method
2296- compile_trailer_paren_helper (comp , pns_paren -> nodes [0 ], true, 0 );
2297- i += 1 ;
2298- } else {
2299- compile_node (comp , pns -> nodes [i ]);
2300- }
2301- comp -> func_arg_is_super = false;
2302- }
2303- }
2304-
23052332// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
23062333STATIC void compile_comprehension (compiler_t * comp , mp_parse_node_struct_t * pns , scope_kind_t kind ) {
23072334 assert (MP_PARSE_NODE_STRUCT_NUM_NODES (pns ) == 2 );
0 commit comments