py: Don't generate unnecessary parse nodes for assignment or kwargs.
This patch eliminates the need for a nested parse node for assignments and keyword arguments. It saves a little bit of RAM when parsing.
This commit is contained in:
parent
4fb5ff86ee
commit
b948de36fb
50
py/compile.c
50
py/compile.c
@ -156,14 +156,15 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m
|
|||||||
#if MICROPY_COMP_CONST
|
#if MICROPY_COMP_CONST
|
||||||
case PN_expr_stmt:
|
case PN_expr_stmt:
|
||||||
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
|
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
|
||||||
mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
|
if (!(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_expr_stmt_augassign)
|
||||||
if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_expr_stmt_assign) {
|
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_expr_stmt_assign_list))) {
|
||||||
|
// this node is of the form <x> = <y>
|
||||||
if (MP_PARSE_NODE_IS_ID(pns->nodes[0])
|
if (MP_PARSE_NODE_IS_ID(pns->nodes[0])
|
||||||
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_power)
|
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)
|
||||||
&& MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[0])
|
&& MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[0])
|
||||||
&& MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[0]) == MP_QSTR_const
|
&& MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[0]) == MP_QSTR_const
|
||||||
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren)
|
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[1], PN_trailer_paren)
|
||||||
&& MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2])
|
&& MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[2])
|
||||||
) {
|
) {
|
||||||
// code to assign dynamic constants: id = const(value)
|
// code to assign dynamic constants: id = const(value)
|
||||||
|
|
||||||
@ -171,7 +172,7 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m
|
|||||||
qstr id_qstr = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
|
qstr id_qstr = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
|
||||||
|
|
||||||
// get the value
|
// get the value
|
||||||
mp_parse_node_t pn_value = ((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0];
|
mp_parse_node_t pn_value = ((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns->nodes[1])->nodes[1])->nodes[0];
|
||||||
pn_value = fold_constants(comp, pn_value, consts);
|
pn_value = fold_constants(comp, pn_value, consts);
|
||||||
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_value)) {
|
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_value)) {
|
||||||
compile_syntax_error(comp, (mp_parse_node_t)pns, "constant must be an integer");
|
compile_syntax_error(comp, (mp_parse_node_t)pns, "constant must be an integer");
|
||||||
@ -188,7 +189,7 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m
|
|||||||
elem->value = MP_OBJ_NEW_SMALL_INT(value);
|
elem->value = MP_OBJ_NEW_SMALL_INT(value);
|
||||||
|
|
||||||
// replace const(value) with value
|
// replace const(value) with value
|
||||||
pns1->nodes[0] = pn_value;
|
pns->nodes[1] = pn_value;
|
||||||
|
|
||||||
// finished folding this assignment
|
// finished folding this assignment
|
||||||
return pn;
|
return pn;
|
||||||
@ -1885,7 +1886,7 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
|
EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
|
||||||
mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
|
mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
|
||||||
int kind = MP_PARSE_NODE_STRUCT_KIND(pns1);
|
int kind = MP_PARSE_NODE_STRUCT_KIND(pns1);
|
||||||
if (kind == PN_expr_stmt_augassign) {
|
if (kind == PN_expr_stmt_augassign) {
|
||||||
@ -1911,7 +1912,7 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
|
c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
|
||||||
} else if (kind == PN_expr_stmt_assign_list) {
|
} else if (kind == PN_expr_stmt_assign_list) {
|
||||||
int rhs = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
|
int rhs = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
|
||||||
compile_node(comp, ((mp_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
|
compile_node(comp, pns1->nodes[rhs]); // rhs
|
||||||
// following CPython, we store left-most first
|
// following CPython, we store left-most first
|
||||||
if (rhs > 0) {
|
if (rhs > 0) {
|
||||||
EMIT(dup_top);
|
EMIT(dup_top);
|
||||||
@ -1921,17 +1922,17 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
if (i + 1 < rhs) {
|
if (i + 1 < rhs) {
|
||||||
EMIT(dup_top);
|
EMIT(dup_top);
|
||||||
}
|
}
|
||||||
c_assign(comp, ((mp_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
|
c_assign(comp, pns1->nodes[i], ASSIGN_STORE); // middle store
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(kind == PN_expr_stmt_assign); // should be
|
plain_assign:
|
||||||
if (MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
|
if (MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
|
||||||
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
|
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
|
||||||
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
|
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
|
||||||
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns1->nodes[0]) == 2
|
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 2
|
||||||
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 2) {
|
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 2) {
|
||||||
// optimisation for a, b = c, d
|
// optimisation for a, b = c, d
|
||||||
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns1->nodes[0];
|
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns->nodes[1];
|
||||||
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
|
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
|
||||||
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
|
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
|
||||||
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)) {
|
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)) {
|
||||||
@ -1944,12 +1945,12 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
|
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
|
||||||
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
|
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
|
||||||
} else if (MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
|
} else if (MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
|
||||||
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
|
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
|
||||||
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
|
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
|
||||||
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns1->nodes[0]) == 3
|
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 3
|
||||||
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 3) {
|
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 3) {
|
||||||
// optimisation for a, b, c = d, e, f
|
// optimisation for a, b, c = d, e, f
|
||||||
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns1->nodes[0];
|
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns->nodes[1];
|
||||||
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
|
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
|
||||||
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
|
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
|
||||||
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
|
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
|
||||||
@ -1967,10 +1968,12 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
|
c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
|
||||||
} else {
|
} else {
|
||||||
no_optimisation:
|
no_optimisation:
|
||||||
compile_node(comp, pns1->nodes[0]); // rhs
|
compile_node(comp, pns->nodes[1]); // rhs
|
||||||
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
|
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
goto plain_assign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2228,18 +2231,15 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
|
|||||||
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
|
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
|
||||||
dblstar_args_node = pns_arg;
|
dblstar_args_node = pns_arg;
|
||||||
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
|
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
|
||||||
assert(MP_PARSE_NODE_IS_STRUCT(pns_arg->nodes[1])); // should always be
|
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns_arg->nodes[1], PN_comp_for)) {
|
||||||
mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns_arg->nodes[1];
|
|
||||||
if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
|
|
||||||
if (!MP_PARSE_NODE_IS_ID(pns_arg->nodes[0])) {
|
if (!MP_PARSE_NODE_IS_ID(pns_arg->nodes[0])) {
|
||||||
compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "LHS of keyword arg must be an id");
|
compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "LHS of keyword arg must be an id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0]));
|
EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0]));
|
||||||
compile_node(comp, pns2->nodes[0]);
|
compile_node(comp, pns_arg->nodes[1]);
|
||||||
n_keyword += 1;
|
n_keyword += 1;
|
||||||
} else {
|
} else {
|
||||||
assert(MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for); // should always be
|
|
||||||
compile_comprehension(comp, pns_arg, SCOPE_GEN_EXPR);
|
compile_comprehension(comp, pns_arg, SCOPE_GEN_EXPR);
|
||||||
n_positional++;
|
n_positional++;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ DEF_RULE(expr_stmt, c(expr_stmt), and(2), rule(testlist_star_expr), opt_rule(exp
|
|||||||
DEF_RULE(expr_stmt_2, nc, or(2), rule(expr_stmt_augassign), rule(expr_stmt_assign_list))
|
DEF_RULE(expr_stmt_2, nc, or(2), rule(expr_stmt_augassign), rule(expr_stmt_assign_list))
|
||||||
DEF_RULE(expr_stmt_augassign, nc, and(2), rule(augassign), rule(expr_stmt_6))
|
DEF_RULE(expr_stmt_augassign, nc, and(2), rule(augassign), rule(expr_stmt_6))
|
||||||
DEF_RULE(expr_stmt_assign_list, nc, one_or_more, rule(expr_stmt_assign))
|
DEF_RULE(expr_stmt_assign_list, nc, one_or_more, rule(expr_stmt_assign))
|
||||||
DEF_RULE(expr_stmt_assign, nc, and(2), tok(DEL_EQUAL), rule(expr_stmt_6))
|
DEF_RULE(expr_stmt_assign, nc, ident | and(2), tok(DEL_EQUAL), rule(expr_stmt_6))
|
||||||
DEF_RULE(expr_stmt_6, nc, or(2), rule(yield_expr), rule(testlist_star_expr))
|
DEF_RULE(expr_stmt_6, nc, or(2), rule(yield_expr), rule(testlist_star_expr))
|
||||||
DEF_RULE(testlist_star_expr, c(generic_tuple), list_with_end, rule(testlist_star_expr_2), tok(DEL_COMMA))
|
DEF_RULE(testlist_star_expr, c(generic_tuple), list_with_end, rule(testlist_star_expr_2), tok(DEL_COMMA))
|
||||||
DEF_RULE(testlist_star_expr_2, nc, or(2), rule(star_expr), rule(test))
|
DEF_RULE(testlist_star_expr_2, nc, or(2), rule(star_expr), rule(test))
|
||||||
@ -322,7 +322,7 @@ DEF_RULE(arglist_dbl_star, nc, and(2), tok(OP_DBL_STAR), rule(test))
|
|||||||
|
|
||||||
DEF_RULE(argument, nc, and(2), rule(test), opt_rule(argument_2))
|
DEF_RULE(argument, nc, and(2), rule(test), opt_rule(argument_2))
|
||||||
DEF_RULE(argument_2, nc, or(2), rule(comp_for), rule(argument_3))
|
DEF_RULE(argument_2, nc, or(2), rule(comp_for), rule(argument_3))
|
||||||
DEF_RULE(argument_3, nc, and(2), tok(DEL_EQUAL), rule(test))
|
DEF_RULE(argument_3, nc, ident | and(2), tok(DEL_EQUAL), rule(test))
|
||||||
DEF_RULE(comp_iter, nc, or(2), rule(comp_for), rule(comp_if))
|
DEF_RULE(comp_iter, nc, or(2), rule(comp_for), rule(comp_if))
|
||||||
DEF_RULE(comp_for, nc, blank | and(5), tok(KW_FOR), rule(exprlist), tok(KW_IN), rule(or_test), opt_rule(comp_iter))
|
DEF_RULE(comp_for, nc, blank | and(5), tok(KW_FOR), rule(exprlist), tok(KW_IN), rule(or_test), opt_rule(comp_iter))
|
||||||
DEF_RULE(comp_if, nc, and(3), tok(KW_IF), rule(test_nocond), opt_rule(comp_iter))
|
DEF_RULE(comp_if, nc, and(3), tok(KW_IF), rule(test_nocond), opt_rule(comp_iter))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user