summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/compile.c30
-rw-r--r--py/parse.c16
2 files changed, 25 insertions, 21 deletions
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;
}