Skip to content

Commit 0288cf0

Browse files
committed
py: Implement compiling of *-expr within parenthesis.
1 parent a5c82a8 commit 0288cf0

2 files changed

Lines changed: 46 additions & 26 deletions

File tree

py/compile.c

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -666,28 +666,42 @@ void c_assign_power(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t
666666
compile_syntax_error(comp, (mp_parse_node_t)pns, "can't assign to expression");
667667
}
668668

669-
void c_assign_tuple(compiler_t *comp, int n, mp_parse_node_t *nodes) {
670-
assert(n >= 0);
669+
// we need to allow for a caller passing in 1 initial node (node_head) followed by an array of nodes (nodes_tail)
670+
void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num_tail, mp_parse_node_t *nodes_tail) {
671+
uint num_head = (node_head == MP_PARSE_NODE_NULL) ? 0 : 1;
672+
673+
// look for star expression
671674
int have_star_index = -1;
672-
for (int i = 0; i < n; i++) {
673-
if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
675+
if (num_head != 0 && MP_PARSE_NODE_IS_STRUCT_KIND(node_head, PN_star_expr)) {
676+
EMIT_ARG(unpack_ex, 0, num_tail);
677+
have_star_index = 0;
678+
}
679+
for (int i = 0; i < num_tail; i++) {
680+
if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes_tail[i], PN_star_expr)) {
674681
if (have_star_index < 0) {
675-
EMIT_ARG(unpack_ex, i, n - i - 1);
676-
have_star_index = i;
682+
EMIT_ARG(unpack_ex, num_head + i, num_tail - i - 1);
683+
have_star_index = num_head + i;
677684
} else {
678-
compile_syntax_error(comp, nodes[i], "two starred expressions in assignment");
685+
compile_syntax_error(comp, nodes_tail[i], "two starred expressions in assignment");
679686
return;
680687
}
681688
}
682689
}
683690
if (have_star_index < 0) {
684-
EMIT_ARG(unpack_sequence, n);
691+
EMIT_ARG(unpack_sequence, num_head + num_tail);
685692
}
686-
for (int i = 0; i < n; i++) {
687-
if (i == have_star_index) {
688-
c_assign(comp, ((mp_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
693+
if (num_head != 0) {
694+
if (0 == have_star_index) {
695+
c_assign(comp, ((mp_parse_node_struct_t*)node_head)->nodes[0], ASSIGN_STORE);
689696
} else {
690-
c_assign(comp, nodes[i], ASSIGN_STORE);
697+
c_assign(comp, node_head, ASSIGN_STORE);
698+
}
699+
}
700+
for (int i = 0; i < num_tail; i++) {
701+
if (num_head + i == have_star_index) {
702+
c_assign(comp, ((mp_parse_node_struct_t*)nodes_tail[i])->nodes[0], ASSIGN_STORE);
703+
} else {
704+
c_assign(comp, nodes_tail[i], ASSIGN_STORE);
691705
}
692706
}
693707
}
@@ -727,7 +741,7 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
727741
if (assign_kind != ASSIGN_STORE) {
728742
goto bad_aug;
729743
}
730-
c_assign_tuple(comp, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
744+
c_assign_tuple(comp, MP_PARSE_NODE_NULL, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
731745
break;
732746

733747
case PN_atom_paren:
@@ -753,13 +767,13 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
753767
}
754768
if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
755769
// empty list, assignment allowed
756-
c_assign_tuple(comp, 0, NULL);
770+
c_assign_tuple(comp, MP_PARSE_NODE_NULL, 0, NULL);
757771
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
758772
pns = (mp_parse_node_struct_t*)pns->nodes[0];
759773
goto testlist_comp;
760774
} else {
761775
// brackets around 1 item
762-
c_assign_tuple(comp, 1, &pns->nodes[0]);
776+
c_assign_tuple(comp, pns->nodes[0], 0, NULL);
763777
}
764778
break;
765779

@@ -776,16 +790,11 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
776790
if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
777791
// sequence of one item, with trailing comma
778792
assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[0]));
779-
c_assign_tuple(comp, 1, &pns->nodes[0]);
793+
c_assign_tuple(comp, pns->nodes[0], 0, NULL);
780794
} else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
781795
// sequence of many items
782-
// TODO call c_assign_tuple instead
783-
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns2);
784-
EMIT_ARG(unpack_sequence, 1 + n);
785-
c_assign(comp, pns->nodes[0], ASSIGN_STORE);
786-
for (int i = 0; i < n; i++) {
787-
c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
788-
}
796+
uint n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns2);
797+
c_assign_tuple(comp, pns->nodes[0], n, pns2->nodes);
789798
} else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
790799
// TODO can we ever get here? can it be compiled?
791800
compile_syntax_error(comp, (mp_parse_node_t)pns, "can't assign to expression");
@@ -797,7 +806,7 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
797806
} else {
798807
// sequence with 2 items
799808
sequence_with_2_items:
800-
c_assign_tuple(comp, 2, pns->nodes);
809+
c_assign_tuple(comp, MP_PARSE_NODE_NULL, 2, pns->nodes);
801810
}
802811
return;
803812
}

tests/bytecode/mp-tests/assign2.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,16 @@
66
[*a] = b
77
[*a,] = b
88
[a, *b] = c
9-
#[a, *b,] = c
10-
#[a, *b, c] = d
9+
[a, *b,] = c
10+
[a, *b, c] = d
11+
12+
(*a,) = x
13+
(*a, b) = x
14+
(a, *b) = x
15+
(*a, b, c) = x
16+
(a, *b, c) = x
17+
(a, b, *c) = x
18+
(*a, b, c, d) = x
19+
(a, *b, c, d) = x
20+
(a, b, *c, d) = x
21+
(a, b, c, *d) = x

0 commit comments

Comments
 (0)