diff --git a/py/compile.c b/py/compile.c index f349dca2b3..8a30518b33 100644 --- a/py/compile.c +++ b/py/compile.c @@ -299,14 +299,12 @@ STATIC void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int la if (jump_if == false) { EMIT_ARG(jump, label); } - } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + } else { + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)); // non-empty tuple, acts as true for the condition if (jump_if == true) { EMIT_ARG(jump, label); } - } else { - // parenthesis around 1 item, is just that item - c_if_cond(comp, pns->nodes[0], jump_if, label); } return; } @@ -420,7 +418,6 @@ STATIC void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num // assigns top of stack to pn STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) { - tail_recursion: assert(!MP_PARSE_NODE_IS_NULL(pn)); if (MP_PARSE_NODE_IS_LEAF(pn)) { if (MP_PARSE_NODE_IS_ID(pn)) { @@ -462,16 +459,13 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_ if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // empty tuple goto cannot_assign; - } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + } else { + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)); if (assign_kind != ASSIGN_STORE) { goto bad_aug; } pns = (mp_parse_node_struct_t*)pns->nodes[0]; goto testlist_comp; - } else { - // parenthesis around 1 item, is just that item - pn = pns->nodes[0]; - goto tail_recursion; } break; @@ -885,7 +879,10 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) { } } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) { pn = ((mp_parse_node_struct_t*)pn)->nodes[0]; - if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) { + if (MP_PARSE_NODE_IS_NULL(pn)) { + goto cannot_delete; + } else { + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)); mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp @@ -915,12 +912,9 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) { c_del_stmt(comp, pns->nodes[0]); c_del_stmt(comp, pns->nodes[1]); } - } else { - // tuple with 1 element - c_del_stmt(comp, pn); } } else { - // TODO is there anything else to implement? + // some arbitrary statment that we can't delete (eg del 1) goto cannot_delete; } @@ -2185,7 +2179,8 @@ STATIC void compile_atom_paren(compiler_t *comp, mp_parse_node_struct_t *pns) { if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // an empty tuple c_tuple(comp, MP_PARSE_NODE_NULL, NULL); - } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + } else { + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)); pns = (mp_parse_node_struct_t*)pns->nodes[0]; assert(!MP_PARSE_NODE_IS_NULL(pns->nodes[1])); if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { @@ -2209,9 +2204,6 @@ STATIC void compile_atom_paren(compiler_t *comp, mp_parse_node_struct_t *pns) { tuple_with_2_items: c_tuple(comp, MP_PARSE_NODE_NULL, pns); } - } else { - // parenthesis around a single item, is just that item - compile_node(comp, pns->nodes[0]); } } diff --git a/py/parse.c b/py/parse.c index 1741757646..6de0a0fbee 100644 --- a/py/parse.c +++ b/py/parse.c @@ -647,6 +647,20 @@ STATIC bool fold_constants(parser_t *parser, const rule_t *rule, size_t num_args #endif STATIC void push_result_rule(parser_t *parser, size_t src_line, const rule_t *rule, size_t num_args) { + // optimise away parenthesis around an expression if possible + if (rule->rule_id == RULE_atom_paren) { + // there should be just 1 arg for this rule + mp_parse_node_t pn = peek_result(parser, 0); + if (MP_PARSE_NODE_IS_NULL(pn)) { + // need to keep parenthesis for () + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_testlist_comp)) { + // need to keep parenthesis for (a, b, ...) + } else { + // parenthesis around a single expression, so it's just the expression + return; + } + } + #if MICROPY_COMP_CONST_FOLDING if (fold_constants(parser, rule, num_args)) { // we folded this rule so return straight away @@ -864,8 +878,6 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { // if a rule has the RULE_ACT_ALLOW_IDENT bit set then this // rule should not be emitted if it has only 1 argument - // NOTE: can't set this flag for atom_paren because we need it - // to distinguish, for example, [a,b] from [(a,b)] if (rule->act & RULE_ACT_ALLOW_IDENT) { emit_rule = false; }