Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d5e5a2a

Browse files
committed
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).
1 parent b5b7b78 commit d5e5a2a

1 file changed

Lines changed: 66 additions & 3 deletions

File tree

Python/compile.c

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,19 +1839,82 @@ com_power(struct compiling *c, node *n)
18391839
}
18401840
}
18411841

1842+
static void
1843+
com_invert_constant(struct compiling *c, node *n)
1844+
{
1845+
/* Compute the inverse of int and longs and use them directly,
1846+
but be prepared to generate code for all other
1847+
possibilities (invalid numbers, floats, complex).
1848+
*/
1849+
PyObject *num, *inv = NULL;
1850+
int i;
1851+
1852+
REQ(n, NUMBER);
1853+
num = parsenumber(c, STR(n));
1854+
if (num == NULL)
1855+
i = 255;
1856+
else {
1857+
inv = PyNumber_Invert(num);
1858+
if (inv == NULL) {
1859+
PyErr_Clear();
1860+
i = com_addconst(c, num);
1861+
} else {
1862+
i = com_addconst(c, inv);
1863+
Py_DECREF(inv);
1864+
}
1865+
Py_DECREF(num);
1866+
}
1867+
com_addoparg(c, LOAD_CONST, i);
1868+
com_push(c, 1);
1869+
if (num != NULL && inv == NULL)
1870+
com_addbyte(c, UNARY_INVERT);
1871+
}
1872+
18421873
static void
18431874
com_factor(struct compiling *c, node *n)
18441875
{
1876+
int childtype = TYPE(CHILD(n, 0));
18451877
REQ(n, factor);
1846-
if (TYPE(CHILD(n, 0)) == PLUS) {
1878+
/* If the unary +, -, or ~ operator is applied to a constant,
1879+
don't generate a UNARY_xxx opcode. Just store the
1880+
approriate value as a constant. If the value is negative,
1881+
extend the string containing the constant and insert a
1882+
negative in the 0th position.
1883+
*/
1884+
if ((childtype == PLUS || childtype == MINUS || childtype == TILDE)
1885+
&& TYPE(CHILD(n, 1)) == factor
1886+
&& TYPE(CHILD(CHILD(n, 1), 0)) == power
1887+
&& TYPE(CHILD(CHILD(CHILD(n, 1), 0), 0)) == atom
1888+
&& TYPE(CHILD(CHILD(CHILD(CHILD(n, 1), 0), 0), 0)) == NUMBER) {
1889+
node *constant = CHILD(CHILD(CHILD(n, 1), 0), 0);
1890+
if (childtype == TILDE) {
1891+
com_invert_constant(c, CHILD(constant, 0));
1892+
return;
1893+
}
1894+
if (childtype == MINUS) {
1895+
node *numnode = CHILD(constant, 0);
1896+
char *s = malloc(strlen(STR(numnode)) + 2);
1897+
if (s == NULL) {
1898+
com_error(c, PyExc_MemoryError, "");
1899+
com_addbyte(c, 255);
1900+
return;
1901+
}
1902+
s[0] = '-';
1903+
strcpy(s + 1, STR(numnode));
1904+
free(STR(numnode));
1905+
STR(numnode) = s;
1906+
}
1907+
com_atom(c, constant);
1908+
}
1909+
else if (childtype == PLUS) {
18471910
com_factor(c, CHILD(n, 1));
18481911
com_addbyte(c, UNARY_POSITIVE);
18491912
}
1850-
else if (TYPE(CHILD(n, 0)) == MINUS) {
1913+
else if (childtype == MINUS) {
18511914
com_factor(c, CHILD(n, 1));
18521915
com_addbyte(c, UNARY_NEGATIVE);
18531916
}
1854-
else if (TYPE(CHILD(n, 0)) == TILDE) {
1917+
else if (childtype == TILDE) {
18551918
com_factor(c, CHILD(n, 1));
18561919
com_addbyte(c, UNARY_INVERT);
18571920
}

0 commit comments

Comments
 (0)