--- old/CHANGELOG	2017-05-25 12:43:49.165410451 -0700
+++ new/CHANGELOG	2017-05-29 12:10:55.294175873 -0700
@@ -15,3 +15,7 @@
                  Fixed (loop (catch #f (catch #f (exit-loop) #f) #f)).
                  Changed macro-doublequote to support \x[0-9A-Fa-f][0-9A-Fa-f].
 
+2017-05-29: 2.6: Added bigint.c and float.c as optional modules.
+                 Clarified documentation.txt regarding things like numcmp().
+                 write-object now shows #t instead of a generic 1.
+
--- old/Makefile	2017-05-17 20:43:29.481586982 -0700
+++ new/Makefile	2017-05-29 11:50:46.514575182 -0700
@@ -8,6 +8,16 @@
 LISPS=compiler.lisp functions.lisp macroexpand.lisp optimizer.lisp
 BUILDDIR=obj/
 
+### Uncomment these three lines to enable float.c
+CFLAGS+=-DUSE_FLOAT
+SRCS+=float.c
+LIBS+=-lm
+
+### Uncomment these three lines to enable bigint.c
+CFLAGS+=-DUSE_BIGINT
+SRCS+=bigint.c
+LIBS+=-lgmp
+
 ### Uncomment this to enable the vm-debug function
 #CFLAGS+=-DDEBUG
 ###
--- old/documentation.txt	2017-05-18 17:26:26.567700897 -0700
+++ new/documentation.txt	2017-05-29 10:58:43.046810068 -0700
@@ -38,8 +38,8 @@
 pass an object to a "regular" C function you'll need to INCREF() the object
 before passing it in (if you're just passing in a copy) and you'll need to
 DECREF() the result when you're done with it.  There are some C functions that
-do not behave like that; they're the ones that take something other than obj*s
-as arguments or return something other than an obj*.
+do not behave like that; they're generally the ones that take something other
+than obj*s as arguments or return something other than an obj*.
 
 Functions that return an obj* return 0 on failure (signifying that they raised
 an error).  The VM handles passing that error up the call chain until a catcher
--- old/lisp.h	2010-08-11 15:46:25.000000000 -0700
+++ new/lisp.h	2017-05-29 11:11:39.598872970 -0700
@@ -1,8 +1,17 @@
-/* lisp.h   by Michael Thorpe   2010-08-11 */
+/* lisp.h   by Michael Thorpe   2017-05-29 */
 
 #ifndef LISP_H
 #define LISP_H
 
+#ifdef USE_FLOAT
+/* Define this if your machine can't handle floating-point division by 0 */
+/* #define NO_FDIV_BY_0 */
+#endif
+
+#ifdef USE_BIGINT
+#include <gmp.h>
+#endif
+
 /* Only necessary for stream objects: */
 #include <stdio.h>
 
@@ -41,12 +50,17 @@
 		obj *nextfree;
 	} rcnf;
 	union {
+#ifdef USE_BIGINT
+		mpz_t bi;
+#endif
 		struct c {
 			obj *a;
 			obj *d;
 		} c;
 		signed long i;
+#ifdef USE_FLOAT
 		double f;
+#endif
 		obj *o;
 		struct rawfunc {
 			unsigned int numargs:2;
@@ -77,8 +91,14 @@
 };
 
 extern objtype
+#ifdef USE_BIGINT
+	bigint_objtype,
+#endif
 	bytefunc_objtype,
 	cons_objtype,
+#ifdef USE_FLOAT
+	float_objtype,
+#endif
 	integer_objtype,
 	nil_objtype,
 	quote_objtype,
@@ -87,6 +107,20 @@
 	string_objtype,
 	word_objtype;
 
+#ifdef USE_BIGINT
+/* bigint.c */
+obj *addb(obj *a,obj *b);
+obj *bitselectb(obj *a,obj *if0,obj *if1);
+obj *div2b(obj *a,obj *b);
+obj *mulb(obj *a,obj *b);
+obj *numcmpb(obj *a,obj *b,int desired);
+obj *string_to_bigint(obj *str);
+obj *subb(obj *a,obj *b);
+#ifdef USE_FLOAT
+obj *bigint_to_float(obj *bi);
+#endif
+#endif
+
 /* bytefunc.c */
 
 /* cons.c */
@@ -94,7 +128,18 @@
 #define CDR(o) ((o)->value.c.d)
 obj *cons(obj *a,obj *d);
 
+#ifdef USE_FLOAT
+/* float.c */
+obj *addf(obj *a,obj *b);
+obj *div2f(obj *a,obj *b);
+obj *mulf(obj *a,obj *b);
+obj *numcmpf(obj *a,obj *b,int desired);
+obj *string_to_float(obj *str);
+obj *subf(obj *a,obj *b);
+#endif
+
 /* integer.c */
+extern obj *divideby0error;
 extern obj trueobj;
 obj *add(obj *a,obj *b);
 obj *bitselect(obj *a,obj *if0,obj *if1);
--- old/integer.c	2017-04-12 16:28:21.003209533 -0700
+++ new/integer.c	2017-05-29 11:17:52.918897762 -0700
@@ -1,4 +1,4 @@
-/* integer.c   by Michael Thorpe   2017-04-12 */
+/* integer.c   by Michael Thorpe   2017-05-29 */
 
 /* If this is defined, we forbid multiplication operands that won't fit in a
  * signed int and require that a signed int be no more than half the size of
@@ -12,8 +12,16 @@
 #include <stdio.h>
 #include "lisp.h"
 
-static obj *divideby0error;
+#ifndef USE_FLOAT
+#ifndef USE_BIGINT
+#define CAN_OVERFLOW 1
+#endif
+#endif
+
+obj *divideby0error;
+#if CAN_OVERFLOW
 static obj *overflowerror;
+#endif
 
 obj trueobj={&integer_objtype,{refcount:1},{i:1}};
 
@@ -22,6 +30,14 @@
 	int overflow=0;
 	obj *r;
 
+#ifdef USE_FLOAT
+	if(a->type==&float_objtype || b->type==&float_objtype)
+		return(addf(a,b));
+#endif
+#ifdef USE_BIGINT
+	if(a->type==&bigint_objtype || b->type==&bigint_objtype)
+		return(addb(a,b));
+#endif
 	if(a->type != &integer_objtype) {
 		DECREF(b);
 		return(throwtypeerror(a));
@@ -34,13 +50,24 @@
 	result=a->value.i+b->value.i;
 	if((a->value.i^result)<0 && (b->value.i^result)<0)
 		overflow=1;
+#ifdef USE_BIGINT
+	if(overflow)
+		return(addb(a,b));
+#else
+#ifdef USE_FLOAT
+	if(overflow)
+		return(addf(a,b));
+#endif
+#endif
 	DECREF(a);
 	DECREF(b);
 	r=new_object(&integer_objtype);
 	if(r) {
 		r->value.i=result;
+#if CAN_OVERFLOW
 		if(overflow)
 			return(throw(INCREF(overflowerror),r));
+#endif
 	}
 	return(r);
 }
@@ -48,6 +75,10 @@
 obj *bitselect(obj *a,obj *if0,obj *if1) {
 	obj *r;
 
+#ifdef USE_BIGINT
+	if(a->type != &bigint_objtype || if0->type != &bigint_objtype || if1->type != &bigint_objtype)
+		return(bitselectb(a,if0,if1));
+#endif
 	if(a->type != &integer_objtype) {
 		DECREF(if0);
 		DECREF(if1);
@@ -110,6 +141,14 @@
 	signed long result;
 	obj *r;
 
+#ifdef USE_FLOAT
+	if(a->type==&float_objtype || b->type==&float_objtype)
+		return(div2f(a,b));
+#endif
+#ifdef USE_BIGINT
+	if(a->type==&bigint_objtype || b->type==&bigint_objtype)
+		return(div2b(a,b));
+#endif
 	if(a->type != &integer_objtype) {
 		DECREF(b);
 		return(throwtypeerror(a));
@@ -119,9 +158,18 @@
 		return(throwtypeerror(b));
 	}
 	if(b->value.i==0) {
+#ifdef USE_FLOAT
+#ifndef NO_FDIV_BY_0
+		return(div2f(a,b));
+#endif
+#endif
 		DECREF(b);
 		return(throw(INCREF(divideby0error),a));
 	}
+#ifdef USE_FLOAT
+	if(LONG_MIN==b->value.i || a->value.i%b->value.i)
+		return(div2f(a,b));
+#endif
 /* FIXME: Does this have undefined behavior on overflow? */
 	result=a->value.i/b->value.i;
 	DECREF(a);
@@ -137,6 +185,14 @@
 	int overflow=0;
 	obj *r;
 
+#ifdef USE_FLOAT
+	if(a->type==&float_objtype || b->type==&float_objtype)
+		return(mulf(a,b));
+#endif
+#ifdef USE_BIGINT
+	if(a->type==&bigint_objtype || b->type==&bigint_objtype)
+		return(mulb(a,b));
+#endif
 	if(a->type != &integer_objtype) {
 		DECREF(b);
 		return(throwtypeerror(a));
@@ -147,12 +203,28 @@
 	}
 #ifdef RESTRICTED_MULTIPLICATION
 	if(a->value.i<INT_MIN || INT_MAX<a->value.i) {
+#ifdef USE_BIGINT
+		return(mulb(a,b));
+#else
+#ifdef USE_FLOAT
+		return(mulf(a,b));
+#else
 		DECREF(b);
 		return(throwrangecheck(a));
+#endif
+#endif
 	}
 	if(b->value.i<INT_MIN || INT_MAX<b->value.i) {
+#ifdef USE_BIGINT
+		return(mulb(a,b));
+#else
+#ifdef USE_FLOAT
+		return(mulf(a,b));
+#else
 		DECREF(a);
 		return(throwrangecheck(b));
+#endif
+#endif
 	}
 	result=a->value.i*b->value.i;
 #else
@@ -160,13 +232,23 @@
 #endif
 	if(result<LONG_MIN || LONG_MAX<result)
 		overflow=1;
+#ifdef USE_BIGINT
+	if(overflow)
+		return(mulb(a,b));
+#endif
+#ifdef USE_FLOAT
+	if(overflow)
+		return(mulf(a,b));
+#endif
 	DECREF(a);
 	DECREF(b);
 	r=new_object(&integer_objtype);
 	if(r) {
 		r->value.i=result;
+#if CAN_OVERFLOW
 		if(overflow)
 			return(throw(INCREF(overflowerror),r));
+#endif
 	}
 	return(r);
 }
@@ -177,6 +259,14 @@
 obj *numcmp(obj *a,obj *b,int desired) {
 	int cmp;
 
+#ifdef USE_FLOAT
+	if(a->type==&float_objtype || b->type==&float_objtype)
+		return(numcmpf(a,b,desired));
+#endif
+#ifdef USE_BIGINT
+	if(a->type==&bigint_objtype || b->type==&bigint_objtype)
+		return(numcmpb(a,b,desired));
+#endif
 	if(a->type != &integer_objtype) {
 		DECREF(b);
 		return(throwtypeerror(a));
@@ -203,6 +293,14 @@
 	int overflow=0;
 	obj *r;
 
+#ifdef USE_FLOAT
+	if(a->type==&float_objtype || b->type==&float_objtype)
+		return(subf(a,b));
+#endif
+#ifdef USE_BIGINT
+	if(a->type==&bigint_objtype || b->type==&bigint_objtype)
+		return(subb(a,b));
+#endif
 	if(a->type != &integer_objtype) {
 		DECREF(b);
 		return(throwtypeerror(a));
@@ -215,13 +313,23 @@
 	result=a->value.i-b->value.i;
 	if((a->value.i^b->value.i)<0 && (a->value.i^result)<0)
 		overflow=1;
+#ifdef USE_BIGINT
+	if(overflow)
+		return(subb(a,b));
+#endif
+#ifdef USE_FLOAT
+	if(overflow)
+		return(subf(a,b));
+#endif
 	DECREF(a);
 	DECREF(b);
 	r=new_object(&integer_objtype);
 	if(r) {
 		r->value.i=result;
+#if CAN_OVERFLOW
 		if(overflow)
 			return(throw(INCREF(overflowerror),r));
+#endif
 	}
 	return(r);
 }
@@ -241,7 +349,13 @@
 
 static int integer_init() {
 	if(!(divideby0error=new_word("divide-by-zero",14))
-	|| !(overflowerror=new_word("overflow",8)))
+#if CAN_OVERFLOW
+	|| !(overflowerror=new_word("overflow",8))
+#endif
+#ifndef USE_FLOAT
+	|| store_builtin_ns1("string->float",throwtypeerror)
+#endif
+	)
 		return(1);
 /* Sanity check to make sure mul() will catch overflows.  If this fails for
  * you, you'll need to implement some method of overflow checking. */
@@ -261,7 +375,9 @@
 
 static void integer_exit() {
 	DECREF(divideby0error); divideby0error=0;
+#if CAN_OVERFLOW
 	DECREF(overflowerror); overflowerror=0;
+#endif
 }
 
 objtype integer_objtype={
--- old/main.c	2010-08-11 15:45:49.000000000 -0700
+++ new/main.c	2017-05-28 14:23:13.458611147 -0700
@@ -1,4 +1,4 @@
-/* main.c   by Michael Thorpe   2010-08-11 */
+/* main.c   by Michael Thorpe   2017-05-28 */
 
 #include <stdio.h>
 #include <string.h>
@@ -59,7 +59,13 @@
 	int i;
 
 	if(register_objtype(&bytefunc_objtype)
+#ifdef USE_BIGINT
+	|| register_objtype(&bigint_objtype)
+#endif
 	|| register_objtype(&cons_objtype)
+#ifdef USE_FLOAT
+	|| register_objtype(&float_objtype)
+#endif
 	|| register_objtype(&integer_objtype)
 	|| register_objtype(&nil_objtype)
 	|| register_objtype(&quote_objtype)
--- old/string.c	2009-05-19 12:27:26.000000000 -0700
+++ new/string.c	2017-05-28 14:25:54.694629799 -0700
@@ -1,4 +1,4 @@
-/* string.c   by Michael Thorpe   2009-05-19 */
+/* string.c   by Michael Thorpe   2017-05-28 */
 
 #include <assert.h>
 #include <ctype.h>
@@ -72,7 +72,13 @@
 	char *s;
 	unsigned long l;
 
-	if(str->type != &string_objtype || str->value.s.len>sizeof(buf)-1)
+	if(str->type != &string_objtype)
+		return(throwtypeerror(str));
+#ifdef USE_BIGINT
+	if(10<str->value.s.len)
+		return(string_to_bigint(str));
+#endif
+	if(str->value.s.len>sizeof(buf)-1)
 		return(throwtypeerror(str));
 	memcpy(buf,str->value.s.data,str->value.s.len);
 	buf[str->value.s.len]='\0';
--- old/float.c	1969-12-31 16:00:00.000000000 -0800
+++ new/float.c	2017-05-29 11:39:24.526704045 -0700
@@ -0,0 +1,569 @@
+/* float.c   by Michael Thorpe   2017-05-29 */
+
+#include <ctype.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "lisp.h"
+
+/* Define this if you want string_to_float to forbid "infinity" or "nan" */
+/* #define NO_INFINITY_OR_NAN */
+
+static obj eobj={&float_objtype,{refcount:1},{f:M_E}};
+static obj piobj={&float_objtype,{refcount:1},{f:M_PI}};
+
+/* Takes an integer and upconverts it to a float */
+static obj *promote(obj *in) {
+	obj *out;
+
+	out=new_object(&float_objtype);
+	if(out)
+		out->value.f=in->value.i;
+	DECREF(in);
+	return(out);
+}
+
+/* Takes a newly-minted float and downconverts it to an integer if possible */
+static obj *reduce(obj *in) {
+	if(in->value.f<LONG_MIN || LONG_MAX<in->value.f)
+		return(in);
+	if(ceil(in->value.f) != in->value.f)
+		return(in);
+	in->type=&integer_objtype;
+	in->value.i=in->value.f;
+	return(in);
+}
+
+static obj *f_func(obj *a,double func(double)) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a)
+			return(0);
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a)
+			return(0);
+	}
+#endif
+	if(a->type != &float_objtype)
+		return(throwtypeerror(a));
+	r=new_object(&float_objtype);
+	if(!r) {
+		DECREF(a);
+		return(0);
+	}
+	r->value.f=func(a->value.f);
+	DECREF(a);
+	return(r);
+}
+
+static obj *f_intfunc(obj *a,double func(double)) {
+	obj *r;
+
+	if(a->type != &float_objtype)
+		return(throwtypeerror(a));
+	if(a->value.f<LONG_MIN || LONG_MAX<a->value.f)
+		return(throwrangecheck(a));
+	r=new_object(&integer_objtype);
+	if(!r) {
+		DECREF(a);
+		return(0);
+	}
+	r->value.i=func(a->value.f);
+	DECREF(a);
+	return(r);
+}
+
+obj *addf(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#endif
+	if(a->type != &float_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==b->type) {
+		b=bigint_to_float(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#endif
+	if(b->type != &float_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&float_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	r->value.f=a->value.f+b->value.f;
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+obj *div2f(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==b->type) {
+#ifdef NO_FDIV_BY_0
+		if(0==b->value.i) {
+			DECREF(b);
+			return(throw(INCREF(divideby0error),a));
+		}
+#endif
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==b->type) {
+		b=bigint_to_float(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#endif
+	if(b->type != &float_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+#ifdef NO_FDIV_BY_0
+	if(0==b->value.f) {
+		DECREF(b);
+		return(throw(INCREF(divideby0error),a));
+	}
+#endif
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#endif
+	if(a->type != &float_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	r=new_object(&float_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	r->value.f=a->value.f/b->value.f;
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+static obj *ffabs(obj *a) {
+	return(f_func(a,fabs));
+}
+
+static obj *facos(obj *a) {
+	return(f_func(a,acos));
+}
+
+static obj *fasin(obj *a) {
+	return(f_func(a,asin));
+}
+
+obj *fatan2(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#endif
+	if(a->type != &float_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==b->type) {
+		b=bigint_to_float(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#endif
+	if(b->type != &float_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&float_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	r->value.f=atan2(a->value.f,b->value.f);
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+static obj *fceiling(obj *a) {
+	return(f_intfunc(a,ceil));
+}
+
+static obj *fcos(obj *a) {
+	return(f_func(a,cos));
+}
+
+static obj *fexp(obj *a) {
+	return(f_func(a,exp));
+}
+
+static obj *ffloor(obj *a) {
+	return(f_intfunc(a,floor));
+}
+
+static obj *flog(obj *a) {
+	return(f_func(a,log));
+}
+
+static obj *fround(obj *a) {
+	return(f_intfunc(a,round));
+}
+
+static obj *fsin(obj *a) {
+	return(f_func(a,sin));
+}
+
+static obj *fsqrt(obj *a) {
+	return(f_func(a,sqrt));
+}
+
+static obj *ftan(obj *a) {
+	return(f_func(a,tan));
+}
+
+obj *mulf(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#endif
+	if(a->type != &float_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==b->type) {
+		b=bigint_to_float(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#endif
+	if(b->type != &float_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&float_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	r->value.f=a->value.f*b->value.f;
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+#define NUMCMP_LT 1
+#define NUMCMP_EQ 2
+#define NUMCMP_GT 4
+obj *numcmpf(obj *a,obj *b,int desired) {
+	int cmp;
+	obj *o;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#endif
+	if(a->type != &float_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==b->type) {
+		b=bigint_to_float(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#endif
+	if(b->type != &float_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	cmp=0;
+	if(a->value.f == b->value.f)
+		cmp=NUMCMP_EQ;
+	if(a->value.f < b->value.f)
+		cmp=NUMCMP_LT;
+	if(a->value.f > b->value.f)
+		cmp=NUMCMP_GT;
+	if(!cmp) {
+		o=cons(a,b);
+		if(o)
+			return(throwrangecheck(o));
+		return(o);
+	}
+	DECREF(a);
+	DECREF(b);
+	if(cmp&desired)
+		return(INCREF(&trueobj));
+	else
+		return(INCREF(&nilobj));
+}
+
+obj *string_to_float(obj *str) {
+	obj *o;
+	char *buf,*end;
+	double f;
+#ifdef NO_INFINITY_OR_NAN
+	int i;
+#endif
+
+	if(str->type != &string_objtype)
+		return(throwtypeerror(str));
+	if(0==str->value.s.len)
+		return(throwtypeerror(str));
+#ifdef NO_INFINITY_OR_NAN
+	i=0;
+	if('+'==str->value.s.data[i] || '-'==str->value.s.data[i]) {
+		i++;
+		if(i==str->value.s.len)
+			return(throwtypeerror(str));
+	}
+	if('.'==str->value.s.data[i]) {
+		i++;
+		if(i==str->value.s.len)
+			return(throwtypeerror(str));
+	}
+	if(!isdigit(str->value.s.data[i]))
+		return(throwtypeerror(str));
+#endif
+	buf=(char *)malloc(str->value.s.len+1);
+	if(!buf) {
+		DECREF(str);
+		return(throwoom());
+	}
+	memcpy(buf,str->value.s.data,str->value.s.len);
+	buf[str->value.s.len]='\0';
+	f=strtod(buf,&end);
+	if(*end) {
+		free(buf);
+		return(throwtypeerror(str));
+	}
+	free(buf);
+	DECREF(str);
+	o=new_object(&float_objtype);
+	if(o)
+		o->value.f=f;
+	return(o);
+}
+
+obj *subf(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==a->type) {
+		a=bigint_to_float(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+#endif
+	if(a->type != &float_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#ifdef USE_BIGINT
+	if(&bigint_objtype==b->type) {
+		b=bigint_to_float(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+#endif
+	if(b->type != &float_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&float_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	r->value.f=a->value.f-b->value.f;
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+static obj *float_tostring(obj *in) {
+	char buf[30];
+	int i;
+
+	i=snprintf(buf,sizeof(buf),"%.15g",in->value.f);
+	if(i<=0)
+		return(throwrangecheck(in));
+	DECREF(in);
+	return(new_string(buf,i));
+}
+
+static int float_init() {
+	if(store_builtin_ns1("acos",facos)
+	|| store_builtin_ns1("asin",fasin)
+	|| store_builtin_ns2("atan",fatan2)
+	|| store_builtin_ns1("ceiling",fceiling)
+	|| store_builtin_ns1("cos",fcos)
+	|| store_object("#e",INCREF(&eobj))
+	|| store_builtin_ns1("exp",fexp)
+	|| store_builtin_ns1("abs",ffabs)
+	|| store_builtin_ns1("floor",ffloor)
+	|| store_builtin_ns1("log",flog)
+	|| store_object("#pi",INCREF(&piobj))
+	|| store_builtin_ns1("round",fround)
+	|| store_builtin_ns1("sin",fsin)
+	|| store_builtin_ns1("sqrt",fsqrt)
+	|| store_builtin_ns1("string->float",string_to_float)
+	|| store_builtin_ns1("tan",ftan))
+		return(1);
+	return(0);
+}
+
+objtype float_objtype={
+	name: "float",
+	tostring: float_tostring,
+	init: float_init,
+};
+
--- old/bigint.c	1969-12-31 16:00:00.000000000 -0800
+++ new/bigint.c	2017-05-29 11:10:53.758869690 -0700
@@ -0,0 +1,436 @@
+/* bigint.c   by Michael Thorpe   2017-05-29 */
+
+#include <ctype.h>
+#include <gmp.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include "lisp.h"
+
+static obj *gmperror;
+
+/* Takes an integer and upconverts it to a bigint */
+static obj *promote(obj *in) {
+	obj *out;
+
+	out=new_object(&bigint_objtype);
+	if(out) {
+/* FIXME: What happens if GMP runs out of memory here? */
+		mpz_init_set_si(out->value.bi,in->value.i);
+	}
+	DECREF(in);
+	return(out);
+}
+
+/* Takes a newly-minted bigint and downconverts it to an integer if possible */
+static obj *reduce(obj *in) {
+	signed long i;
+
+	if(!mpz_fits_slong_p(in->value.bi))
+		return(in);
+	i=mpz_get_si(in->value.bi);
+	mpz_clear(in->value.bi);
+	in->type=&integer_objtype;
+	in->value.i=i;
+	return(in);
+}
+
+obj *addb(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+	if(a->type != &bigint_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+	if(b->type != &bigint_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&bigint_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	mpz_init(r->value.bi);
+/* FIXME: What happens if GMP runs out of memory here? */
+	mpz_add(r->value.bi,a->value.bi,b->value.bi);
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+obj *bitselectb(obj *a,obj *if0,obj *if1) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(if0);
+			DECREF(if1);
+			return(0);
+		}
+	}
+	if(a->type != &bigint_objtype) {
+		DECREF(if0);
+		DECREF(if1);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==if0->type) {
+		if0=promote(if0);
+		if(!if0) {
+			DECREF(a);
+			DECREF(if1);
+			return(0);
+		}
+	}
+	if(if0->type != &bigint_objtype) {
+		DECREF(a);
+		DECREF(if1);
+		return(throwtypeerror(if0));
+	}
+	if(&integer_objtype==if1->type) {
+		if1=promote(if1);
+		if(!if1) {
+			DECREF(a);
+			DECREF(if0);
+			return(0);
+		}
+	}
+	if(if1->type != &bigint_objtype) {
+		DECREF(a);
+		DECREF(if0);
+		return(throwtypeerror(if1));
+	}
+/*
+ * For each bit in a, selects the corresponding bit in if0 if it's 0 or
+ * the corresponding bit in if1 if it's 1.  For instance:
+ *   (bitwise-not a) is (bitselect a -1 0)
+ *   (bitwise-and a b) is (bitselect a 0 b)
+ *   (bitwise-or a b) is (bitselect a -1 b)
+ *   (bitwise-xor a b) is (bitselect a b (bitwise-not b))
+ * We use the equivalence that (if0&!a)|(if1&a) == (if0^if1)&a)^if0.
+*/
+	r=new_object(&bigint_objtype);
+	if(r) {
+		mpz_init(r->value.bi);
+		mpz_xor(r->value.bi,if0->value.bi,if1->value.bi);
+		mpz_and(r->value.bi,r->value.bi,a->value.bi);
+		mpz_xor(r->value.bi,r->value.bi,if0->value.bi);
+		r=reduce(r);
+	}
+	DECREF(a);
+	DECREF(if0);
+	DECREF(if1);
+	return(r);
+}
+
+obj *div2b(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==b->type) {
+		if(0==b->value.i) {
+			DECREF(b);
+			return(throw(INCREF(divideby0error),a));
+		}
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+	if(b->type != &bigint_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+	if(a->type != &bigint_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	r=new_object(&bigint_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	mpz_init(r->value.bi);
+/* FIXME: What happens if GMP runs out of memory here? */
+	mpz_tdiv_q(r->value.bi,a->value.bi,b->value.bi);
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+/* Returns #t, #f, or the input number if it's not sure */
+obj *isprime(obj *n) {
+	int res;
+
+	if(&integer_objtype==n->type) {
+		n=promote(n);
+		if(!n)
+			return(0);
+	}
+	if(n->type != &bigint_objtype)
+		return(throwtypeerror(n));
+	res=mpz_probab_prime_p(n->value.bi,32);
+	if(2==res) {
+		DECREF(n);
+		return(INCREF(&trueobj));
+	}
+	if(0==res) {
+		DECREF(n);
+		return(INCREF(&nilobj));
+	}
+/* We almost always don't need to reduce, but just in case: */
+	return(reduce(n));
+}
+
+obj *mulb(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+	if(a->type != &bigint_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+	if(b->type != &bigint_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&bigint_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	mpz_init(r->value.bi);
+/* FIXME: What happens if GMP runs out of memory here? */
+	mpz_mul(r->value.bi,a->value.bi,b->value.bi);
+	DECREF(a);
+	DECREF(b);
+/* We only need to reduce() here when -LONG_MIN is multiplied by -1: */
+	return(reduce(r));
+}
+
+obj *nextprime(obj *n) {
+	obj *r;
+
+	if(&integer_objtype==n->type) {
+		n=promote(n);
+		if(!n)
+			return(0);
+	}
+	if(n->type != &bigint_objtype)
+		return(throwtypeerror(n));
+	r=new_object(&bigint_objtype);
+	if(r) {
+		mpz_init(r->value.bi);
+		mpz_nextprime(r->value.bi,n->value.bi);
+	}
+	DECREF(n);
+	return(r);
+}
+
+#define NUMCMP_LT 1
+#define NUMCMP_EQ 2
+#define NUMCMP_GT 4
+obj *numcmpb(obj *a,obj *b,int desired) {
+	int cmp;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+	if(a->type != &bigint_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&bigint_objtype==b->type)
+		cmp=mpz_cmp(a->value.bi,b->value.bi);
+	else if(&integer_objtype==b->type)
+		cmp=mpz_cmp_si(a->value.bi,b->value.i);
+	else {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	DECREF(a);
+	DECREF(b);
+	if(cmp<0)
+		cmp=NUMCMP_LT;
+	else if(0==cmp)
+		cmp=NUMCMP_EQ;
+	else
+		cmp=NUMCMP_GT;
+	if(cmp&desired)
+		return(INCREF(&trueobj));
+	else
+		return(INCREF(&nilobj));
+}
+
+obj *string_to_bigint(obj *str) {
+	int i;
+	obj *o;
+	char *buf;
+
+	if(str->type != &string_objtype)
+		return(throwtypeerror(str));
+	if(0==str->value.s.len)
+		return(throwtypeerror(str));
+	for(i=('-'==str->value.s.data[0]);i<str->value.s.len;i++) {
+		if(!isdigit(str->value.s.data[i]))
+			return(throwtypeerror(str));
+	}
+	buf=(char *)malloc(str->value.s.len+1);
+	if(!buf) {
+		DECREF(str);
+		return(throwoom());
+	}
+	memcpy(buf,str->value.s.data,str->value.s.len);
+	buf[str->value.s.len]='\0';
+	DECREF(str);
+	o=new_object(&bigint_objtype);
+	if(!o) {
+		free(buf);
+		return(0);
+	}
+	if(mpz_init_set_str(o->value.bi,buf,10)) {
+		free(buf);
+		DECREF(o);
+		return(INCREF(gmperror));
+	}
+	free(buf);
+	return(reduce(o));
+}
+
+obj *subb(obj *a,obj *b) {
+	obj *r;
+
+	if(&integer_objtype==a->type) {
+		a=promote(a);
+		if(!a) {
+			DECREF(b);
+			return(0);
+		}
+	}
+	if(a->type != &bigint_objtype) {
+		DECREF(b);
+		return(throwtypeerror(a));
+	}
+	if(&integer_objtype==b->type) {
+		b=promote(b);
+		if(!b) {
+			DECREF(a);
+			return(0);
+		}
+	}
+	if(b->type != &bigint_objtype) {
+		DECREF(a);
+		return(throwtypeerror(b));
+	}
+	r=new_object(&bigint_objtype);
+	if(!r) {
+		DECREF(a);
+		DECREF(b);
+		return(0);
+	}
+	mpz_init(r->value.bi);
+/* FIXME: What happens if GMP runs out of memory here? */
+	mpz_sub(r->value.bi,a->value.bi,b->value.bi);
+	DECREF(a);
+	DECREF(b);
+	return(reduce(r));
+}
+
+#ifdef USE_FLOAT
+obj *bigint_to_float(obj *bi) {
+	obj *f;
+
+	if(bi->type != &bigint_objtype)
+		return(throwtypeerror(bi));
+	f=new_object(&float_objtype);
+	if(f)
+		f->value.f=mpz_get_d(bi->value.bi);
+	DECREF(bi);
+	return(f);
+}
+#endif
+
+static void bigint_nuke(obj *in) {
+	mpz_clear(in->value.bi);
+}
+
+static obj *bigint_tostring(obj *in) {
+	obj *out;
+	char *s;
+	int i;
+
+	s=mpz_get_str(0,10,in->value.bi);
+	if(!s)
+		return(throw(gmperror,in));
+	DECREF(in);
+	i=strlen(s);
+	out=new_string(s,i);
+	free(s);
+	return(out);
+}
+
+static int bigint_init() {
+	if(!(gmperror=new_word("gmp-error",9))
+#ifdef USE_FLOAT
+	|| store_builtin_ns1("bigint->float",bigint_to_float)
+#endif
+	|| store_builtin_ns1("prime?",isprime)
+	|| store_builtin_ns1("next-prime",nextprime))
+		return(1);
+	return(0);
+}
+
+static void bigint_exit() {
+	DECREF(gmperror); gmperror=0;
+}
+
+objtype bigint_objtype={
+	name: "bigint",
+	predropobj: bigint_nuke,
+	tostring: bigint_tostring,
+	init: bigint_init,
+	exit: bigint_exit,
+};
+
--- old/compiler.lisp	2017-05-24 15:57:51.908892070 -0700
+++ new/compiler.lisp	2017-05-28 14:06:24.622491116 -0700
@@ -649,6 +649,8 @@
 			(ifelse (and (<= -0x8000000 code) (<= code 0x7FFFFFF))
 				`((pushi . ,code))
 				`((localobj . ,code))))
+		(('bigint 'float)
+			`((localobj . ,code)))
 		(('nil)
 			`((nil . 0)))
 		(('bytefunc 'func 'rawfunc 'stream 'string)
--- old/functions.lisp	2017-05-24 16:03:59.020887692 -0700
+++ new/functions.lisp	2017-05-29 09:50:03.709943724 -0700
@@ -1,4 +1,4 @@
-; functions.lisp   by Michael Thorpe   2017-05-24
+; functions.lisp   by Michael Thorpe   2017-05-29
 
 (define (pair? o)
 	(eq? (object-type o) 'cons))
@@ -32,7 +32,9 @@
 (define (write-newline file)
 	(write-char file 10))
 (define (write-object file obj)
-	(write-string file (->string obj)))
+	(ifelse (eq? obj #t)
+		(write-string file "#t")
+		(write-string file (->string obj))))
 (define (#dprint o)
 	(while o
 		(write-object #standard-out (car o))
@@ -249,7 +251,9 @@
 			()
 			(catch 'type-error
 				(string->integer buffer)
-				(string->symbol buffer)))))
+				(catch 'type-error
+					(string->float buffer)
+					(string->symbol buffer))))))
 
 (define (read-object stream)
 	(let ((c (skip-whitespace stream))
@@ -301,7 +305,7 @@
 			#t
 			(ifelse (neq? ot-a (object-type b))
 				#f
-				(ifelse (eq? ot-a 'integer)
+				(ifelse (or (eq? ot-a 'integer) (eq? ot-a 'bigint) (eq? ot-a 'float))
 					(= a b)
 					(ifelse (eq? ot-a 'quote)
 						(eqv? (unquote a) (unquote b))
--- old/obj/compiler.c	2017-05-25 12:44:20.293407213 -0700
+++ new/obj/compiler.c	2017-05-29 11:18:25.466899769 -0700
@@ -3174,11 +3174,11 @@
 	if(!o) return(1);
 	DECREF(o);
 
-// (define (byte-compile-helper code stackitems flowstack) (if (and byte-compile-debug (neq? 'cons (object-type code))) (dprint 'byte-compile-helper code stackitems flowstack)) (switch (object-type code) (('word) (let ((pos (list-index stackitems code))) (ifelse pos (list (cons 'index pos)) (switch code ((#f '#f) (list (list 'nil . '0))) (('#t) (list (list 'nil . '0) (list 'not . '0))) (('#exception) (list (list 'extype . '0))) (('#exceptionvalue) (list (list 'exvalue . '0))) (else (list (cons 'localobj code) (list 'lookup . '0))))))) (('cons) (let ((helper (get #function-compilers (car code)))) (ifelse helper (helper code stackitems flowstack) (byte-compile-helper-unknown-function code stackitems flowstack)))) (('quote) (set code (unquote code)) (ifelse code (ifelse (eq? (object-type code) 'integer) (byte-compile-helper code stackitems flowstack) (list (cons 'localobj code))) (list (list 'nil . '0)))) (('integer) (ifelse (and (<= -134217728 code) (<= code 134217727)) (list (cons 'pushi code)) (list (cons 'localobj code)))) (('nil) (list (list 'nil . '0))) (('bytefunc 'func 'rawfunc 'stream 'string) (list (cons 'localobj code))) (else (throw 'unknown-objtype code))))
-// (#define 'byte-compile-helper (byte-compile '(code stackitems flowstack) '(#prog2of2 (#ifelse (#and byte-compile-debug '(not (eq? 'cons (object-type code)))) '(#dprint (cons 'byte-compile-helper (cons code (cons stackitems (cons flowstack #f))))) '#f) '(#let '#word-1232056856 (object-type code) '(#ifelse (eq? #word-1232056856 'word) '(#let 'pos (list-index stackitems code) '(#ifelse pos '(cons (cons 'index pos) #f) '(#let '#word-1745790417 code '(#ifelse (#or (eq? #word-1745790417 #f) '(eq? #word-1745790417 '#f)) '(cons (cons 'nil '0) #f) '(#ifelse (eq? #word-1745790417 '#t) '(cons (cons 'nil '0) (cons (cons 'not '0) #f)) '(#ifelse (eq? #word-1745790417 '#exception) '(cons (cons 'extype '0) #f) '(#ifelse (eq? #word-1745790417 '#exceptionvalue) '(cons (cons 'exvalue '0) #f) '(cons (cons 'localobj code) (cons (cons 'lookup '0) #f))))))))) '(#ifelse (eq? #word-1232056856 'cons) '(#let 'helper (get #function-compilers (car code)) '(#ifelse helper '(helper code stackitems flowstack) '(byte-compile-helper-unknown-function code stackitems flowstack))) '(#ifelse (eq? #word-1232056856 'quote) '(#prog2of2 (#set 'code (unquote code)) '(#ifelse code '(#ifelse (eq? (object-type code) 'integer) '(byte-compile-helper code stackitems flowstack) '(cons (cons 'localobj code) #f)) '(cons (cons 'nil '0) #f))) '(#ifelse (eq? #word-1232056856 'integer) '(#ifelse (#and (<= -134217728 code) '(<= code 134217727)) '(cons (cons 'pushi code) #f) '(cons (cons 'localobj code) #f)) '(#ifelse (eq? #word-1232056856 'nil) '(cons (cons 'nil '0) #f) '(#ifelse (#or (#or (#or (#or (eq? #word-1232056856 'bytefunc) '(eq? #word-1232056856 'func)) '(eq? #word-1232056856 'rawfunc)) '(eq? #word-1232056856 'stream)) '(eq? #word-1232056856 'string)) '(cons (cons 'localobj code) #f) '(throw 'unknown-objtype code)))))))))))
-// (#lambda "\x83#LlI\x88\x46\x44\x81L\x83IO=!\x94\x46\x82L\x83I\x83I\x83I0cccc\x83Ll\x81\x43\x81G0D\x82IOI\x84L=\x80\xEC\x46\x82I\x84I\x85Ll\x82\x43I\x8A\x46\x86L\x81Ic0c\x80\xD2G\x84II0=I\x84TDI0=\x88\x46\x87Lic0c\xBBGI\x88L=\x8D\x46\x87Lic\x89Lic0cc\xA8GI\x8AL=\x88\x46\x8BLic0c\x9AGI\x8CL=\x88\x46\x8DLic0c\x8CG\x8EL\x86Ic\x8FLic0ccPP\x81\xDAGI\x81L=\xA9\x46\x90Ll\x84Ia\x91Ll\x82\x43I\x8C\x46\x84I\x84I\x84I\x83I\x83\x43\x8BG\x84I\x84I\x84I\x92Ll\x83\x43P\x81\xABGI\x93L=\xB2\x46\x83I,I\x84PD\x83I\x9E\x46\x83IO\x94L=\x8D\x46\x83I\x83I\x83I\x82Ll\x83\x43\x87G\x8EL\x84Ic0c\x86G\x87Lic0c\x80\xF3GI\x94L=\xAB\x46\xC0\x80\x80\x80i\x84I\x83?I\x8A\x46\x44\x83I\xBF\xFF\xFF\xFFi\x83?\x89\x46\x95L\x84Ic0c\x87G\x8EL\x84Ic0c\x80\xC2GI\x87L=\x88\x46\x87Lic0c\xB4GI\x96L=I\x85TDI\x97L=I\x85TDI\x98L=I\x85TDI\x99L=I\x85TDI\x9AL=\x89\x46\x8EL\x84Ic0c\x85G\x83I\x9BL:P\x83R" '(byte-compile-debug cons byte-compile-helper #dprint word list-index index nil #t not #exception extype #exceptionvalue exvalue localobj lookup #function-compilers get byte-compile-helper-unknown-function quote integer pushi bytefunc func rawfunc stream string unknown-objtype))
-// (#lambda "\x83#LlI\x88\x46\x44\x81L\x83IO=!\x93\x46\x82L\x83I\x83I\x83I0cccc\x83Ll\x81\x43\x44\x82IOI\x84L=\x80\xEC\x46\x82I\x84I\x85Ll\x82\x43I\x8A\x46\x86L\x81Ic0c\x80\xD2G\x84II0=I\x84TDI0=\x88\x46\x87Lic0c\xBBGI\x88L=\x8D\x46\x87Lic\x89Lic0cc\xA8GI\x8AL=\x88\x46\x8BLic0c\x9AGI\x8CL=\x88\x46\x8DLic0c\x8CG\x8EL\x86Ic\x8FLic0ccPP\x81\xDBGI\x81L=\xA9\x46\x90Ll\x84Ia\x91Ll\x82\x43I\x8C\x46\x84I\x84I\x84I\x83I\x83\x43\x8BG\x84I\x84I\x84I\x92Ll\x83\x43P\x81\xACGI\x93L=\xB2\x46\x83I,\x83P\x83I\xA0\x46\x83IO\x94L=\x8E\x46\x83I\x83I\x83I\x82Ll\x83\x43\x81\x87G\x8EL\x84Ic0c\x80\xFDG\x87Lic0c\x80\xF4GI\x94L=\xAC\x46\xC0\x80\x80\x80i\x84I\x83?I\x8A\x46\x44\x83I\xBF\xFF\xFF\xFFi\x83?\x8A\x46\x95L\x84Ic0c\x80\xCCG\x8EL\x84Ic0c\x80\xC2GI\x87L=\x88\x46\x87Lic0c\xB4GI\x96L=I\x85TDI\x97L=I\x85TDI\x98L=I\x85TDI\x99L=I\x85TDI\x9AL=\x89\x46\x8EL\x84Ic0c\x85G\x83I\x9BL:P\x82P\x81\x44R" '(byte-compile-debug cons byte-compile-helper #dprint word list-index index nil #t not #exception extype #exceptionvalue exvalue localobj lookup #function-compilers get byte-compile-helper-unknown-function quote integer pushi bytefunc func rawfunc stream string unknown-objtype))
-	s=new_string("\x83#LlI\x88\x46\x44\x81L\x83IO=!\x93\x46\x82L\x83I\x83I\x83I0cccc\x83Ll\x81\x43\x44\x82IOI\x84L=\x80\xEC\x46\x82I\x84I\x85Ll\x82\x43I\x8A\x46\x86L\x81Ic0c\x80\xD2G\x84II0=I\x84TDI0=\x88\x46\x87Lic0c\xBBGI\x88L=\x8D\x46\x87Lic\x89Lic0cc\xA8GI\x8AL=\x88\x46\x8BLic0c\x9AGI\x8CL=\x88\x46\x8DLic0c\x8CG\x8EL\x86Ic\x8FLic0ccPP\x81\xDBGI\x81L=\xA9\x46\x90Ll\x84Ia\x91Ll\x82\x43I\x8C\x46\x84I\x84I\x84I\x83I\x83\x43\x8BG\x84I\x84I\x84I\x92Ll\x83\x43P\x81\xACGI\x93L=\xB2\x46\x83I,\x83P\x83I\xA0\x46\x83IO\x94L=\x8E\x46\x83I\x83I\x83I\x82Ll\x83\x43\x81\x87G\x8EL\x84Ic0c\x80\xFDG\x87Lic0c\x80\xF4GI\x94L=\xAC\x46\xC0\x80\x80\x80i\x84I\x83?I\x8A\x46\x44\x83I\xBF\xFF\xFF\xFFi\x83?\x8A\x46\x95L\x84Ic0c\x80\xCCG\x8EL\x84Ic0c\x80\xC2GI\x87L=\x88\x46\x87Lic0c\xB4GI\x96L=I\x85TDI\x97L=I\x85TDI\x98L=I\x85TDI\x99L=I\x85TDI\x9AL=\x89\x46\x8EL\x84Ic0c\x85G\x83I\x9BL:P\x82P\x81\x44R",379);
+// (define (byte-compile-helper code stackitems flowstack) (if (and byte-compile-debug (neq? 'cons (object-type code))) (dprint 'byte-compile-helper code stackitems flowstack)) (switch (object-type code) (('word) (let ((pos (list-index stackitems code))) (ifelse pos (list (cons 'index pos)) (switch code ((#f '#f) (list (list 'nil . '0))) (('#t) (list (list 'nil . '0) (list 'not . '0))) (('#exception) (list (list 'extype . '0))) (('#exceptionvalue) (list (list 'exvalue . '0))) (else (list (cons 'localobj code) (list 'lookup . '0))))))) (('cons) (let ((helper (get #function-compilers (car code)))) (ifelse helper (helper code stackitems flowstack) (byte-compile-helper-unknown-function code stackitems flowstack)))) (('quote) (set code (unquote code)) (ifelse code (ifelse (eq? (object-type code) 'integer) (byte-compile-helper code stackitems flowstack) (list (cons 'localobj code))) (list (list 'nil . '0)))) (('integer) (ifelse (and (<= -134217728 code) (<= code 134217727)) (list (cons 'pushi code)) (list (cons 'localobj code)))) (('bigint 'float) (list (cons 'localobj code))) (('nil) (list (list 'nil . '0))) (('bytefunc 'func 'rawfunc 'stream 'string) (list (cons 'localobj code))) (else (throw 'unknown-objtype code))))
+// (#define 'byte-compile-helper (byte-compile '(code stackitems flowstack) '(#prog2of2 (#ifelse (#and byte-compile-debug '(not (eq? 'cons (object-type code)))) '(#dprint (cons 'byte-compile-helper (cons code (cons stackitems (cons flowstack #f))))) '#f) '(#let '#word-1232056856 (object-type code) '(#ifelse (eq? #word-1232056856 'word) '(#let 'pos (list-index stackitems code) '(#ifelse pos '(cons (cons 'index pos) #f) '(#let '#word-1745790417 code '(#ifelse (#or (eq? #word-1745790417 #f) '(eq? #word-1745790417 '#f)) '(cons (cons 'nil '0) #f) '(#ifelse (eq? #word-1745790417 '#t) '(cons (cons 'nil '0) (cons (cons 'not '0) #f)) '(#ifelse (eq? #word-1745790417 '#exception) '(cons (cons 'extype '0) #f) '(#ifelse (eq? #word-1745790417 '#exceptionvalue) '(cons (cons 'exvalue '0) #f) '(cons (cons 'localobj code) (cons (cons 'lookup '0) #f))))))))) '(#ifelse (eq? #word-1232056856 'cons) '(#let 'helper (get #function-compilers (car code)) '(#ifelse helper '(helper code stackitems flowstack) '(byte-compile-helper-unknown-function code stackitems flowstack))) '(#ifelse (eq? #word-1232056856 'quote) '(#prog2of2 (#set 'code (unquote code)) '(#ifelse code '(#ifelse (eq? (object-type code) 'integer) '(byte-compile-helper code stackitems flowstack) '(cons (cons 'localobj code) #f)) '(cons (cons 'nil '0) #f))) '(#ifelse (eq? #word-1232056856 'integer) '(#ifelse (#and (<= -134217728 code) '(<= code 134217727)) '(cons (cons 'pushi code) #f) '(cons (cons 'localobj code) #f)) '(#ifelse (#or (eq? #word-1232056856 'bigint) '(eq? #word-1232056856 'float)) '(cons (cons 'localobj code) #f) '(#ifelse (eq? #word-1232056856 'nil) '(cons (cons 'nil '0) #f) '(#ifelse (#or (#or (#or (#or (eq? #word-1232056856 'bytefunc) '(eq? #word-1232056856 'func)) '(eq? #word-1232056856 'rawfunc)) '(eq? #word-1232056856 'stream)) '(eq? #word-1232056856 'string)) '(cons (cons 'localobj code) #f) '(throw 'unknown-objtype code))))))))))))
+// (#lambda "\x83#LlI\x88\x46\x44\x81L\x83IO=!\x94\x46\x82L\x83I\x83I\x83I0cccc\x83Ll\x81\x43\x81G0D\x82IOI\x84L=\x80\xEC\x46\x82I\x84I\x85Ll\x82\x43I\x8A\x46\x86L\x81Ic0c\x80\xD2G\x84II0=I\x84TDI0=\x88\x46\x87Lic0c\xBBGI\x88L=\x8D\x46\x87Lic\x89Lic0cc\xA8GI\x8AL=\x88\x46\x8BLic0c\x9AGI\x8CL=\x88\x46\x8DLic0c\x8CG\x8EL\x86Ic\x8FLic0ccPP\x81\xF2GI\x81L=\xA9\x46\x90Ll\x84Ia\x91Ll\x82\x43I\x8C\x46\x84I\x84I\x84I\x83I\x83\x43\x8BG\x84I\x84I\x84I\x92Ll\x83\x43P\x81\xC3GI\x93L=\xB2\x46\x83I,I\x84PD\x83I\x9E\x46\x83IO\x94L=\x8D\x46\x83I\x83I\x83I\x82Ll\x83\x43\x87G\x8EL\x84Ic0c\x86G\x87Lic0c\x81\x8BGI\x94L=\xAB\x46\xC0\x80\x80\x80i\x84I\x83?I\x8A\x46\x44\x83I\xBF\xFF\xFF\xFFi\x83?\x89\x46\x95L\x84Ic0c\x87G\x8EL\x84Ic0c\x80\xDAGI\x96L=I\x85TDI\x97L=\x8A\x46\x8EL\x84Ic0c\x80\xC2GI\x87L=\x88\x46\x87Lic0c\xB4GI\x98L=I\x85TDI\x99L=I\x85TDI\x9AL=I\x85TDI\x9BL=I\x85TDI\x9CL=\x89\x46\x8EL\x84Ic0c\x85G\x83I\x9DL:P\x83R" '(byte-compile-debug cons byte-compile-helper #dprint word list-index index nil #t not #exception extype #exceptionvalue exvalue localobj lookup #function-compilers get byte-compile-helper-unknown-function quote integer pushi bigint float bytefunc func rawfunc stream string unknown-objtype))
+// (#lambda "\x83#LlI\x88\x46\x44\x81L\x83IO=!\x93\x46\x82L\x83I\x83I\x83I0cccc\x83Ll\x81\x43\x44\x82IOI\x84L=\x80\xEC\x46\x82I\x84I\x85Ll\x82\x43I\x8A\x46\x86L\x81Ic0c\x80\xD2G\x84II0=I\x84TDI0=\x88\x46\x87Lic0c\xBBGI\x88L=\x8D\x46\x87Lic\x89Lic0cc\xA8GI\x8AL=\x88\x46\x8BLic0c\x9AGI\x8CL=\x88\x46\x8DLic0c\x8CG\x8EL\x86Ic\x8FLic0ccPP\x81\xF3GI\x81L=\xA9\x46\x90Ll\x84Ia\x91Ll\x82\x43I\x8C\x46\x84I\x84I\x84I\x83I\x83\x43\x8BG\x84I\x84I\x84I\x92Ll\x83\x43P\x81\xC4GI\x93L=\xB2\x46\x83I,\x83P\x83I\xA0\x46\x83IO\x94L=\x8E\x46\x83I\x83I\x83I\x82Ll\x83\x43\x81\x9FG\x8EL\x84Ic0c\x81\x95G\x87Lic0c\x81\x8CGI\x94L=\xAC\x46\xC0\x80\x80\x80i\x84I\x83?I\x8A\x46\x44\x83I\xBF\xFF\xFF\xFFi\x83?\x8A\x46\x95L\x84Ic0c\x80\xE4G\x8EL\x84Ic0c\x80\xDAGI\x96L=I\x85TDI\x97L=\x8A\x46\x8EL\x84Ic0c\x80\xC2GI\x87L=\x88\x46\x87Lic0c\xB4GI\x98L=I\x85TDI\x99L=I\x85TDI\x9AL=I\x85TDI\x9BL=I\x85TDI\x9CL=\x89\x46\x8EL\x84Ic0c\x85G\x83I\x9DL:P\x82P\x81\x44R" '(byte-compile-debug cons byte-compile-helper #dprint word list-index index nil #t not #exception extype #exceptionvalue exvalue localobj lookup #function-compilers get byte-compile-helper-unknown-function quote integer pushi bigint float bytefunc func rawfunc stream string unknown-objtype))
+	s=new_string("\x83#LlI\x88\x46\x44\x81L\x83IO=!\x93\x46\x82L\x83I\x83I\x83I0cccc\x83Ll\x81\x43\x44\x82IOI\x84L=\x80\xEC\x46\x82I\x84I\x85Ll\x82\x43I\x8A\x46\x86L\x81Ic0c\x80\xD2G\x84II0=I\x84TDI0=\x88\x46\x87Lic0c\xBBGI\x88L=\x8D\x46\x87Lic\x89Lic0cc\xA8GI\x8AL=\x88\x46\x8BLic0c\x9AGI\x8CL=\x88\x46\x8DLic0c\x8CG\x8EL\x86Ic\x8FLic0ccPP\x81\xF3GI\x81L=\xA9\x46\x90Ll\x84Ia\x91Ll\x82\x43I\x8C\x46\x84I\x84I\x84I\x83I\x83\x43\x8BG\x84I\x84I\x84I\x92Ll\x83\x43P\x81\xC4GI\x93L=\xB2\x46\x83I,\x83P\x83I\xA0\x46\x83IO\x94L=\x8E\x46\x83I\x83I\x83I\x82Ll\x83\x43\x81\x9FG\x8EL\x84Ic0c\x81\x95G\x87Lic0c\x81\x8CGI\x94L=\xAC\x46\xC0\x80\x80\x80i\x84I\x83?I\x8A\x46\x44\x83I\xBF\xFF\xFF\xFFi\x83?\x8A\x46\x95L\x84Ic0c\x80\xE4G\x8EL\x84Ic0c\x80\xDAGI\x96L=I\x85TDI\x97L=\x8A\x46\x8EL\x84Ic0c\x80\xC2GI\x87L=\x88\x46\x87Lic0c\xB4GI\x98L=I\x85TDI\x99L=I\x85TDI\x9AL=I\x85TDI\x9BL=I\x85TDI\x9CL=\x89\x46\x8EL\x84Ic0c\x85G\x83I\x9DL:P\x82P\x81\x44R",403);
 	if(!s) return(1);
 	c=INCREF(&nilobj);
 	o=new_word("unknown-objtype",15);
@@ -3205,6 +3205,14 @@
 	if(!o) return(1);
 	c=cons(o,c);
 	if(!c) return(1);
+	o=new_word("float",5);
+	if(!o) return(1);
+	c=cons(o,c);
+	if(!c) return(1);
+	o=new_word("bigint",6);
+	if(!o) return(1);
+	c=cons(o,c);
+	if(!c) return(1);
 	o=new_word("pushi",5);
 	if(!o) return(1);
 	c=cons(o,c);
--- old/obj/functions.c	2017-05-25 12:44:20.941407146 -0700
+++ new/obj/functions.c	2017-05-29 11:18:26.130899809 -0700
@@ -158,18 +158,22 @@
 	if(!o) return(1);
 	DECREF(o);
 
-// (define (write-object file obj) (write-string file (->string obj)))
-// (#define 'write-object (byte-compile '(file obj) '(write-string file (->string obj))))
-// (#lambda "\x82#\x81I\x81ILl\x81\x43\x81Ll\x82\x43\x82R" '(->string write-string))
-// (#lambda "\x82#\x81I\x81ILl\x81\x43\x81P\x81P\x81Ll\x82r" '(->string write-string))
-	s=new_string("\x82#\x81I\x81ILl\x81\x43\x81P\x81P\x81Ll\x82r",19);
+// (define (write-object file obj) (ifelse (eq? obj #t) (write-string file "#t") (write-string file (->string obj))))
+// (#define 'write-object (byte-compile '(file obj) '(#ifelse (eq? obj #t) '(write-string file "#t") '(write-string file (->string obj)))))
+// (#lambda "\x82#I0!=\x8A\x46\x81IL\x81Ll\x82\x43\x8EG\x81I\x81I\x82Ll\x81\x43\x81Ll\x82\x43\x82R" '("#t" write-string ->string))
+// (#lambda "\x82#I0!=\x8C\x46\x81IL\x81P\x81P\x81Ll\x82r\x81I\x81I\x82Ll\x81\x43\x81P\x81P\x81Ll\x82r" '("#t" write-string ->string))
+	s=new_string("\x82#I0!=\x8C\x46\x81IL\x81P\x81P\x81Ll\x82r\x81I\x81I\x82Ll\x81\x43\x81P\x81P\x81Ll\x82r",38);
 	if(!s) return(1);
 	c=INCREF(&nilobj);
+	o=new_word("->string",8);
+	if(!o) return(1);
+	c=cons(o,c);
+	if(!c) return(1);
 	o=new_word("write-string",12);
 	if(!o) return(1);
 	c=cons(o,c);
 	if(!c) return(1);
-	o=new_word("->string",8);
+	o=new_string("#t",2);
 	if(!o) return(1);
 	c=cons(o,c);
 	if(!c) return(1);
@@ -971,17 +975,21 @@
 	o=set(s,o);
 	if(!o) return(1);
 	DECREF(o);
-// (define (read-token stream c) (let ((buffer (new-string 512)) (i 0)) (loop (if (= i (string-length buffer)) (set buffer (expand-string buffer))) (put-char buffer i c) (set i (+ i 1)) (catch 'end-of-file (set c (peek-char stream)) (exit-loop)) (if (is-space c) (exit-loop)) (unless (is-ascii c) (exit-loop)) (if (get-using-= #character-macros c) (exit-loop)) (set c (read-char stream))) (set buffer (substring buffer 0 i)) (ifelse (string-eqv? buffer "#f") #f (catch 'type-error (string->integer buffer) (string->symbol buffer)))))
-// (#define 'read-token (byte-compile '(stream c) '(#let 'buffer (new-string 512) '(#let 'i 0 '(#prog2of2 (#loop '(#prog2of2 (#ifelse (= i (string-length buffer)) '(#set 'buffer (expand-string buffer)) '#f) '(#prog2of2 (put-char buffer i c) '(#prog2of2 (#set 'i (+ i 1)) '(#prog2of2 (#catch 'end-of-file '(#set 'c (peek-char stream)) '(#exit-loop #f)) '(#prog2of2 (#ifelse (is-space c) '(#exit-loop #f) '#f) '(#prog2of2 (#ifelse (is-ascii c) '#f '(#exit-loop #f)) '(#prog2of2 (#ifelse (get-using-= #character-macros c) '(#exit-loop #f) '#f) '(#set 'c (read-char stream)))))))))) '(#prog2of2 (#set 'buffer (substring buffer 0 i)) '(#ifelse (string-eqv? buffer "#f") '#f '(#catch 'type-error '(string->integer buffer) '(string->symbol buffer)))))))))
-// (#lambda "\x82#\x84\x80iLl\x81\x43iI\x82I\x81Ll\x81\x43\x82?\x8C\x46\x81I\x82Ll\x81\x43I\x82P\x81G0D\x81I\x81I\x84I\x83Ll\x83\x43\x44I\x81i+I\x81PD\x8D{\x83I\x84Ll\x81\x43I\x83P}\x8DG\x85L1=\x83T21:0\x80\xC2GD\x82I\x86Ll\x81\x43\x85\x46\x30\xB5G\x81G0D\x82I\x87Ll\x81\x43\x83\x46\x30\x83G0\xA2GD\x88Ll\x83I\x89Ll\x82\x43\x85\x46\x30\x92G\x81G0D\x83I\x8ALl\x81\x43I\x83PD\xFE\xF4GD\x81Ii\x82I\x8BLl\x83\x43I\x82PD\x81I\x8CL\x8DLl\x82\x43\x83\x46\x30\x9CG\x8A{\x81I\x8ELl\x81\x43}\x90G\x8FL1=\x83T21:\x81I\x90Ll\x81\x43PP\x82R" '(new-string string-length expand-string put-char peek-char end-of-file is-space is-ascii #character-macros get-using-= read-char substring "#f" string-eqv? string->integer type-error string->symbol))
-// (#lambda "\x82#\x84\x80iLl\x81\x43iI\x82I\x81Ll\x81\x43\x82?\x89\x46\x81I\x82Ll\x81\x43\x81P\x81I\x81I\x84I\x83Ll\x83\x43\x44\x81i+\x8E{\x83I\x84Ll\x81\x43I\x83P}D\x8BG\x85L1=\x83T21:\xAAG\x82I\x86Ll\x81\x43\xA1T\x82I\x87Ll\x81\x43\x98\x46\x88Ll\x83I\x89Ll\x82\x43\x8CT\x83I\x8ALl\x81\x43\x82P\xFF\x97G\x81Ii\x82I\x8BLl\x83\x43\x81P\x81I\x8CL\x8DLl\x82\x43\x83\x46\x30\x9CG\x8A{\x81I\x8ELl\x81\x43}\x90G\x8FL1=\x83T21:\x81I\x90Ll\x81\x43PP\x81PDR" '(new-string string-length expand-string put-char peek-char end-of-file is-space is-ascii #character-macros get-using-= read-char substring "#f" string-eqv? string->integer type-error string->symbol))
-	s=new_string("\x82#\x84\x80iLl\x81\x43iI\x82I\x81Ll\x81\x43\x82?\x89\x46\x81I\x82Ll\x81\x43\x81P\x81I\x81I\x84I\x83Ll\x83\x43\x44\x81i+\x8E{\x83I\x84Ll\x81\x43I\x83P}D\x8BG\x85L1=\x83T21:\xAAG\x82I\x86Ll\x81\x43\xA1T\x82I\x87Ll\x81\x43\x98\x46\x88Ll\x83I\x89Ll\x82\x43\x8CT\x83I\x8ALl\x81\x43\x82P\xFF\x97G\x81Ii\x82I\x8BLl\x83\x43\x81P\x81I\x8CL\x8DLl\x82\x43\x83\x46\x30\x9CG\x8A{\x81I\x8ELl\x81\x43}\x90G\x8FL1=\x83T21:\x81I\x90Ll\x81\x43PP\x81PDR",175);
+// (define (read-token stream c) (let ((buffer (new-string 512)) (i 0)) (loop (if (= i (string-length buffer)) (set buffer (expand-string buffer))) (put-char buffer i c) (set i (+ i 1)) (catch 'end-of-file (set c (peek-char stream)) (exit-loop)) (if (is-space c) (exit-loop)) (unless (is-ascii c) (exit-loop)) (if (get-using-= #character-macros c) (exit-loop)) (set c (read-char stream))) (set buffer (substring buffer 0 i)) (ifelse (string-eqv? buffer "#f") #f (catch 'type-error (string->integer buffer) (catch 'type-error (string->float buffer) (string->symbol buffer))))))
+// (#define 'read-token (byte-compile '(stream c) '(#let 'buffer (new-string 512) '(#let 'i 0 '(#prog2of2 (#loop '(#prog2of2 (#ifelse (= i (string-length buffer)) '(#set 'buffer (expand-string buffer)) '#f) '(#prog2of2 (put-char buffer i c) '(#prog2of2 (#set 'i (+ i 1)) '(#prog2of2 (#catch 'end-of-file '(#set 'c (peek-char stream)) '(#exit-loop #f)) '(#prog2of2 (#ifelse (is-space c) '(#exit-loop #f) '#f) '(#prog2of2 (#ifelse (is-ascii c) '#f '(#exit-loop #f)) '(#prog2of2 (#ifelse (get-using-= #character-macros c) '(#exit-loop #f) '#f) '(#set 'c (read-char stream)))))))))) '(#prog2of2 (#set 'buffer (substring buffer 0 i)) '(#ifelse (string-eqv? buffer "#f") '#f '(#catch 'type-error '(string->integer buffer) '(#catch 'type-error '(string->float buffer) '(string->symbol buffer))))))))))
+// (#lambda "\x82#\x84\x80iLl\x81\x43iI\x82I\x81Ll\x81\x43\x82?\x8C\x46\x81I\x82Ll\x81\x43I\x82P\x81G0D\x81I\x81I\x84I\x83Ll\x83\x43\x44I\x81i+I\x81PD\x8D{\x83I\x84Ll\x81\x43I\x83P}\x8DG\x85L1=\x83T21:0\x80\xC2GD\x82I\x86Ll\x81\x43\x85\x46\x30\xB5G\x81G0D\x82I\x87Ll\x81\x43\x83\x46\x30\x83G0\xA2GD\x88Ll\x83I\x89Ll\x82\x43\x85\x46\x30\x92G\x81G0D\x83I\x8ALl\x81\x43I\x83PD\xFE\xF4GD\x81Ii\x82I\x8BLl\x83\x43I\x82PD\x81I\x8CL\x8DLl\x82\x43\x83\x46\x30\xB1G\x8A{\x81I\x8ELl\x81\x43}\xA5G\x8FL1=\x83T21:\x8A{\x81I\x90Ll\x81\x43}\x90G\x8FL1=\x83T21:\x81I\x91Ll\x81\x43PP\x82R" '(new-string string-length expand-string put-char peek-char end-of-file is-space is-ascii #character-macros get-using-= read-char substring "#f" string-eqv? string->integer type-error string->float string->symbol))
+// (#lambda "\x82#\x84\x80iLl\x81\x43iI\x82I\x81Ll\x81\x43\x82?\x89\x46\x81I\x82Ll\x81\x43\x81P\x81I\x81I\x84I\x83Ll\x83\x43\x44\x81i+\x8E{\x83I\x84Ll\x81\x43I\x83P}D\x8BG\x85L1=\x83T21:\xAAG\x82I\x86Ll\x81\x43\xA1T\x82I\x87Ll\x81\x43\x98\x46\x88Ll\x83I\x89Ll\x82\x43\x8CT\x83I\x8ALl\x81\x43\x82P\xFF\x97G\x81Ii\x82I\x8BLl\x83\x43\x81P\x81I\x8CL\x8DLl\x82\x43\x83\x46\x30\xB1G\x8A{\x81I\x8ELl\x81\x43}\xA5G\x8FL1=\x83T21:\x8A{\x81I\x90Ll\x81\x43}\x90G\x8FL1=\x83T21:\x81I\x91Ll\x81\x43PP\x81PDR" '(new-string string-length expand-string put-char peek-char end-of-file is-space is-ascii #character-macros get-using-= read-char substring "#f" string-eqv? string->integer type-error string->float string->symbol))
+	s=new_string("\x82#\x84\x80iLl\x81\x43iI\x82I\x81Ll\x81\x43\x82?\x89\x46\x81I\x82Ll\x81\x43\x81P\x81I\x81I\x84I\x83Ll\x83\x43\x44\x81i+\x8E{\x83I\x84Ll\x81\x43I\x83P}D\x8BG\x85L1=\x83T21:\xAAG\x82I\x86Ll\x81\x43\xA1T\x82I\x87Ll\x81\x43\x98\x46\x88Ll\x83I\x89Ll\x82\x43\x8CT\x83I\x8ALl\x81\x43\x82P\xFF\x97G\x81Ii\x82I\x8BLl\x83\x43\x81P\x81I\x8CL\x8DLl\x82\x43\x83\x46\x30\xB1G\x8A{\x81I\x8ELl\x81\x43}\xA5G\x8FL1=\x83T21:\x8A{\x81I\x90Ll\x81\x43}\x90G\x8FL1=\x83T21:\x81I\x91Ll\x81\x43PP\x81PDR",196);
 	if(!s) return(1);
 	c=INCREF(&nilobj);
 	o=new_word("string->symbol",14);
 	if(!o) return(1);
 	c=cons(o,c);
 	if(!c) return(1);
+	o=new_word("string->float",13);
+	if(!o) return(1);
+	c=cons(o,c);
+	if(!c) return(1);
 	o=new_word("type-error",10);
 	if(!o) return(1);
 	c=cons(o,c);
@@ -1222,11 +1230,11 @@
 	if(!o) return(1);
 	DECREF(o);
 
-// (define (eqv? a b) (let ((ot-a (object-type a))) (ifelse (eq? a b) #t (ifelse (neq? ot-a (object-type b)) #f (ifelse (eq? ot-a 'integer) (= a b) (ifelse (eq? ot-a 'quote) (eqv? (unquote a) (unquote b)) (ifelse (eq? ot-a 'string) (string-eqv? a b) (ifelse (eq? ot-a 'cons) (and (eqv? (car a) (car b)) (eqv? (cdr a) (cdr b))) #f))))))))
-// (#define 'eqv? (byte-compile '(a b) '(#let 'ot-a (object-type a) '(#ifelse (eq? a b) '#t '(#ifelse (not (eq? ot-a (object-type b))) '#f '(#ifelse (eq? ot-a 'integer) '(= a b) '(#ifelse (eq? ot-a 'quote) '(eqv? (unquote a) (unquote b)) '(#ifelse (eq? ot-a 'string) '(string-eqv? a b) '(#ifelse (eq? ot-a 'cons) '(#and (eqv? (car a) (car b)) '(eqv? (cdr a) (cdr b))) '#f)))))))))
-// (#lambda "\x82#\x81IO\x82I\x82I=\x85\x46\x30!\x80\xE1GI\x82IO=!\x84\x46\x30\x80\xD5GIL=\x89\x46\x82I\x82I\x82?\x80\xC7GI\x81L=\x8D\x46\x82I,\x82I,\x82Ll\x82\x43\xB4GI\x83L=\x8B\x46\x82I\x82I\x84Ll\x82\x43\xA3GI\x85L=\x9C\x46\x82Ia\x82Ia\x82Ll\x82\x43I\x8C\x46\x44\x82Id\x82Id\x82Ll\x82\x43\x81G0P\x82R" '(integer quote eqv? string string-eqv? cons))
-// (#lambda "\x82#\x81IO\x82I\x82I=\x85\x46\x30!\x80\xE1GI\x82IO=!\x84\x46\x30\x80\xD5GIL=\x89\x46\x82I\x82I\x82?\x80\xC7GI\x81L=\x8D\x46\x82I,\x82I,\x82Ll\x82\x43\xB4GI\x83L=\x8B\x46\x82I\x82I\x84Ll\x82\x43\xA3GI\x85L=\x9C\x46\x82Ia\x82Ia\x82Ll\x82\x43I\x8C\x46\x44\x82Id\x82Id\x82Ll\x82\x43\x81G0P\x81PDR" '(integer quote eqv? string string-eqv? cons))
-	s=new_string("\x82#\x81IO\x82I\x82I=\x85\x46\x30!\x80\xE1GI\x82IO=!\x84\x46\x30\x80\xD5GIL=\x89\x46\x82I\x82I\x82?\x80\xC7GI\x81L=\x8D\x46\x82I,\x82I,\x82Ll\x82\x43\xB4GI\x83L=\x8B\x46\x82I\x82I\x84Ll\x82\x43\xA3GI\x85L=\x9C\x46\x82Ia\x82Ia\x82Ll\x82\x43I\x8C\x46\x44\x82Id\x82Id\x82Ll\x82\x43\x81G0P\x81PDR",119);
+// (define (eqv? a b) (let ((ot-a (object-type a))) (ifelse (eq? a b) #t (ifelse (neq? ot-a (object-type b)) #f (ifelse (or (eq? ot-a 'integer) (eq? ot-a 'bigint) (eq? ot-a 'float)) (= a b) (ifelse (eq? ot-a 'quote) (eqv? (unquote a) (unquote b)) (ifelse (eq? ot-a 'string) (string-eqv? a b) (ifelse (eq? ot-a 'cons) (and (eqv? (car a) (car b)) (eqv? (cdr a) (cdr b))) #f))))))))
+// (#define 'eqv? (byte-compile '(a b) '(#let 'ot-a (object-type a) '(#ifelse (eq? a b) '#t '(#ifelse (not (eq? ot-a (object-type b))) '#f '(#ifelse (#or (#or (eq? ot-a 'integer) '(eq? ot-a 'bigint)) '(eq? ot-a 'float)) '(= a b) '(#ifelse (eq? ot-a 'quote) '(eqv? (unquote a) (unquote b)) '(#ifelse (eq? ot-a 'string) '(string-eqv? a b) '(#ifelse (eq? ot-a 'cons) '(#and (eqv? (car a) (car b)) '(eqv? (cdr a) (cdr b))) '#f)))))))))
+// (#lambda "\x82#\x81IO\x82I\x82I=\x85\x46\x30!\x80\xF1GI\x82IO=!\x84\x46\x30\x80\xE5GIL=I\x85TDI\x81L=I\x85TDI\x82L=\x89\x46\x82I\x82I\x82?\x80\xC7GI\x83L=\x8D\x46\x82I,\x82I,\x84Ll\x82\x43\xB4GI\x85L=\x8B\x46\x82I\x82I\x86Ll\x82\x43\xA3GI\x87L=\x9C\x46\x82Ia\x82Ia\x84Ll\x82\x43I\x8C\x46\x44\x82Id\x82Id\x84Ll\x82\x43\x81G0P\x82R" '(integer bigint float quote eqv? string string-eqv? cons))
+// (#lambda "\x82#\x81IO\x82I\x82I=\x85\x46\x30!\x80\xF1GI\x82IO=!\x84\x46\x30\x80\xE5GIL=I\x85TDI\x81L=I\x85TDI\x82L=\x89\x46\x82I\x82I\x82?\x80\xC7GI\x83L=\x8D\x46\x82I,\x82I,\x84Ll\x82\x43\xB4GI\x85L=\x8B\x46\x82I\x82I\x86Ll\x82\x43\xA3GI\x87L=\x9C\x46\x82Ia\x82Ia\x84Ll\x82\x43I\x8C\x46\x44\x82Id\x82Id\x84Ll\x82\x43\x81G0P\x81PDR" '(integer bigint float quote eqv? string string-eqv? cons))
+	s=new_string("\x82#\x81IO\x82I\x82I=\x85\x46\x30!\x80\xF1GI\x82IO=!\x84\x46\x30\x80\xE5GIL=I\x85TDI\x81L=I\x85TDI\x82L=\x89\x46\x82I\x82I\x82?\x80\xC7GI\x83L=\x8D\x46\x82I,\x82I,\x84Ll\x82\x43\xB4GI\x85L=\x8B\x46\x82I\x82I\x86Ll\x82\x43\xA3GI\x87L=\x9C\x46\x82Ia\x82Ia\x84Ll\x82\x43I\x8C\x46\x44\x82Id\x82Id\x84Ll\x82\x43\x81G0P\x81PDR",135);
 	if(!s) return(1);
 	c=INCREF(&nilobj);
 	o=new_word("cons",4);
@@ -1249,6 +1257,14 @@
 	if(!o) return(1);
 	c=cons(o,c);
 	if(!c) return(1);
+	o=new_word("float",5);
+	if(!o) return(1);
+	c=cons(o,c);
+	if(!c) return(1);
+	o=new_word("bigint",6);
+	if(!o) return(1);
+	c=cons(o,c);
+	if(!c) return(1);
 	o=new_word("integer",7);
 	if(!o) return(1);
 	c=cons(o,c);
