[Python-checkins] CVS: python/dist/src/Python ceval.c,2.263,2.264 compile.c,2.211,2.212 future.c,2.8,2.9 graminit.c,2.29,2.30

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 07 Aug 2001 22:00:21 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv23513/Python

Modified Files:
	ceval.c compile.c future.c graminit.c 
Log Message:
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.



Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.263
retrieving revision 2.264
diff -C2 -d -r2.263 -r2.264
*** ceval.c	2001/08/02 04:15:00	2.263
--- ceval.c	2001/08/08 05:00:18	2.264
***************
*** 885,888 ****
--- 885,908 ----
  			break;
  
+ 		case BINARY_FLOOR_DIVIDE:
+ 			w = POP();
+ 			v = POP();
+ 			x = PyNumber_FloorDivide(v, w);
+ 			Py_DECREF(v);
+ 			Py_DECREF(w);
+ 			PUSH(x);
+ 			if (x != NULL) continue;
+ 			break;
+ 
+ 		case BINARY_TRUE_DIVIDE:
+ 			w = POP();
+ 			v = POP();
+ 			x = PyNumber_TrueDivide(v, w);
+ 			Py_DECREF(v);
+ 			Py_DECREF(w);
+ 			PUSH(x);
+ 			if (x != NULL) continue;
+ 			break;
+ 
  		case BINARY_MODULO:
  			w = POP();
***************
*** 1046,1049 ****
--- 1066,1089 ----
  			v = POP();
  			x = PyNumber_InPlaceDivide(v, w);
+ 			Py_DECREF(v);
+ 			Py_DECREF(w);
+ 			PUSH(x);
+ 			if (x != NULL) continue;
+ 			break;
+ 
+ 		case INPLACE_FLOOR_DIVIDE:
+ 			w = POP();
+ 			v = POP();
+ 			x = PyNumber_InPlaceFloorDivide(v, w);
+ 			Py_DECREF(v);
+ 			Py_DECREF(w);
+ 			PUSH(x);
+ 			if (x != NULL) continue;
+ 			break;
+ 
+ 		case INPLACE_TRUE_DIVIDE:
+ 			w = POP();
+ 			v = POP();
+ 			x = PyNumber_InPlaceTrueDivide(v, w);
  			Py_DECREF(v);
  			Py_DECREF(w);

Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.211
retrieving revision 2.212
diff -C2 -d -r2.211 -r2.212
*** compile.c	2001/08/06 20:34:25	2.211
--- compile.c	2001/08/08 05:00:18	2.212
***************
*** 1875,1886 ****
  			break;
  		case SLASH:
! 			op = BINARY_DIVIDE;
  			break;
  		case PERCENT:
  			op = BINARY_MODULO;
  			break;
  		default:
  			com_error(c, PyExc_SystemError,
! 				  "com_term: operator not *, / or %");
  			op = 255;
  		}
--- 1875,1892 ----
  			break;
  		case SLASH:
! 			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 %");
  			op = 255;
  		}
***************
*** 2476,2480 ****
  	case '+': opcode = INPLACE_ADD; break;
  	case '-': opcode = INPLACE_SUBTRACT; break;
! 	case '/': opcode = INPLACE_DIVIDE; break;
  	case '%': opcode = INPLACE_MODULO; break;
  	case '<': opcode = INPLACE_LSHIFT; break;
--- 2482,2493 ----
  	case '+': opcode = INPLACE_ADD; break;
  	case '-': opcode = INPLACE_SUBTRACT; 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;
***************
*** 3946,3950 ****
  		    || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION))
  			sc.c_nested = 1;
! 		sc.c_flags |= base->c_flags & CO_GENERATOR_ALLOWED;
  	} else {
  		sc.c_private = NULL;
--- 3959,3964 ----
  		    || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION))
  			sc.c_nested = 1;
! 		sc.c_flags |= base->c_flags & (CO_GENERATOR_ALLOWED |
! 					       CO_FUTURE_DIVISION);
  	} else {
  		sc.c_private = NULL;
***************
*** 3964,3967 ****
--- 3978,3986 ----
  			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) {
***************
*** 4438,4441 ****
--- 4457,4462 ----
  		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)

Index: future.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/future.c,v
retrieving revision 2.8
retrieving revision 2.9
diff -C2 -d -r2.8 -r2.9
*** future.c	2001/07/16 03:11:48	2.8
--- future.c	2001/08/08 05:00:18	2.9
***************
*** 34,37 ****
--- 34,39 ----
  		} else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
  			ff->ff_generators = 1;
+ 		} else if (strcmp(feature, FUTURE_DIVISION) == 0) {
+ 			ff->ff_division = 1;
  		} else if (strcmp(feature, "braces") == 0) {
  			PyErr_SetString(PyExc_SyntaxError,
***************
*** 235,238 ****
--- 237,241 ----
  	ff->ff_nested_scopes = 0;
  	ff->ff_generators = 0;
+ 	ff->ff_division = 0;
  
  	if (future_parse(ff, n, filename) < 0) {

Index: graminit.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v
retrieving revision 2.29
retrieving revision 2.30
diff -C2 -d -r2.29 -r2.30
*** graminit.c	2001/06/18 22:08:13	2.29
--- graminit.c	2001/08/08 05:00:18	2.30
***************
*** 253,257 ****
  	{2, arcs_11_5},
  };
! static arc arcs_12_0[11] = {
  	{38, 1},
  	{39, 1},
--- 253,257 ----
  	{2, arcs_11_5},
  };
! static arc arcs_12_0[12] = {
  	{38, 1},
[...1463 lines suppressed...]
*** 1681,1684 ****
--- 1684,1688 ----
  	{17, 0},
  	{24, 0},
+ 	{48, 0},
  	{32, 0},
  	{304, 0},
***************
*** 1708,1712 ****
  	65,
  	dfas,
! 	{144, labels},
  	256
  };
--- 1712,1716 ----
  	65,
  	dfas,
! 	{146, labels},
  	256
  };