From d5e5a2aa284d610b2bf1fb948c0e8da348ad2733 Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Sun, 12 Aug 2001 01:54:38 +0000 Subject: [PATCH] SF Patch [ 429024 ] deal with some unary ops at compile time Revised version of Fred's patch, including support for ~ operator. If the unary +, -, or ~ operator is applied to a constant, don't generate a UNARY_xxx opcode. Just store the approriate value as a constant. If the value is negative, extend the string containing the constant and insert a negative in the 0th position. For ~, compute the inverse of int and longs and use them directly, but be prepared to generate code for all other possibilities (invalid numbers, floats, complex). --- Python/compile.c | 69 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/Python/compile.c b/Python/compile.c index 18f6c71f047..9a2d50b0b5c 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1839,19 +1839,82 @@ com_power(struct compiling *c, node *n) } } +static void +com_invert_constant(struct compiling *c, node *n) +{ + /* Compute the inverse of int and longs and use them directly, + but be prepared to generate code for all other + possibilities (invalid numbers, floats, complex). + */ + PyObject *num, *inv = NULL; + int i; + + REQ(n, NUMBER); + num = parsenumber(c, STR(n)); + if (num == NULL) + i = 255; + else { + inv = PyNumber_Invert(num); + if (inv == NULL) { + PyErr_Clear(); + i = com_addconst(c, num); + } else { + i = com_addconst(c, inv); + Py_DECREF(inv); + } + Py_DECREF(num); + } + com_addoparg(c, LOAD_CONST, i); + com_push(c, 1); + if (num != NULL && inv == NULL) + com_addbyte(c, UNARY_INVERT); +} + static void com_factor(struct compiling *c, node *n) { + int childtype = TYPE(CHILD(n, 0)); REQ(n, factor); - if (TYPE(CHILD(n, 0)) == PLUS) { + /* If the unary +, -, or ~ operator is applied to a constant, + don't generate a UNARY_xxx opcode. Just store the + approriate value as a constant. If the value is negative, + extend the string containing the constant and insert a + negative in the 0th position. + */ + if ((childtype == PLUS || childtype == MINUS || childtype == TILDE) + && TYPE(CHILD(n, 1)) == factor + && TYPE(CHILD(CHILD(n, 1), 0)) == power + && TYPE(CHILD(CHILD(CHILD(n, 1), 0), 0)) == atom + && TYPE(CHILD(CHILD(CHILD(CHILD(n, 1), 0), 0), 0)) == NUMBER) { + node *constant = CHILD(CHILD(CHILD(n, 1), 0), 0); + if (childtype == TILDE) { + com_invert_constant(c, CHILD(constant, 0)); + return; + } + if (childtype == MINUS) { + node *numnode = CHILD(constant, 0); + char *s = malloc(strlen(STR(numnode)) + 2); + if (s == NULL) { + com_error(c, PyExc_MemoryError, ""); + com_addbyte(c, 255); + return; + } + s[0] = '-'; + strcpy(s + 1, STR(numnode)); + free(STR(numnode)); + STR(numnode) = s; + } + com_atom(c, constant); + } + else if (childtype == PLUS) { com_factor(c, CHILD(n, 1)); com_addbyte(c, UNARY_POSITIVE); } - else if (TYPE(CHILD(n, 0)) == MINUS) { + else if (childtype == MINUS) { com_factor(c, CHILD(n, 1)); com_addbyte(c, UNARY_NEGATIVE); } - else if (TYPE(CHILD(n, 0)) == TILDE) { + else if (childtype == TILDE) { com_factor(c, CHILD(n, 1)); com_addbyte(c, UNARY_INVERT); }