diff Python/compile.c @ 19051:f20727cc3d0f legacy-trunk

Implement PEP 238 in its (almost) full glory. This introduces: - A new operator // that means floor division (the kind of division where 1/2 is 0). - The "future division" statement ("from __future__ import division) which changes the meaning of the / operator to implement "true division" (where 1/2 is 0.5). - New overloadable operators __truediv__ and __floordiv__. - New slots in the PyNumberMethods struct for true and floor division, new abstract APIs for them, new opcodes, and so on. I emphasize that without the future division statement, the semantics of / will remain unchanged until Python 3.0. Not yet implemented are warnings (default off) when / is used with int or long arguments. This has been on display since 7/31 as SF patch #443474. Flames to /dev/null.
author Guido van Rossum <guido@python.org>
date Wed, 08 Aug 2001 05:00:18 +0000
parents e5754f048f0b
children 97a3d3d7029f
line wrap: on
line diff
--- a/Python/compile.c	Wed Aug 08 01:30:38 2001 +0000
+++ b/Python/compile.c	Wed Aug 08 05:00:18 2001 +0000
@@ -1874,14 +1874,20 @@
 			op = BINARY_MULTIPLY;
 			break;
 		case SLASH:
-			op = BINARY_DIVIDE;
+			if (c->c_flags & CO_FUTURE_DIVISION)
+				op = BINARY_TRUE_DIVIDE;
+			else
+				op = BINARY_DIVIDE;
 			break;
 		case PERCENT:
 			op = BINARY_MODULO;
 			break;
+		case DOUBLESLASH:
+			op = BINARY_FLOOR_DIVIDE;
+			break;
 		default:
 			com_error(c, PyExc_SystemError,
-				  "com_term: operator not *, / or %");
+				  "com_term: operator not *, /, // or %");
 			op = 255;
 		}
 		com_addbyte(c, op);
@@ -2475,7 +2481,14 @@
 	switch (STR(CHILD(CHILD(n, 1), 0))[0]) {
 	case '+': opcode = INPLACE_ADD; break;
 	case '-': opcode = INPLACE_SUBTRACT; break;
-	case '/': opcode = INPLACE_DIVIDE; break;
+	case '/':
+		if (STR(CHILD(CHILD(n, 1), 0))[1] == '/')
+			opcode = INPLACE_FLOOR_DIVIDE;
+		else if (c->c_flags & CO_FUTURE_DIVISION)
+			opcode = INPLACE_TRUE_DIVIDE;
+		else
+			opcode = INPLACE_DIVIDE;
+		break;
 	case '%': opcode = INPLACE_MODULO; break;
 	case '<': opcode = INPLACE_LSHIFT; break;
 	case '>': opcode = INPLACE_RSHIFT; break;
@@ -3945,7 +3958,8 @@
 		if (base->c_nested 
 		    || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION))
 			sc.c_nested = 1;
-		sc.c_flags |= base->c_flags & CO_GENERATOR_ALLOWED;
+		sc.c_flags |= base->c_flags & (CO_GENERATOR_ALLOWED |
+					       CO_FUTURE_DIVISION);
 	} else {
 		sc.c_private = NULL;
 		sc.c_future = PyNode_Future(n, filename);
@@ -3963,6 +3977,11 @@
 				sc.c_future->ff_generators = 1;
 			else if (sc.c_future->ff_generators)
 				flags->cf_flags |= PyCF_GENERATORS;
+
+			if (flags->cf_flags & PyCF_DIVISION)
+				sc.c_future->ff_division = 1;
+			else if (sc.c_future->ff_division)
+				flags->cf_flags |= PyCF_DIVISION;
 		}
 		if (symtable_build(&sc, n) < 0) {
 			com_free(&sc);
@@ -4437,6 +4456,8 @@
 			c->c_flags |= CO_NESTED;
 		if (c->c_future->ff_generators)
 			c->c_flags |= CO_GENERATOR_ALLOWED;
+		if (c->c_future->ff_division)
+			c->c_flags |= CO_FUTURE_DIVISION;
 	}
 	if (ste->ste_generator)
 		c->c_flags |= CO_GENERATOR;