@ -115,7 +115,6 @@ typedef struct _compiler_t {
uint8_t is_repl ;
uint8_t pass ; // holds enum type pass_kind_t
uint8_t func_arg_is_super ; // used to compile special case of super() function call
uint8_t have_star ;
// 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
if ( MP_PARSE_NODE_IS_STRUCT_KIND ( parents , PN_classdef_2 ) ) {
parents = MP_PARSE_NODE_NULL ;
}
comp - > func_arg_is_super = false ;
compile_trailer_paren_helper ( comp , parents , false , 2 ) ;
// 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) {
// nodes[1] contains arguments to the decorator function, if any
if ( ! MP_PARSE_NODE_IS_NULL ( pns_decorator - > nodes [ 1 ] ) ) {
// call the decorator function with the arguments in nodes[1]
comp - > func_arg_is_super = false ;
compile_node ( comp , pns_decorator - > nodes [ 1 ] ) ;
}
}
@ -2175,36 +2172,83 @@ STATIC void compile_factor_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
STATIC void compile_atom_expr_normal ( compiler_t * comp , mp_parse_node_struct_t * pns ) {
// this is to handle special super() call
comp - > func_arg_is_super = MP_PARSE_NODE_IS_ID ( pns - > nodes [ 0 ] ) & & MP_PARSE_NODE_LEAF_ARG ( pns - > nodes [ 0 ] ) = = MP_QSTR_super ;
// compile the subject of the expression
compile_node ( comp , pns - > nodes [ 0 ] ) ;
compile_generic_all_nodes ( comp , pns ) ;
}
// compile_atom_expr_await may call us with a NULL node
if ( MP_PARSE_NODE_IS_NULL ( pns - > nodes [ 1 ] ) ) {
return ;
}
STATIC void compile_power ( compiler_t * comp , mp_parse_node_struct_t * pns ) {
compile_generic_all_nodes ( comp , pns ) ; // 2 nodes, arguments of power
EMIT_ARG ( binary_op , MP_BINARY_OP_POWER ) ;
}
// get the array of trailers (known to be an array of PARSE_NODE_STRUCT)
size_t num_trail = 1 ;
mp_parse_node_struct_t * * pns_trail = ( mp_parse_node_struct_t * * ) & pns - > nodes [ 1 ] ;
if ( MP_PARSE_NODE_STRUCT_KIND ( pns_trail [ 0 ] ) = = PN_atom_expr_trailers ) {
num_trail = MP_PARSE_NODE_STRUCT_NUM_NODES ( pns_trail [ 0 ] ) ;
pns_trail = ( mp_parse_node_struct_t * * ) & pns_trail [ 0 ] - > nodes [ 0 ] ;
}
STATIC void compile_trailer_paren_helper ( compiler_t * comp , mp_parse_node_t pn_arglist , bool is_method_call , int n_positional_extra ) {
// function to call is on top of stack
// the current index into the array of trailers
size_t i = 0 ;
// this is to handle special super() call
if ( MP_PARSE_NODE_IS_NULL ( pn_arglist ) & & comp - > func_arg_is_super & & comp - > scope_cur - > kind = = SCOPE_FUNCTION ) {
// handle special super() call
if ( comp - > scope_cur - > kind = = SCOPE_FUNCTION
& & MP_PARSE_NODE_IS_ID ( pns - > nodes [ 0 ] )
& & MP_PARSE_NODE_LEAF_ARG ( pns - > nodes [ 0 ] ) = = MP_QSTR_super
& & MP_PARSE_NODE_STRUCT_KIND ( pns_trail [ 0 ] ) = = PN_trailer_paren
& & MP_PARSE_NODE_IS_NULL ( pns_trail [ 0 ] - > nodes [ 0 ] ) ) {
// at this point we have matched "super()" within a function
// load the class for super to search for a parent
compile_load_id ( comp , MP_QSTR___class__ ) ;
// look for first argument to function (assumes it's "self")
for ( int i = 0 ; i < comp - > scope_cur - > id_info_len ; i + + ) {
id_info_t * id = & comp - > scope_cur - > id_info [ i ] ;
bool found = false ;
id_info_t * id = & comp - > scope_cur - > id_info [ 0 ] ;
for ( size_t n = comp - > scope_cur - > id_info_len ; n > 0 ; - - n , + + id ) {
if ( id - > flags & ID_FLAG_IS_PARAM ) {
// first argument found; load it and call super
// first argument found; load it
compile_load_id ( comp , id - > qst ) ;
EMIT_ARG ( call_function , 2 , 0 , 0 ) ;
return ;
found = true ;
break ;
}
}
compile_syntax_error ( comp , MP_PARSE_NODE_NULL , " super() call cannot find self " ) ; // really a TypeError
return ;
if ( ! found ) {
compile_syntax_error ( comp , ( mp_parse_node_t ) pns_trail [ 0 ] ,
" super() can't find self " ) ; // really a TypeError
return ;
}
// a super() call
EMIT_ARG ( call_function , 2 , 0 , 0 ) ;
i = 1 ;
}
// compile the remaining trailers
for ( ; i < num_trail ; i + + ) {
if ( i + 1 < num_trail
& & MP_PARSE_NODE_STRUCT_KIND ( pns_trail [ i ] ) = = PN_trailer_period
& & MP_PARSE_NODE_STRUCT_KIND ( pns_trail [ i + 1 ] ) = = PN_trailer_paren ) {
// optimisation for method calls a.f(...), following PyPy
mp_parse_node_struct_t * pns_period = pns_trail [ i ] ;
mp_parse_node_struct_t * pns_paren = pns_trail [ i + 1 ] ;
EMIT_ARG ( load_method , MP_PARSE_NODE_LEAF_ARG ( pns_period - > nodes [ 0 ] ) ) ;
compile_trailer_paren_helper ( comp , pns_paren - > nodes [ 0 ] , true , 0 ) ;
i + = 1 ;
} else {
// node is one of: trailer_paren, trailer_bracket, trailer_period
compile_node ( comp , ( mp_parse_node_t ) pns_trail [ i ] ) ;
}
}
}
STATIC void compile_power ( compiler_t * comp , mp_parse_node_struct_t * pns ) {
compile_generic_all_nodes ( comp , pns ) ; // 2 nodes, arguments of power
EMIT_ARG ( binary_op , MP_BINARY_OP_POWER ) ;
}
STATIC void compile_trailer_paren_helper ( compiler_t * comp , mp_parse_node_t pn_arglist , bool is_method_call , int n_positional_extra ) {
// function to call is on top of stack
// get the list of arguments
mp_parse_node_t * args ;
@ -2285,23 +2329,6 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
}
}
STATIC void compile_atom_expr_trailers ( compiler_t * comp , mp_parse_node_struct_t * pns ) {
int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES ( pns ) ;
for ( int i = 0 ; i < num_nodes ; i + + ) {
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 ) ) {
// optimisation for method calls a.f(...), following PyPy
mp_parse_node_struct_t * pns_period = ( mp_parse_node_struct_t * ) pns - > nodes [ i ] ;
mp_parse_node_struct_t * pns_paren = ( mp_parse_node_struct_t * ) pns - > nodes [ i + 1 ] ;
EMIT_ARG ( load_method , MP_PARSE_NODE_LEAF_ARG ( pns_period - > nodes [ 0 ] ) ) ; // get the method
compile_trailer_paren_helper ( comp , pns_paren - > nodes [ 0 ] , true , 0 ) ;
i + = 1 ;
} else {
compile_node ( comp , pns - > nodes [ i ] ) ;
}
comp - > func_arg_is_super = false ;
}
}
// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
STATIC void compile_comprehension ( compiler_t * comp , mp_parse_node_struct_t * pns , scope_kind_t kind ) {
assert ( MP_PARSE_NODE_STRUCT_NUM_NODES ( pns ) = = 2 ) ;