--- old/CHANGELOG	Sat Aug 13 20:44:19 2005
+++ CHANGELOG	Fri Aug 26 07:14:19 2005
@@ -48,3 +48,10 @@
 Changed dprint to allow for multiple arguments.
 Removed many uses of real_eqv as eqv? words are now eq?.
 Implemented eqv? in preload.lisp and removed it from the .h and .c's.
+
+2005-08-26: 1.6: Modified eqv? to not need the short-circuit macro.
+Added #let function and let macro.
+Added const to char* in the store_builtin_* #defines.
+Removed define-local.
+Changed define_local into real_define and made it not decref its arguments.
+Removed subscope.
--- old/Makefile	Fri Aug 12 13:49:53 2005
+++ Makefile	Fri Aug 26 07:12:28 2005
@@ -3,7 +3,7 @@
 CFLAGS=-O2 -Wall -Werror
 SRCS=builtin.c cons.c func.c integer.c main.c nil.c quote.c rawfunc.c reader.c scope.c stream.c string.c throw.c util.c word.c
 BUILDDIR=obj/
-VERSION=1.5
+VERSION=1.6
 -include .local.Makefile
 
 $(BUILDDIR)mikelisp : $(SRCS:%.c=$(BUILDDIR)%.o) lisp.h
--- old/lisp.h	Sat Aug 13 20:41:37 2005
+++ lisp.h	Fri Aug 26 00:54:43 2005
@@ -1,4 +1,4 @@
-/* lisp.h   by Michael Thorpe   2005-08-13 */
+/* lisp.h   by Michael Thorpe   2005-08-26 */
 
 #ifndef OBJ_H
 #define OBJ_H
@@ -116,19 +116,19 @@
 void drop_scope(scope *scope);
 #define decscoperef(s) do{if(!--(s)->refcount)drop_scope(s);}while(0)
 obj *define(scope *scope,obj *name,obj *value);
-obj *define_local(scope *scope,obj *name,obj *value);
 #define incscoperef(s) ((s)->refcount++,(s))
 obj *lookup(scope *scope,obj *name);
 scope *newscope(scope *parent);
+int real_define(scope *scope,obj *name,obj *value);
 int store_builtin(unsigned int numargs,unsigned int wantscope,const char *name,obj *(*rawfunc)());
-#define store_builtin_ns0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)()))store_builtin)(0,0,name,func)
-#define store_builtin_ns1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(obj *)))store_builtin)(1,0,name,func)
-#define store_builtin_ns2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(obj *,obj *)))store_builtin)(2,0,name,func)
-#define store_builtin_ns3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(obj *,obj *,obj *)))store_builtin)(3,0,name,func)
-#define store_builtin_s0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *)))store_builtin)(0,1,name,func)
-#define store_builtin_s1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *,obj *)))store_builtin)(1,1,name,func)
-#define store_builtin_s2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *,obj *,obj *)))store_builtin)(2,1,name,func)
-#define store_builtin_s3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *,obj *,obj *,obj *)))store_builtin)(3,1,name,func)
+#define store_builtin_ns0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)()))store_builtin)(0,0,name,func)
+#define store_builtin_ns1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(obj *)))store_builtin)(1,0,name,func)
+#define store_builtin_ns2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(obj *,obj *)))store_builtin)(2,0,name,func)
+#define store_builtin_ns3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(obj *,obj *,obj *)))store_builtin)(3,0,name,func)
+#define store_builtin_s0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *)))store_builtin)(0,1,name,func)
+#define store_builtin_s1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *,obj *)))store_builtin)(1,1,name,func)
+#define store_builtin_s2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *,obj *,obj *)))store_builtin)(2,1,name,func)
+#define store_builtin_s3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *,obj *,obj *,obj *)))store_builtin)(3,1,name,func)
 int store_object(const char *name,obj *o);
 extern scope *globalscope;
 #ifdef DEBUG
--- old/builtin.c	Sat Aug 13 20:41:51 2005
+++ builtin.c	Fri Aug 26 07:13:33 2005
@@ -1,4 +1,4 @@
-/* builtin.c   by Michael Thorpe   2005-08-13 */
+/* builtin.c   by Michael Thorpe   2005-08-26 */
 
 #include <ctype.h>
 #include <limits.h>
@@ -245,10 +245,8 @@
 	for(new=list;&cons_objtype==new->type;new=new->value.c.d)
 		length++;
 	if(!length) {
-		tmp=define_local(incscoperef(s),incref(mapvar),incref(list));
-		if(!tmp)
+		if(real_define(s,mapvar,list))
 			goto fail_nostart;
-		decref(tmp);
 		decref(list);
 		return(evaluate(s,expr));
 	}
@@ -258,10 +256,8 @@
 	new=start;
 	old=list;
 	while(1) {
-		tmp=define_local(incscoperef(s),incref(mapvar),incref(CAR(old)));
-		if(!tmp)
+		if(real_define(s,mapvar,CAR(old)))
 			goto fail;
-		decref(tmp);
 		tmp=evaluate(incscoperef(s),incref(expr));
 		if(!tmp)
 			goto fail;
@@ -273,10 +269,8 @@
 		new=CDR(new);
 	}
 	if(&nilobj != old) {
-		tmp=define_local(incscoperef(s),incref(mapvar),incref(old));
-		if(!tmp)
+		if(real_define(s,mapvar,old))
 			goto fail;
-		decref(tmp);
 		tmp=evaluate(incscoperef(s),incref(expr));
 		if(!tmp)
 			goto fail;
@@ -403,14 +397,6 @@
 	return((o)->type->tostring(o));
 }
 
-static obj *subscope(scope *s,obj *o) {
-	s=newscope(s);
-	if(s)
-		return(evaluate(s,o));
-	decref(o);
-	return(0);
-}
-
 int builtin_init() {
 	if(!(divideby0error=newword("divide-by-zero",14))
 	|| !(exitloop=newword("exit-loop",9))
@@ -440,8 +426,7 @@
 	|| store_builtin_s1("#loop",loop)
 	|| store_builtin_s2("#map",map)
 	|| store_builtin_s2("#prog2of2",prog2of2)
-	|| store_builtin_ns1("->string",tostring)
-	|| store_builtin_s1("#subscope",subscope))
+	|| store_builtin_ns1("->string",tostring))
 		return(1);
 	INC_KNOWN_OBJECTS(5);
 	return(0);
--- old/func.c	Sat Aug 13 20:42:09 2005
+++ func.c	Fri Aug 26 00:54:44 2005
@@ -1,12 +1,10 @@
-/* func.c   by Michael Thorpe   2005-08-13 */
+/* func.c   by Michael Thorpe   2005-08-26 */
 
 #include <string.h>
 #include "lisp.h"
 
 /* This function does not incref/decref anything; returns 0 on success */
 static int bindlist(scope *s,obj *names,obj *values) {
-	obj *tmp;
-
 	if(names==&nilobj) {
 		if(values==&nilobj)
 			return(0);
@@ -19,12 +17,7 @@
 			return(-1);
 		return(bindlist(s,CDR(names),CDR(values)));
 	}
-	tmp=define_local(incscoperef(s),incref(names),incref(values));
-	if(tmp) {
-		decref(tmp);
-		return(0);
-	}
-	return(-1);
+	return(real_define(s,names,values));
 }
 
 static obj *applyfunc(scope *s,obj *func,obj *args) {
--- old/scope.c	Sat Aug 13 19:57:11 2005
+++ scope.c	Fri Aug 26 00:54:43 2005
@@ -1,4 +1,4 @@
-/* scope.c   by Michael Thorpe   2005-08-13 */
+/* scope.c   by Michael Thorpe   2005-08-26 */
 
 #include <stdlib.h>
 #include <string.h>
@@ -40,32 +40,18 @@
 	entry *e;
 
 	e=real_lookup(s,name);
+	decscoperef(s);
 	if(e) {
 		decref(e->value);
 		e->value=value;
-		decscoperef(s);
 		return(name);
 	}
-	incscoperef(globalscope);
-	decscoperef(s);
-	return(define_local(globalscope,name,value));
-}
-
-obj *define_local(scope *s,obj *name,obj *value) {
-	entry *e;
-
-	e=(entry *)malloc(sizeof(entry));
-	if(!e) {
-		decscoperef(s);
-		decref(name);
+	if(real_define(globalscope,name,value)) {
 		decref(value);
-		return(throwoom());
+		decref(name);
+		return(0);
 	}
-	e->next=s->firstentry;
-	e->name=incref(name);
-	e->value=value;
-	s->firstentry=e;
-	decscoperef(s);
+	decref(value);
 	return(name);
 }
 
@@ -93,6 +79,29 @@
 	decscoperef(t);
 }
 
+static obj *let(scope *scope,obj *var,obj *val,obj *block) {
+	/* We can short-circuit the scope creation if its refcount is 1: */
+	if(1 != scope->refcount) {
+		scope=newscope(scope);
+		if(!scope) {
+			decref(var);
+			decref(val);
+			decref(block);
+			return(0);
+		}
+	}
+	if(real_define(scope,var,val)) {
+		decref(var);
+		decref(val);
+		decscoperef(scope);
+		decref(block);
+		return(0);
+	}
+	decref(var);
+	decref(val);
+	return(evaluate(scope,block));
+}
+
 obj *lookup(scope *scope,obj *name) {
 	entry *e;
 	obj *val;
@@ -128,8 +137,24 @@
 	return(new);
 }
 
+int real_define(scope *s,obj *name,obj *value) {
+	entry *e;
+
+	e=(entry *)malloc(sizeof(entry));
+	if(!e) {
+		throwoom();
+		return(-1);
+	}
+	e->next=s->firstentry;
+	e->name=incref(name);
+	e->value=incref(value);
+	s->firstentry=e;
+	return(0);
+}
+
 int store_builtin(unsigned int numargs,unsigned int wantscope,const char *name,obj *(*rawfunc)()) {
 	obj *key,*func;
+	int i;
 
 	key=newword(name,strlen(name));
 	if(!key)
@@ -142,31 +167,30 @@
 	func->value.rawfunc.numargs=numargs;
 	func->value.rawfunc.wantscope=wantscope;
 	func->value.rawfunc.rawfuncptr.ns0=rawfunc;
-	key=define_local(incscoperef(globalscope),key,func);
-	if(!key)
-		return(-1);
+	i=real_define(globalscope,key,func);
 	decref(key);
-	return(0);
+	decref(func);
+	return(i);
 }
 
 int store_object(const char *name,obj *o) {
 	obj *key;
+	int i;
 
 	key=newword(name,strlen(name));
 	if(!key)
 		return(-1);
-	key=define_local(incscoperef(globalscope),key,o);
-	if(!key)
-		return(-1);
+	i=real_define(globalscope,key,o);
 	decref(key);
-	return(0);
+	decref(o);
+	return(i);
 }
 
 int scope_init() {
 	if(!(globalscope=newscope(incscoperef(&topscope)))
 	|| !(undefined_error=newword("undefined",9))
 	|| store_builtin_s2("#define",define)
-	|| store_builtin_s2("#define-local",define_local))
+	|| store_builtin_s3("#let",let))
 		return(1);
 	INC_KNOWN_OBJECTS(1);
 	return(0);
--- old/throw.c	Sat Aug 13 19:58:15 2005
+++ throw.c	Fri Aug 26 00:54:44 2005
@@ -1,4 +1,4 @@
-/* throw.c   by Michael Thorpe   2005-08-13 */
+/* throw.c   by Michael Thorpe   2005-08-26 */
 
 #include "lisp.h"
 
@@ -12,7 +12,7 @@
 obj *exceptionvar,*exceptionvaluevar;
 
 static obj *catch(scope *s,obj *type,obj *func,obj *handler) {
-	obj *e,*o,*tmp;
+	obj *e,*o;
 
 	o=evaluate(incscoperef(s),func);
 	if(!o && (type==exception || type==&nilobj)) {
@@ -24,22 +24,22 @@
 		}
 		e=exception;
 		exception=incref(&nilobj);
-		tmp=define_local(incscoperef(s),incref(exceptionvar),e);
-		if(!tmp) {
+		if(real_define(s,exceptionvar,e)) {
+			decref(e);
 			decscoperef(s);
 			decref(handler);
 			return(0);
 		}
-		decref(tmp);
+		decref(e);
 		e=exceptionvalue;
 		exceptionvalue=incref(&nilobj);
-		tmp=define_local(incscoperef(s),incref(exceptionvaluevar),e);
-		if(!tmp) {
+		if(real_define(s,exceptionvaluevar,e)) {
+			decref(e);
 			decscoperef(s);
 			decref(handler);
 			return(0);
 		}
-		decref(tmp);
+		decref(e);
 		return(evaluate(s,handler));
 	}
 	decref(type);
--- old/preload.lisp	Sat Aug 13 20:40:44 2005
+++ preload.lisp	Fri Aug 26 07:13:07 2005
@@ -1,4 +1,4 @@
-; preload.lisp   by Michael Thorpe   2005-08-13
+; preload.lisp   by Michael Thorpe   2005-08-26
 
 (#define '#f (= 1 2))
 (#define '#t (= 1 1))
@@ -20,16 +20,13 @@
 	(#lambda '(o)
 		'(#ifelse (pair? o)
 			'(#prog2of2
-				(#prog2of2
-					(#define-local 'macro (get macroexpansions (car o)))
+				(#let 'macro (get macroexpansions (car o))
 					'(#ifelse macro
-						'(#prog2of2
-							(#prog2of2
-								(#define-local 'cdr-o (cdr o))
-								'(#define-local 'expansion (macro . cdr-o)))
-							'(#ifelse (eq? expansion dont-macro-expand)
-								'#f
-								'(#define-local 'o (macro-expand expansion))))
+						'(#let 'cdr-o (cdr o)
+							'(#let 'expansion (macro . cdr-o)
+								'(#ifelse (eq? expansion dont-macro-expand)
+									'#f
+									'(#define 'o (macro-expand expansion)))))
 						'#f))
 				'(#map '(macro-expand #object) o))
 			'o)))
@@ -44,14 +41,18 @@
 		'(#ifelse (pair? name)
 			'(list '#define (quote (car name)) (list 'lambda (cdr name) (cons 'progn value)))
 			'(list '#define (quote name) . value))))
-(#macro-define 'define-local
-	(#lambda '(name . value)
-		'(#ifelse (pair? name)
-			'(list '#define-local (quote (car name)) (list 'lambda (cdr name) (cons 'progn value)))
-			'(list '#define-local (quote name) . value))))
 (#macro-define 'lambda
 	(#lambda '(args . prog)
 		'(list '#lambda (quote args) (quote (macro-expand (cons 'progn prog))))))
+(#macro-define 'let
+	(#lambda '(vars . prog)
+		'(#ifelse (pair? vars)
+			'(list
+				'#let
+				(quote (car (car vars)))
+				(cons 'progn (cdr (car vars)))
+				(quote (macro-expand (cons 'let (cons (cdr vars) prog)))))
+			'(cons 'progn prog))))
 (#macro-define 'macro-define
 	(#lambda '(name . value)
 		'(#ifelse (pair? name)
@@ -81,9 +82,6 @@
 (#macro-define 'map
 	(#lambda '(mapper . args)
 		'(list '#map (quote (macro-expand mapper)) . args)))
-(#macro-define 'subscope
-	(#lambda 'body
-		'(list '#subscope (quote (macro-expand (cons 'progn body))))))
 
 (#define 'evaluate-file
 	(#lambda '(file)
@@ -131,19 +129,14 @@
 	(list 'ifelse bool
 		(cons 'progn progs)
 		#f))
-(macro-define (let* bindings . body)
-	(ifelse bindings
-		(list 'progn
-			(list 'define-local (car (car bindings)) (cons 'progn (cdr (car bindings))))
-			(cons 'let* (cons (cdr bindings) body)))
-		(cons 'progn body)))
 (macro-define (next-loop) (list 'throw ''next-loop #f))
 (macro-define (not a) (list 'ifelse a #f #t))
 (macro-define (or a . b)
 	(ifelse b
-		(list 'subscope
-			(list 'define-local 'a a)
-			(list 'ifelse 'a 'a (cons 'or b)))
+		(let ((var (unique-word)))
+			(list 'let
+				(list (list var a))
+				(list 'ifelse var var (cons 'or b))))
 		a))
 (macro-define (unless bool . body)
 	(list 'ifelse bool
@@ -157,8 +150,8 @@
 
 (define (reverse/append straight newtail)
 	(while straight
-		(define-local newtail (cons (car straight) newtail))
-		(define-local straight (cdr straight)))
+		(define newtail (cons (car straight) newtail))
+		(define straight (cdr straight)))
 	newtail)
 (define (reverse straight)
 	(reverse/append straight '()))
@@ -172,7 +165,7 @@
 (define (dprint . o)
 	(while o
 		(write-object #standard-out (car o))
-		(define-local o (cdr o))
+		(define o (cdr o))
 		(if o
 			(write-char #standard-out 32)))
 	(write-newline #standard-out)
@@ -210,10 +203,10 @@
 		(define hash (cdr hash))))
 
 (define (expand-string oldstring)
-	(define-local newstring (new-string (+ 512 (string-length oldstring))))
-	(define-local i 0)
-	(while (< i (string-length oldstring))
-		(put-char newstring i (get-char oldstring i)))
+	(let ((i 0)
+	      (newstring (new-string (+ 512 (string-length oldstring)))))
+		(while (< i (string-length oldstring))
+			(put-char newstring i (get-char oldstring i))))
 	newstring)
 
 (define (macro-singlequote stream)
@@ -226,30 +219,29 @@
 ; token if it's not a close parenthesis
 (define (submacro-dot stream)
 	(catch 'end-of-file
-		(progn
-			(define-local o (read-object stream))
+		(let ((o (read-object stream)))
 			(ifelse (not (eq? ') (read-object stream)))
 				(throw 'reader-error stream)
 				o))
 		(throw 'reader-error stream)))
 
 (define (macro-openparen stream)
-	(define-local reverse-list '())
-	(define-local new-list '())
-	(catch 'end-of-file
-		(loop
-			(define-local o (read-object stream))
-			(ifelse (eq? o '))
-				(exit-loop)
-				(ifelse (eq? o '.)
-					(ifelse reverse-list
-						(progn
-							(define-local new-list (submacro-dot stream))
-							(exit-loop))
-						(throw 'reader-error stream))
-					(define-local reverse-list (cons o reverse-list)))))
-		(throw 'reader-error stream))
-	(reverse/append reverse-list new-list))
+	(let ((reverse-list '())
+	      (new-list '()))
+		(catch 'end-of-file
+			(loop
+				(let ((o (read-object stream)))
+					(ifelse (eq? o '))
+						(exit-loop)
+						(ifelse (eq? o '.)
+							(ifelse reverse-list
+								(progn
+									(define new-list (submacro-dot stream))
+									(exit-loop))
+								(throw 'reader-error stream))
+							(define reverse-list (cons o reverse-list))))))
+			(throw 'reader-error stream))
+		(reverse/append reverse-list new-list)))
 (define-character-macro 40 macro-openparen)
 
 (define (macro-closeparen stream)
@@ -263,9 +255,9 @@
 (define-character-macro 44 macro-comma)
 
 (define (macro-semicolon stream)
-	(define-local c 0)
-	(while (and (<> c 10) (<> c 13))
-		(define-local c (read-char stream)))
+	(let ((c 0))
+		(while (and (<> c 10) (<> c 13))
+			(define c (read-char stream))))
 	(read-object stream))
 (define-character-macro 59 macro-semicolon)
 
@@ -282,15 +274,14 @@
 ;		(ifelse (pair? obj)
 ;			(ifelse (eq? unquote-identifier (car obj))
 ;				(cdr obj)
-;				(progn
-;					(define-local stack '(list))
-;					(define-local newtail '())
+;				(let ((stack '(list))
+;				      (newtail '()))
 ;					(while obj
 ;						(if (eq? unquote-identifier (car obj))
-;							(define-local newtail (cdr obj))
+;							(define newtail (cdr obj))
 ;							(exit-loop))
-;						(define-local stack (cons (quasiquote (car obj)) stack))
-;						(define-local obj (cdr obj)))
+;						(define stack (cons (quasiquote (car obj)) stack))
+;						(define obj (cdr obj)))
 ;					(reverse/append stack newtail)))
 ;			(quote obj))
 ;		obj))
@@ -312,61 +303,61 @@
 (define-character-macro 96 macro-backtick)
 
 (define (macro-doublequote stream)
-	(define-local string (new-string 512))
-	(define-local i 0)
-	(define-local c 0)
-	(loop
-		(if (= i (string-length string))
-			(define-local string (expand-string string)))
-		(define-local c
-			(catch 'end-of-file
-				(read-char stream)
-				(throw 'reader-error stream)))
-		(if (= c 34) ; 34 = ASCII double quote
-			(exit-loop))
-		(if (= c 92) ; 92 = ASCII backslash
-			(define-local c 
+	(let ((c 0)
+	      (i 0)
+	      (string (new-string 512)))
+		(loop
+			(if (= i (string-length string))
+				(define string (expand-string string)))
+			(define c
 				(catch 'end-of-file
 					(read-char stream)
-					(throw 'reader-error stream))))
-		(put-char string i c)
-		(define-local i (+ i 1)))
-	(substring string 0 i))
+					(throw 'reader-error stream)))
+			(if (= c 34) ; 34 = ASCII double quote
+				(exit-loop))
+			(if (= c 92) ; 92 = ASCII backslash
+				(define c 
+					(catch 'end-of-file
+						(read-char stream)
+						(throw 'reader-error stream))))
+			(put-char string i c)
+			(define i (+ i 1)))
+		(substring string 0 i)))
 (define-character-macro 34 macro-doublequote)
 
 (define (read-token stream c)
-	(define-local buffer (new-string 512))
-	(define-local i 0)
-	(loop
-		(if (= i (string-length buffer))
-			(define-local buffer (expand-string buffer)))
-		(put-char buffer i c)
-		(define-local i (+ i 1))
-		(catch 'end-of-file
-			(define-local c (peek-char stream))
-			(exit-loop))
-		(if (isspace c)
-			(exit-loop))
-		(unless (isascii c)
-			(exit-loop))
-		(if (get-using-= character-macros c)
-			(exit-loop))
-		(define-local c (read-char stream)))
-	(define buffer (substring buffer 0 i))
-	(catch 'type-error
-		(string->integer buffer)
-		(string->symbol buffer)))
+	(let ((buffer (new-string 512))
+	      (i 0))
+		(loop
+			(if (= i (string-length buffer))
+				(define buffer (expand-string buffer)))
+			(put-char buffer i c)
+			(define i (+ i 1))
+			(catch 'end-of-file
+				(define c (peek-char stream))
+				(exit-loop))
+			(if (isspace c)
+				(exit-loop))
+			(unless (isascii c)
+				(exit-loop))
+			(if (get-using-= character-macros c)
+				(exit-loop))
+			(define c (read-char stream)))
+		(define buffer (substring buffer 0 i))
+		(catch 'type-error
+			(string->integer buffer)
+			(string->symbol buffer))))
 
 (define (read-object stream)
-	(define-local c 32) ; 32 = ASCII space
-	(while (isspace c)
-		(define-local c (read-char stream)))
-	(unless (isascii c)
-		(throw 'reader-error stream))
-	(define macro (get-using-= character-macros c))
-	(ifelse macro
-		(macro stream)
-		(read-token stream c)))
+	(let ((c 32)) ; 32 = ASCII space
+		(while (isspace c)
+			(define c (read-char stream)))
+		(unless (isascii c)
+			(throw 'reader-error stream))
+		(define macro (get-using-= character-macros c))
+		(ifelse macro
+			(macro stream)
+			(read-token stream c))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Some more utility routines ;;;
@@ -385,6 +376,53 @@
 (macro-define (cddar o) `(cdr (cdr (car ,o))))
 (macro-define (cdddr o) `(cdr (cdr (cdr ,o))))
 
+(define (cars arg) ; ((1 2) (3 4)) => (1 3)
+	(let ((stack '()))
+		(while arg
+			(define stack (cons (caar arg) stack))
+			(define arg (cdr arg)))
+		(reverse stack)))
+(define (cdrs arg) ; ((1 2) (3 4)) => ((2) (4))
+	(let ((stack '()))
+		(while arg
+			(define stack (cons (cdar arg) stack))
+			(define arg (cdr arg)))
+		(reverse stack)))
+(define (cadrs arg) ; ((1 2) (3 4)) => (2 4)
+	(let ((stack '()))
+		(while arg
+			(define stack (cons (cadar arg) stack))
+			(define arg (cdr arg)))
+		(reverse stack)))
+
+(define (string-eqv? a b)
+	(let ((c (string-length a)))
+		(ifelse (= c (string-length b))
+			(loop
+				(if (= c 0)
+					(exit-loop #t))
+				(define c (- c 1))
+				(if (<> (get-char a c) (get-char b c))
+					(exit-loop #f)))
+			#f)))
+(define (eqv? 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? (evaluate a) (evaluate 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))))))))
+
 ;
 ; switch (takes the place of case)
 ;
@@ -409,67 +447,10 @@
 				(switch-handle var (cdr cases))))
 		#f))
 (macro-define (switch key . cases)
-	(define-local var (unique-word))
-	`(progn
-		(define-local ,var ,key)
-		,(switch-handle var cases)))
-
-(define (string-equivalent a b)
-	(define-local c (string-length a))
-	(ifelse (= c (string-length b))
-		(loop
-			(if (= c 0)
-				(exit-loop #t))
-			(define-local c (- c 1))
-			(if (<> (get-char a c) (get-char b c))
-				(exit-loop #f)))
-		#f))
-; This short-circuit macro is necessary to prevent switch/eqv? from getting
-; into an endless mutual recursion loop:
-(macro-define (eqv? a b)
-	(ifelse
-		(or
-			(and (eq? 'quote (object-type a)) (eq? 'word (object-type (evaluate a))))
-			(and (eq? 'quote (object-type b)) (eq? 'word (object-type (evaluate b)))))
-		(list 'eq? a b)
-		dont-macro-expand))
-(define (eqv? a b)
-	(ifelse (eq? a b)
-		#t
-		(ifelse (eq? (object-type a) (object-type b))
-			(switch (object-type a)
-				(('integer)
-					(= a b))
-				(('cons)
-					(and
-						(eqv? (car a) (car b))
-						(eqv? (cdr a) (cdr b))))
-				(('quote)
-					(eqv? (evaluate a) (evaluate b)))
-				(('string)
-					(string-equivalent a b))
-				(else
-					#f))
-			#f)))
-
-(define (cars arg) ; ((1 2) (3 4)) => (1 3)
-	(define-local stack '())
-	(while arg
-		(define-local stack (cons (caar arg) stack))
-		(define-local arg (cdr arg)))
-	(reverse stack))
-(define (cdrs arg) ; ((1 2) (3 4)) => ((2) (4))
-	(define-local stack '())
-	(while arg
-		(define-local stack (cons (cdar arg) stack))
-		(define-local arg (cdr arg)))
-	(reverse stack))
-(define (cadrs arg) ; ((1 2) (3 4)) => (2 4)
-	(define-local stack '())
-	(while arg
-		(define-local stack (cons (cadar arg) stack))
-		(define-local arg (cdr arg)))
-	(reverse stack))
+	(let ((var (unique-word)))
+		`(progn
+			(define ,var ,key)
+			,(switch-handle var cases))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; And here's our repl ;;;
@@ -487,17 +468,18 @@
 	(write-object #standard-out errorvalue)
 	(write-newline #standard-out))
 (define (read-eval-print in out prompt)
-	(loop
-		(if prompt (write-string out prompt))
-		(define-local scratchspace
-			(catch 'end-of-file
-				(read-object in)
-				(progn (if prompt (write-newline out)) (exit-loop))))
-		(define-local scratchspace
-			(catch #f
-				(evaluate (macro-expand scratchspace))
-				(progn (show-error #exception #exceptionvalue) (ifelse prompt (next-loop) (exit-loop)))))
-		(if (and prompt scratchspace)
-			(write-object out scratchspace)
-			(write-newline out))))
+	(let ((scratchspace #f))
+		(loop
+			(if prompt (write-string out prompt))
+			(define scratchspace
+				(catch 'end-of-file
+					(read-object in)
+					(progn (if prompt (write-newline out)) (exit-loop))))
+			(define scratchspace
+				(catch #f
+					(evaluate (macro-expand scratchspace))
+					(progn (show-error #exception #exceptionvalue) (ifelse prompt (next-loop) (exit-loop)))))
+			(if (and prompt scratchspace)
+				(write-object out scratchspace)
+				(write-newline out)))))
 (read-eval-print #standard-in #standard-out (ifelse (isatty #standard-in) "mikelisp> " #f))
