* Include/classobject.h, Objects/classobject.c, Python/ceval.c:
	entirely redone operator overloading.  The rules for class
	instances are now much more relaxed than for other built-in types
	(whose coerce must still return two objects of the same type)

	* Objects/floatobject.c: add overflow check when converting float
	to int and implement truncation towards zero using ceil/float

	* Objects/longobject.c: change ValueError to OverflowError when
	converting to int

	* Objects/rangeobject.c: modernized

	* Objects/stringobject.c: use HAVE_LIMITS instead of __STDC__

	* Objects/xxobject.c: changed to use new style (not finished?)
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 8b7e4da..923ad45 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -25,9 +25,7 @@
 /* Class object implementation */
 
 #include "allobjects.h"
-#include "modsupport.h"
 #include "structmember.h"
-#include "ceval.h"
 
 /* Forward */
 static object *class_lookup PROTO((classobject *, char *, classobject **));
@@ -520,33 +518,22 @@
 
 static int
 instance_compare(inst, other)
-	instanceobject *inst, *other;
+	object *inst, *other;
 {
-	object *func;
-	object *res;
+	object *result;
 	int outcome;
-
-	func = instance_getattr(inst, "__cmp__");
-	if (func == NULL) {
-		err_clear();
-		if (inst < other)
-			return -1;
-		if (inst > other)
-			return 1;
-		return 0;
-	}
-	res = call_object(func, (object *)other);
-	DECREF(func);
-	if (res == NULL) {
-		err_clear(); /* XXX Should report the error, bot how...??? */
-		return 0;
-	}
-	if (is_intobject(res))
-		outcome = getintvalue(res);
-	else
-		outcome = 0; /* XXX Should report the error, bot how...??? */
-	DECREF(res);
-	return outcome;
+	result  = instancebinop(inst, other, "__cmp__", "__rcmp__");
+	if (result == NULL)
+		return -2;
+	outcome = getintvalue(result);
+	DECREF(result);
+	if (outcome == -1 && err_occurred())
+		return -2;
+	if (outcome < 0)
+		return -1;
+	else if (outcome > 0)
+		return 1;
+	return 0;
 }
 
 static long
@@ -681,47 +668,6 @@
 };
 
 static object *
-instance_concat(inst, other)
-	instanceobject *inst, *other;
-{
-	object *func, *arg, *res;
-
-	func = instance_getattr(inst, "__add__");
-	if (func == NULL)
-		return NULL;
-	arg = mkvalue("(O)", other);
-	if (arg == NULL) {
-		DECREF(func);
-		return NULL;
-	}
-	res = call_object(func, arg);
-	DECREF(func);
-	DECREF(arg);
-	return res;
-}
-
-static object *
-instance_repeat(inst, count)
-	instanceobject *inst;
-	int count;
-{
-	object *func, *arg, *res;
-
-	func = instance_getattr(inst, "__mul__");
-	if (func == NULL)
-		return NULL;
-	arg = newintobject((long)count);
-	if (arg == NULL) {
-		DECREF(func);
-		return NULL;
-	}
-	res = call_object(func, arg);
-	DECREF(func);
-	DECREF(arg);
-	return res;
-}
-
-static object *
 instance_item(inst, i)
 	instanceobject *inst;
 	int i;
@@ -827,8 +773,8 @@
 
 static sequence_methods instance_as_sequence = {
 	(inquiry)instance_length, /*sq_length*/
-	(binaryfunc)instance_concat, /*sq_concat*/
-	(intargfunc)instance_repeat, /*sq_repeat*/
+	0, /*sq_concat*/
+	0, /*sq_repeat*/
 	(intargfunc)instance_item, /*sq_item*/
 	(intintargfunc)instance_slice, /*sq_slice*/
 	(intobjargproc)instance_ass_item, /*sq_ass_item*/
@@ -836,27 +782,6 @@
 };
 
 static object *
-generic_binary_op(self, other, methodname)
-	instanceobject *self;
-	object *other;
-	char *methodname;
-{
-	object *func, *arg, *res;
-
-	if ((func = instance_getattr(self, methodname)) == NULL)
-		return NULL;
-	arg = mkvalue("O", other);
-	if (arg == NULL) {
-		DECREF(func);
-		return NULL;
-	}
-	res = call_object(func, arg);
-	DECREF(func);
-	DECREF(arg);
-	return res;
-}
-
-static object *
 generic_unary_op(self, methodname)
 	instanceobject *self;
 	char *methodname;
@@ -870,23 +795,120 @@
 	return res;
 }
 
-#define BINARY(funcname, methodname) \
-static object * funcname(self, other) instanceobject *self; object *other; { \
-	return generic_binary_op(self, other, methodname); \
+
+/* Forward */
+static int halfbinop PROTO((object *, object *, char *, object **));
+
+
+/* Implement a binary operator involving at least one class instance. */
+
+object *
+instancebinop(v, w, opname, ropname)
+	object *v;
+	object *w;
+	char *opname;
+	char *ropname;
+{
+	char buf[256];
+	object *result = NULL;
+	if (halfbinop(v, w, opname, &result) <= 0)
+		return result;
+	if (halfbinop(w, v, ropname, &result) <= 0)
+		return result;
+	sprintf(buf, "%s nor %s defined for these operands", opname, ropname);
+	err_setstr(TypeError, buf);
+	return NULL;
 }
 
+
+/* Try one half of a binary operator involving a class instance.
+   Return value:
+   -1 if an exception is to be reported right away
+   0  if we have a valid result
+   1  if we could try another operation
+*/
+
+static int
+halfbinop(v, w, opname, r_result)
+	object *v;
+	object *w;
+	char *opname;
+	object **r_result;
+{
+	object *func;
+	object *args;
+	object *coerce;
+	object *coerced = NULL;
+	object *v1;
+	
+	if (!is_instanceobject(v))
+		return 1;
+	func = getattr(v, opname);
+	if (func == NULL) {
+		if (err_occurred() != AttributeError)
+			return -1;
+		err_clear();
+		return 1;
+	}
+	coerce = getattr(v, "__coerce__");
+	if (coerce == NULL) {
+		err_clear();
+	}
+	else {
+		args = mkvalue("(O)", w);
+		if (args == NULL) {
+			DECREF(func);
+			return -1;
+		}
+		coerced = call_object(coerce, args);
+		DECREF(args);
+		DECREF(coerce);
+		if (coerced == NULL) {
+			DECREF(func);
+			return -1;
+		}
+		if (coerced == None) {
+			DECREF(coerced);
+			DECREF(func);
+			return 1;
+		}
+		if (!is_tupleobject(coerced) || gettuplesize(coerced) != 2) {
+			DECREF(coerced);
+			DECREF(func);
+			err_setstr(TypeError, "coercion should return None or 2-tuple");
+			return -1;
+		}
+		v1 = gettupleitem(coerced, 0);
+		if (v1 != v) {
+			v = v1;
+			DECREF(func);
+			func = getattr(v, opname);
+			if (func == NULL) {
+				XDECREF(coerced);
+				return -1;
+			}
+		}
+		w = gettupleitem(coerced, 1);
+	}
+	args = mkvalue("(O)", w);
+	if (args == NULL) {
+		DECREF(func);
+		XDECREF(coerced);
+		return -1;
+	}
+	*r_result = call_object(func, args);
+	DECREF(args);
+	DECREF(func);
+	XDECREF(coerced);
+	return *r_result == NULL ? -1 : 0;
+}
+
+
 #define UNARY(funcname, methodname) \
 static object *funcname(self) instanceobject *self; { \
 	return generic_unary_op(self, methodname); \
 }
 
-BINARY(instance_add, "__add__")
-BINARY(instance_sub, "__sub__")
-BINARY(instance_mul, "__mul__")
-BINARY(instance_div, "__div__")
-BINARY(instance_mod, "__mod__")
-BINARY(instance_divmod, "__divmod__")
-BINARY(instance_pow, "__pow__")
 UNARY(instance_neg, "__neg__")
 UNARY(instance_pos, "__pos__")
 UNARY(instance_abs, "__abs__")
@@ -926,76 +948,56 @@
 }
 
 UNARY(instance_invert, "__invert__")
-BINARY(instance_lshift, "__lshift__")
-BINARY(instance_rshift, "__rshift__")
-BINARY(instance_and, "__and__")
-BINARY(instance_xor, "__xor__")
-BINARY(instance_or, "__or__")
-
-static int
-instance_coerce(pv, pw)
-	object **pv, **pw;
-{
-	object *v =  *pv;
-	object *w = *pw;
-	object *func;
-	object *res;
-	int outcome;
-
-	if (!is_instanceobject(v))
-		return 1; /* XXX shouldn't be possible */
-	func = instance_getattr((instanceobject *)v, "__coerce__");
-	if (func == NULL) {
-		err_clear();
-		return 1;
-	}
-	res = call_object(func, w);
-	if (res == NULL)
-		return -1;
-	if (res == None) {
-		DECREF(res);
-		return 1;
-	}
-	outcome = getargs(res, "(OO)", &v, &w);
-	if (!outcome || v->ob_type != w->ob_type ||
-			v->ob_type->tp_as_number == NULL) {
-		DECREF(res);
-		err_setstr(TypeError, "bad __coerce__ result");
-		return -1;
-	}
-	INCREF(v);
-	INCREF(w);
-	DECREF(res);
-	*pv = v;
-	*pw = w;
-	return 0;
-}
-
 UNARY(instance_int, "__int__")
 UNARY(instance_long, "__long__")
 UNARY(instance_float, "__float__")
 UNARY(instance_oct, "__oct__")
 UNARY(instance_hex, "__hex__")
 
+/* This version is for ternary calls only (z != None) */
+static object *
+instance_pow(v, w, z)
+	object *v;
+	object *w;
+	object *z;
+{
+	/* XXX Doesn't do coercions... */
+	object *func;
+	object *args;
+	object *result;
+	func = getattr(v, "__pow__");
+	if (func == NULL)
+		return NULL;
+	args = mkvalue("(OO)", w, z);
+	if (args == NULL) {
+		DECREF(func);
+		return NULL;
+	}
+	result = call_object(func, args);
+	DECREF(func);
+	DECREF(args);
+	return result;
+}
+
 static number_methods instance_as_number = {
-	(binaryfunc)instance_add, /*nb_add*/
-	(binaryfunc)instance_sub, /*nb_subtract*/
-	(binaryfunc)instance_mul, /*nb_multiply*/
-	(binaryfunc)instance_div, /*nb_divide*/
-	(binaryfunc)instance_mod, /*nb_remainder*/
-	(binaryfunc)instance_divmod, /*nb_divmod*/
+	0, /*nb_add*/
+	0, /*nb_subtract*/
+	0, /*nb_multiply*/
+	0, /*nb_divide*/
+	0, /*nb_remainder*/
+	0, /*nb_divmod*/
 	(ternaryfunc)instance_pow, /*nb_power*/
 	(unaryfunc)instance_neg, /*nb_negative*/
 	(unaryfunc)instance_pos, /*nb_positive*/
 	(unaryfunc)instance_abs, /*nb_absolute*/
 	(inquiry)instance_nonzero, /*nb_nonzero*/
 	(unaryfunc)instance_invert, /*nb_invert*/
-	(binaryfunc)instance_lshift, /*nb_lshift*/
-	(binaryfunc)instance_rshift, /*nb_rshift*/
-	(binaryfunc)instance_and, /*nb_and*/
-	(binaryfunc)instance_xor, /*nb_xor*/
-	(binaryfunc)instance_or, /*nb_or*/
-	(coercion)instance_coerce, /*nb_coerce*/
+	0, /*nb_lshift*/
+	0, /*nb_rshift*/
+	0, /*nb_and*/
+	0, /*nb_xor*/
+	0, /*nb_or*/
+	0, /*nb_coerce*/
 	(unaryfunc)instance_int, /*nb_int*/
 	(unaryfunc)instance_long, /*nb_long*/
 	(unaryfunc)instance_float, /*nb_float*/
@@ -1011,10 +1013,9 @@
 	0,
 	(destructor)instance_dealloc, /*tp_dealloc*/
 	0,			/*tp_print*/
-	(object * (*) FPROTO((object *, char *)))
 	(getattrfunc)instance_getattr, /*tp_getattr*/
 	(setattrfunc)instance_setattr, /*tp_setattr*/
-	(cmpfunc)instance_compare, /*tp_compare*/
+	instance_compare, /*tp_compare*/
 	(reprfunc)instance_repr, /*tp_repr*/
 	&instance_as_number,	/*tp_as_number*/
 	&instance_as_sequence,	/*tp_as_sequence*/
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index cbdcfd5..b37dd15 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -47,6 +47,18 @@
 #define CHECK(x) /* Don't know how to check */
 #endif
 
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 0X7FFFFFFFL
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (-LONG_MAX-1)
+#endif
+
 #ifndef macintosh
 extern double fmod PROTO((double, double));
 extern double pow PROTO((double, double));
@@ -397,8 +409,11 @@
 	object *v;
 {
 	double x = getfloatvalue(v);
-	/* XXX should check for overflow */
-	/* XXX should define how we round */
+	if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
+	          : (x = floor(x)) > (double)LONG_MAX) {
+		err_setstr(OverflowError, "float to large to convert");
+		return NULL;
+	}
 	return newintobject((long)x);
 }
 
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 45907e8..82a74c0 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -159,7 +159,7 @@
 		prev = x;
 		x = (x << SHIFT) + v->ob_digit[i];
 		if ((x >> SHIFT) != prev) {
-			err_setstr(ValueError,
+			err_setstr(OverflowError,
 				"long int too long to convert");
 			return -1;
 		}
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index f19dad8..5f9da1d 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -105,7 +105,7 @@
 	rangeobject *r;
 {
 	char buf[80];
-	sprintf(buf, "(range(%ld, %ld, %ld) * %d)",
+	sprintf(buf, "(xrange(%ld, %ld, %ld) * %d)",
 			r->start,
 			r->start + r->len * r->step,
 			r->step,
@@ -222,7 +222,7 @@
 	char *name;
 {
 	static struct methodlist range_methods[] = {
-		{"tolist",	range_tolist},
+		{"tolist",	(method)range_tolist},
 		{NULL,		NULL}
 	};
 
@@ -230,11 +230,11 @@
 }
 
 static sequence_methods range_as_sequence = {
-	range_length,	/*sq_length*/
-	range_concat,	/*sq_concat*/
-	range_repeat,	/*sq_repeat*/
-	range_item,	/*sq_item*/
-	range_slice,	/*sq_slice*/
+	(inquiry)range_length, /*sq_length*/
+	(binaryfunc)range_concat, /*sq_concat*/
+	(intargfunc)range_repeat, /*sq_repeat*/
+	(intargfunc)range_item, /*sq_item*/
+	(intintargfunc)range_slice, /*sq_slice*/
 	0,		/*sq_ass_item*/
 	0,		/*sq_ass_slice*/
 };
@@ -245,12 +245,12 @@
 	"xrange",		/* Name of this type */
 	sizeof(rangeobject),	/* Basic object size */
 	0,			/* Item size for varobject */
-	range_dealloc,		/*tp_dealloc*/
-	range_print,		/*tp_print*/
-	range_getattr,		/*tp_getattr*/
+	(destructor)range_dealloc, /*tp_dealloc*/
+	(printfunc)range_print, /*tp_print*/
+	(getattrfunc)range_getattr, /*tp_getattr*/
 	0,			/*tp_setattr*/
-	range_compare,		/*tp_compare*/
-	range_repr,		/*tp_repr*/
+	(cmpfunc)range_compare, /*tp_compare*/
+	(reprfunc)range_repr, /*tp_repr*/
 	0,			/*tp_as_number*/
 	&range_as_sequence,	/*tp_as_sequence*/
 	0,			/*tp_as_mapping*/
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 4221d68..359e4e9 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -32,7 +32,7 @@
 int null_strings, one_strings;
 #endif
 
-#ifdef __STDC__
+#ifdef HAVE_LIMITS_H
 #include <limits.h>
 #else
 #ifndef UCHAR_MAX
diff --git a/Objects/xxobject.c b/Objects/xxobject.c
index e135d3f..7a29925 100644
--- a/Objects/xxobject.c
+++ b/Objects/xxobject.c
@@ -34,24 +34,23 @@
 
 /* Xx objects */
 
-#include "allobjects.h"
-#include "modsupport.h"		/* For getargs() etc. */
+#include "Python.h"
 
 typedef struct {
-	OB_HEAD
-	object	*x_attr;	/* Attributes dictionary */
+	PyObject_HEAD
+	PyObject	*x_attr;	/* Attributes dictionary */
 } xxobject;
 
-staticforward typeobject Xxtype;
+staticforward PyTypeObject Xxtype;
 
 #define is_xxobject(v)		((v)->ob_type == &Xxtype)
 
 static xxobject *
 newxxobject(arg)
-	object *arg;
+	PyObject *arg;
 {
 	xxobject *xp;
-	xp = NEWOBJ(xxobject, &Xxtype);
+	xp = PyObject_NEW(xxobject, &Xxtype);
 	if (xp == NULL)
 		return NULL;
 	xp->x_attr = NULL;
@@ -64,65 +63,65 @@
 xx_dealloc(xp)
 	xxobject *xp;
 {
-	XDECREF(xp->x_attr);
-	DEL(xp);
+	Py_XDECREF(xp->x_attr);
+	PyMem_DEL(xp);
 }
 
-static object *
+static PyObject *
 xx_demo(self, args)
 	xxobject *self;
-	object *args;
+	PyObject *args;
 {
-	if (!getnoarg(args))
+	if (!PyArg_NoArgs(args))
 		return NULL;
-	INCREF(None);
-	return None;
+	Py_INCREF(Py_None);
+	return Py_None;
 }
 
-static struct methodlist xx_methods[] = {
-	{"demo",	(method)xx_demo},
+static Py_MethodDef xx_methods[] = {
+	{"demo",	(PyCFunction)xx_demo},
 	{NULL,		NULL}		/* sentinel */
 };
 
-static object *
+static PyObject *
 xx_getattr(xp, name)
 	xxobject *xp;
 	char *name;
 {
 	if (xp->x_attr != NULL) {
-		object *v = dictlookup(xp->x_attr, name);
+		PyObject *v = PyDict_GetItemString(xp->x_attr, name);
 		if (v != NULL) {
-			INCREF(v);
+			Py_INCREF(v);
 			return v;
 		}
 	}
-	return findmethod(xx_methods, (object *)xp, name);
+	return Py_FindMethod(xx_methods, (PyObject *)xp, name);
 }
 
 static int
 xx_setattr(xp, name, v)
 	xxobject *xp;
 	char *name;
-	object *v;
+	PyObject *v;
 {
 	if (xp->x_attr == NULL) {
-		xp->x_attr = newdictobject();
+		xp->x_attr = PyDict_New();
 		if (xp->x_attr == NULL)
 			return -1;
 	}
 	if (v == NULL) {
-		int rv = dictremove(xp->x_attr, name);
+		int rv = PyDict_DelItemString(xp->x_attr, name);
 		if (rv < 0)
-			err_setstr(AttributeError,
+			PyErr_SetString(PyExc_AttributeError,
 			        "delete non-existing xx attribute");
 		return rv;
 	}
 	else
-		return dictinsert(xp->x_attr, name, v);
+		return PyDict_SetItemString(xp->x_attr, name, v);
 }
 
-static typeobject Xxtype = {
-	OB_HEAD_INIT(&Typetype)
+static PyTypeObject Xxtype = {
+	PyObject_HEAD_INIT(&PyType_Type)
 	0,			/*ob_size*/
 	"xx",			/*tp_name*/
 	sizeof(xxobject),	/*tp_basicsize*/