--- old/CHANGELOG	2006-07-14 21:49:18.000000000 -0700
+++ CHANGELOG	2006-08-15 00:24:02.000000000 -0700
@@ -66,3 +66,8 @@
 Fix: added predropobj to struct objtype so word.c can unhash words sooner.
 Fixed switch.
 
+2006-08-15: 1.9: Fixed typo in debug message in unique_word.
+Added let@ macro.
+Added member function.
+Improved quasiquote to handle things like `(foo . ,(car bar)).
+
--- old/Makefile	2006-03-12 19:37:14.000000000 -0800
+++ Makefile	2006-07-14 21:50:16.000000000 -0700
@@ -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.8
+VERSION=1.9
 -include .local.Makefile
 
 $(BUILDDIR)mikelisp : $(SRCS:%.c=$(BUILDDIR)%.o) lisp.h
--- old/word.c	2006-07-14 21:31:44.000000000 -0700
+++ word.c	2006-07-19 16:23:44.000000000 -0700
@@ -1,4 +1,4 @@
-/* word.c   by Michael Thorpe   2006-07-14 */
+/* word.c   by Michael Thorpe   2006-07-19 */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -107,7 +107,7 @@
 	while(1) {
 		len=snprintf(buf,sizeof(buf),"#word-%u",rand());
 		if(-1==len || sizeof(buf)<=len) {
-			fprintf(stderr,"unique_word ust got %d from snprintf\n",len);
+			fprintf(stderr,"unique_word just got %d from snprintf\n",len);
 			exit(-1);
 		}
 		h=hash(buf,len);
--- old/preload.lisp	2006-07-14 21:49:07.000000000 -0700
+++ preload.lisp	2006-08-15 00:20:19.000000000 -0700
@@ -1,4 +1,4 @@
-; preload.lisp   by Michael Thorpe   2006-07-14
+; preload.lisp   by Michael Thorpe   2006-08-15
 
 (#define '#f (= 1 2))
 (#define '#t (= 1 1))
@@ -140,6 +140,16 @@
 	(list 'ifelse bool
 		(cons 'progn progs)
 		#f))
+(define (member item list)
+	(ifelse list
+		(ifelse (pair? list)
+			(ifelse (eq? item (car list))
+				list
+				(member item (cdr list)))
+			(ifelse (eq? item list)
+				list
+				#f))
+		#f))
 (macro-define (next-loop) (list 'throw ''next-loop #f))
 (macro-define (not a) (list 'ifelse a #f #t))
 (macro-define (or a . b)
@@ -201,6 +211,11 @@
 ; Then quasiquote will do its thing and return:
 ;   (list 'foo bar 'baz)
 ;
+; Note that quasiquote needs to be able to handle things like:
+;   `(foo bar . ,(car baz))
+; turning them into:
+;   (cons 'foo (cons 'bar (car baz)))
+;
 (define unquote-identifier '(unquote . identifier))
 
 (define character-macros '())
@@ -272,37 +287,14 @@
 	(read-object stream))
 (define-character-macro 59 macro-semicolon)
 
-; FIXME: quasiquote should be rewritten to handle things like:
-;   `(foo bar . ,(baz quux))
-; Which needs to be translated into:
-;   (cons 'foo (cons 'bar (baz quux)))
-;
-; The old version which handles:
-;   `(foo . ,bar)
-; (i.e., not a cons as the unquoted object in the final cdr) is:
-;(define (quasiquote obj)
-;	(ifelse obj
-;		(ifelse (pair? obj)
-;			(ifelse (eq? unquote-identifier (car obj))
-;				(cdr obj)
-;				(let ((stack '(list))
-;				      (newtail '()))
-;					(while obj
-;						(if (eq? unquote-identifier (car obj))
-;							(set newtail (cdr obj))
-;							(exit-loop))
-;						(set stack (cons (quasiquote (car obj)) stack))
-;						(set obj (cdr obj)))
-;					(reverse/append stack newtail)))
-;			(quote obj))
-;		obj))
-;
 (define (quasiquote obj)
 	(ifelse obj
 		(ifelse (pair? obj)
 			(ifelse (eq? unquote-identifier (car obj))
 				(cdr obj)
-				(cons 'list (map obj (quasiquote obj) obj)))
+				(ifelse (member unquote-identifier obj)
+					(list 'cons (quasiquote (car obj)) (quasiquote (cdr obj)))
+					(cons 'list (map obj (quasiquote obj) obj))))
 			(quote obj))
 		obj))
 
@@ -407,6 +399,27 @@
 			(set arg (cdr arg)))
 		(reverse stack)))
 
+;
+; my let@ is like Lisp's let, whereas my let is like Lisp's let*.
+;
+(macro-define (let@ vars . body)
+	(ifelse vars
+		(ifelse (cdr vars)
+			(let ((varnames (reverse (cdr (cars vars))))
+			      (firstvar (caar vars)))
+				(set body (list 'progn `(set ,firstvar (car ,firstvar)) . body))
+				(while varnames
+					(set body
+						`(let ((,(car varnames) (car ,firstvar)))
+							(set ,firstvar (cdr ,firstvar))
+							,body))
+					(set varnames (cdr varnames)))
+				`(let
+					((,firstvar ,(cons 'list (reverse (cadrs vars)))))
+					,body))
+			(list 'let vars . body))
+		(list 'progn . body)))
+
 (define (string-eqv? a b)
 	(let ((c (string-length a)))
 		(ifelse (= c (string-length b))
