summaryrefslogtreecommitdiffstatshomepage
path: root/py/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c105
1 files changed, 66 insertions, 39 deletions
diff --git a/py/compile.c b/py/compile.c
index 2110867291..42c2cc3a24 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -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);