summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2000-08-21 17:07:20 (GMT)
committerBarry Warsaw <barry@python.org>2000-08-21 17:07:20 (GMT)
commit24703a02e737134ee71368d891d5170500885db7 (patch)
tree94d96935d87b0135342dff5f153525f56f10d68b /Python/compile.c
parent62c53ddabef25f3dd4fa2019ee998a3f4189a3bd (diff)
downloadcpython-24703a02e737134ee71368d891d5170500885db7.zip
cpython-24703a02e737134ee71368d891d5170500885db7.tar.gz
cpython-24703a02e737134ee71368d891d5170500885db7.tar.bz2
com_print_stmt(): Guido rightly points out that the stream expression
in extended prints should only be evaluated once. This patch plays stack games (documented!) to fix this.
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/Python/compile.c b/Python/compile.c
index b7ce770..e09204e 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -2055,6 +2055,9 @@ com_print_stmt(struct compiling *c, node *n)
/* are we using the extended print form? */
if (NCH(n) >= 2 && TYPE(CHILD(n, 1)) == RIGHTSHIFT) {
stream = CHILD(n, 2);
+ com_node(c, stream);
+ /* stack: [...] => [... stream] */
+ com_push(c, 1);
if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == COMMA)
i = 4;
else
@@ -2062,24 +2065,38 @@ com_print_stmt(struct compiling *c, node *n)
}
for (; i < NCH(n); i += 2) {
if (stream != NULL) {
- /* stack: [...] => [... obj stream] */
+ com_addbyte(c, DUP_TOP);
+ /* stack: [stream] => [stream stream] */
+ com_push(c, 1);
com_node(c, CHILD(n, i));
- com_node(c, stream);
+ /* stack: [stream stream] => [stream stream obj] */
+ com_addbyte(c, ROT_TWO);
+ /* stack: [stream stream obj] => [stream obj stream] */
com_addbyte(c, PRINT_ITEM_TO);
+ /* stack: [stream obj stream] => [stream] */
com_pop(c, 2);
}
else {
- /* stack: [...] => [... obj] */
com_node(c, CHILD(n, i));
+ /* stack: [...] => [... obj] */
com_addbyte(c, PRINT_ITEM);
com_pop(c, 1);
}
}
/* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
- if (TYPE(CHILD(n, NCH(n)-1)) != COMMA) {
+ if (TYPE(CHILD(n, NCH(n)-1)) == COMMA) {
+ if (stream != NULL) {
+ /* must pop the extra stream object off the stack */
+ com_addbyte(c, POP_TOP);
+ /* stack: [... stream] => [...] */
+ com_pop(c, 1);
+ }
+ }
+ else {
if (stream != NULL) {
- com_node(c, stream);
+ /* this consumes the last stream object on stack */
com_addbyte(c, PRINT_NEWLINE_TO);
+ /* stack: [... stream] => [...] */
com_pop(c, 1);
}
else