Initial revision
diff --git a/Objects/intobject.c b/Objects/intobject.c
new file mode 100644
index 0000000..7a69238
--- /dev/null
+++ b/Objects/intobject.c
@@ -0,0 +1,250 @@
+/* Integer object implementation */
+
+#include <stdio.h>
+
+#include "PROTO.h"
+#include "object.h"
+#include "intobject.h"
+#include "stringobject.h"
+#include "objimpl.h"
+
+/* Standard Booleans */
+intobject FalseObject = {
+	OB_HEAD_INIT(&Inttype)
+	0
+};
+intobject TrueObject = {
+	OB_HEAD_INIT(&Inttype)
+	1
+};
+
+object *
+newintobject(ival)
+	long ival;
+{
+	/* For efficiency, this code is copied from newobject() */
+	register intobject *op = (intobject *) malloc(sizeof(intobject));
+	if (op == NULL) {
+		errno = ENOMEM;
+	}
+	else {
+		NEWREF(op);
+		op->ob_type = &Inttype;
+		op->ob_ival = ival;
+	}
+	return (object *) op;
+}
+
+long
+getintvalue(op)
+	register object *op;
+{
+	if (!is_intobject(op)) {
+		errno = EBADF;
+		return -1;
+	}
+	else
+		return ((intobject *)op) -> ob_ival;
+}
+
+/* Methods */
+
+static void
+intprint(v, fp, flags)
+	intobject *v;
+	FILE *fp;
+	int flags;
+{
+	fprintf(fp, "%ld", v->ob_ival);
+}
+
+static object *
+intrepr(v)
+	intobject *v;
+{
+	char buf[20];
+	sprintf(buf, "%ld", v->ob_ival);
+	return newstringobject(buf);
+}
+
+static int
+intcompare(v, w)
+	intobject *v, *w;
+{
+	register long i = v->ob_ival;
+	register long j = w->ob_ival;
+	return (i < j) ? -1 : (i > j) ? 1 : 0;
+}
+
+static object *
+intadd(v, w)
+	intobject *v;
+	register object *w;
+{
+	register long a, b, x;
+	if (!is_intobject(w)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	a = v->ob_ival;
+	b = ((intobject *)w) -> ob_ival;
+	x = a + b;
+	if ((x^a) < 0 && (x^b) < 0) {
+		errno = ERANGE;
+		return NULL;
+	}
+	return newintobject(x);
+}
+
+static object *
+intsub(v, w)
+	intobject *v;
+	register object *w;
+{
+	register long a, b, x;
+	if (!is_intobject(w)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	a = v->ob_ival;
+	b = ((intobject *)w) -> ob_ival;
+	x = a - b;
+	if ((x^a) < 0 && (x^~b) < 0) {
+		errno = ERANGE;
+		return NULL;
+	}
+	return newintobject(x);
+}
+
+static object *
+intmul(v, w)
+	intobject *v;
+	register object *w;
+{
+	register long a, b;
+	double x;
+	if (!is_intobject(w)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	a = v->ob_ival;
+	b = ((intobject *)w) -> ob_ival;
+	x = (double)a * (double)b;
+	if (x > 0x7fffffff || x < (double) (long) 0x80000000) {
+		errno = ERANGE;
+		return NULL;
+	}
+	return newintobject(a * b);
+}
+
+static object *
+intdiv(v, w)
+	intobject *v;
+	register object *w;
+{
+	if (!is_intobject(w)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	if (((intobject *)w) -> ob_ival == 0) {
+		errno = EDOM;
+		return NULL;
+	}
+	return newintobject(v->ob_ival / ((intobject *)w) -> ob_ival);
+}
+
+static object *
+intrem(v, w)
+	intobject *v;
+	register object *w;
+{
+	if (!is_intobject(w)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	if (((intobject *)w) -> ob_ival == 0) {
+		errno = EDOM;
+		return NULL;
+	}
+	return newintobject(v->ob_ival % ((intobject *)w) -> ob_ival);
+}
+
+static object *
+intpow(v, w)
+	intobject *v;
+	register object *w;
+{
+	register long iv, iw, ix;
+	register int neg;
+	if (!is_intobject(w)) {
+		errno = EINVAL;
+		return NULL;
+	}
+	iv = v->ob_ival;
+	iw = ((intobject *)w)->ob_ival;
+	neg = 0;
+	if (iw < 0)
+		neg = 1, iw = -iw;
+	ix = 1;
+	for (; iw > 0; iw--)
+		ix = ix * iv;
+	if (neg) {
+		if (ix == 0) {
+			errno = EDOM;
+			return NULL;
+		}
+		ix = 1/ix;
+	}
+	/* XXX How to check for overflow? */
+	return newintobject(ix);
+}
+
+static object *
+intneg(v)
+	intobject *v;
+{
+	register long a, x;
+	a = v->ob_ival;
+	x = -a;
+	if (a < 0 && x < 0) {
+		errno = ERANGE;
+		return NULL;
+	}
+	return newintobject(x);
+}
+
+static object *
+intpos(v)
+	intobject *v;
+{
+	INCREF(v);
+	return (object *)v;
+}
+
+static number_methods int_as_number = {
+	intadd,	/*tp_add*/
+	intsub,	/*tp_subtract*/
+	intmul,	/*tp_multiply*/
+	intdiv,	/*tp_divide*/
+	intrem,	/*tp_remainder*/
+	intpow,	/*tp_power*/
+	intneg,	/*tp_negate*/
+	intpos,	/*tp_plus*/
+};
+
+typeobject Inttype = {
+	OB_HEAD_INIT(&Typetype)
+	0,
+	"int",
+	sizeof(intobject),
+	0,
+	free,		/*tp_dealloc*/
+	intprint,	/*tp_print*/
+	0,		/*tp_getattr*/
+	0,		/*tp_setattr*/
+	intcompare,	/*tp_compare*/
+	intrepr,	/*tp_repr*/
+	&int_as_number,	/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+};