This is an autogenerated patch header for a single-debian-patch file. The
delta against upstream is either kept as a single patch, or maintained
in some VCS, and exported as a single patch instead of more manageable
atomic patches.

--- chibi-scheme-0.9.1.orig/Makefile
+++ chibi-scheme-0.9.1/Makefile
@@ -1,6 +1,6 @@
 # -*- makefile-gmake -*-
 
-.PHONY: dist mips-dist cleaner test test-all test-dist checkdefs debian snowballs init-dev
+.PHONY: dist mips-dist cleaner distclean dist-clean test test-all test-dist checkdefs debian snowballs init-dev
 .DEFAULT_GOAL := all
 
 CHIBI_VERSION ?= $(shell cat VERSION)
@@ -11,7 +11,7 @@ CHIBI_FFI ?= $(CHIBI) -q tools/chibi-ffi
 CHIBI_FFI_DEPENDENCIES ?= $(CHIBI_DEPENDENCIES) tools/chibi-ffi
 
 CHIBI_DOC ?= $(CHIBI) tools/chibi-doc
-CHIBI_DOC_DEPENDENCIES ?= $(CHIBI_DEPENDENCIES) tools/chibi-doc
+CHIBI_DOC_DEPENDENCIES ?= $(CHIBI_DEPENDENCIES) tools/chibi-doc $(COMPILED_LIBS)
 
 GENSTATIC ?= ./tools/chibi-genstatic
 
@@ -50,8 +50,9 @@ MODULE_DOCS := app ast base64 bytevector
 	crypto/sha2 diff disasm doc edit-distance equiv filesystem generic \
 	heap-stats io iset/base iset/constructors iset/iterators json loop \
 	match math/prime memoize mime modules net net/http-server net/servlet \
-	parse pathname process repl scribble string stty sxml system temp-file \
-	test time trace type-inference uri weak monad/environment crypto/sha2
+	optional parse pathname process repl scribble string stty sxml system \
+	temp-file test time trace type-inference uri weak monad/environment \
+	crypto/sha2
 
 IMAGE_FILES = lib/chibi.img lib/red.img lib/snow.img
 
@@ -82,11 +83,11 @@ chibi-scheme-static.bc:
 	emmake $(MAKE) PLATFORM=emscripten CHIBI_DEPENDENCIES= CHIBI=./chibi-scheme-emscripten PREFIX= CFLAGS=-O2 SEXP_USE_DL=0 EXE=.bc SO=.bc CPPFLAGS="-DSEXP_USE_STRICT_TOPLEVEL_BINDINGS=1 -DSEXP_USE_ALIGNED_BYTECODE=1 -DSEXP_USE_STATIC_LIBS=1 -DSEXP_USE_STATIC_LIBS_NO_INCLUDE=0" clibs.c chibi-scheme-static.bc
 
 chibi-scheme-emscripten: VERSION
-	$(MAKE) dist-clean
+	$(MAKE) distclean
 	$(MAKE) chibi-scheme-static PLATFORM=emscripten SEXP_USE_DL=0
 	(tempfile="`mktemp -t chibi.XXXXXX`" && \
 	mv chibi-scheme-static$(EXE) "$$tempfile" && \
-	$(MAKE) dist-clean; \
+	$(MAKE) distclean; \
 	mv "$$tempfile" chibi-scheme-emscripten)
 
 include/chibi/install.h: Makefile
@@ -131,10 +132,10 @@ chibi-scheme$(EXE): main.o libchibi-sche
 	$(CC) $(XCPPFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ $< -L. $(RLDFLAGS) -lchibi-scheme
 
 chibi-scheme-static$(EXE): main.o $(SEXP_OBJS) $(EVAL_OBJS)
-	$(CC) $(XCFLAGS) $(STATICFLAGS) -o $@ $^ $(LDFLAGS) $(GCLDFLAGS) -lm -ldl -lutil
+	$(CC) $(XCFLAGS) $(STATICFLAGS) -o $@ $^ $(LDFLAGS) $(GCLDFLAGS) $(STATIC_LDFLAGS)
 
 chibi-scheme-ulimit$(EXE): main.o $(SEXP_ULIMIT_OBJS) $(EVAL_OBJS)
-	$(CC) $(XCFLAGS) $(STATICFLAGS) -o $@ $^ $(LDFLAGS) $(GCLDFLAGS) -lm -ldl -lutil
+	$(CC) $(XCFLAGS) $(STATICFLAGS) -o $@ $^ $(LDFLAGS) $(GCLDFLAGS) $(STATIC_LDFLAGS)
 
 clibs.c: $(GENSTATIC) $(CHIBI_DEPENDENCIES) $(COMPILED_LIBS:%$(SO)=%.c)
 	$(GIT) ls-files lib | $(GREP) .sld | $(CHIBI) -q $(GENSTATIC) > $@
@@ -290,7 +291,8 @@ cleaner: clean
 	    js/chibi.* \
 	    $(shell $(FIND) lib -name \*.o)
 
-dist-clean: dist-clean-libs cleaner
+distclean: dist-clean-libs cleaner
+dist-clean: distclean
 
 install-base: all
 	$(MKDIR) $(DESTDIR)$(BINDIR)
@@ -392,9 +394,9 @@ install-base: all
 install: install-base
 ifneq "$(IMAGE_FILES)" ""
 	echo "Generating images"
-	-cd / && LD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(LD_LIBRARY_PATH)" DYLD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(DYLD_LIBRARY_PATH)" CHIBI_MODULE_PATH="$(DESTDIR)$(MODDIR):$(DESTDIR)$(BINMODDIR)" $(DESTDIR)$(BINDIR)/chibi-scheme$(EXE) -d $(DESTDIR)$(MODDIR)/chibi.img
-	-cd / && LD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(LD_LIBRARY_PATH)" DYLD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(DYLD_LIBRARY_PATH)" CHIBI_MODULE_PATH="$(DESTDIR)$(MODDIR):$(DESTDIR)$(BINMODDIR)" $(DESTDIR)$(BINDIR)/chibi-scheme$(EXE) -xscheme.red -d $(DESTDIR)$(MODDIR)/red.img
-	-cd / && LD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(LD_LIBRARY_PATH)" DYLD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(DYLD_LIBRARY_PATH)" CHIBI_MODULE_PATH="$(DESTDIR)$(MODDIR):$(DESTDIR)$(BINMODDIR)" $(DESTDIR)$(BINDIR)/chibi-scheme$(EXE) -mchibi.snow.commands -mchibi.snow.interface -mchibi.snow.package -mchibi.snow.utils -d $(DESTDIR)$(MODDIR)/snow.img
+	-LD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(LD_LIBRARY_PATH)" DYLD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(DYLD_LIBRARY_PATH)" CHIBI_MODULE_PATH="$(DESTDIR)$(MODDIR):$(DESTDIR)$(BINMODDIR)" $(DESTDIR)$(BINDIR)/chibi-scheme$(EXE) -mchibi.repl -d $(DESTDIR)$(MODDIR)/chibi.img
+	-LD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(LD_LIBRARY_PATH)" DYLD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(DYLD_LIBRARY_PATH)" CHIBI_MODULE_PATH="$(DESTDIR)$(MODDIR):$(DESTDIR)$(BINMODDIR)" $(DESTDIR)$(BINDIR)/chibi-scheme$(EXE) -xscheme.red -mchibi.repl -d $(DESTDIR)$(MODDIR)/red.img
+	-LD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(LD_LIBRARY_PATH)" DYLD_LIBRARY_PATH="$(DESTDIR)$(SOLIBDIR):$(DYLD_LIBRARY_PATH)" CHIBI_MODULE_PATH="$(DESTDIR)$(MODDIR):$(DESTDIR)$(BINMODDIR)" $(DESTDIR)$(BINDIR)/chibi-scheme$(EXE) -mchibi.snow.commands -mchibi.snow.interface -mchibi.snow.package -mchibi.snow.utils -d $(DESTDIR)$(MODDIR)/snow.img
 endif
 
 uninstall:
@@ -466,14 +468,14 @@ uninstall:
 	-$(RM) $(DESTDIR)$(MANDIR)/chibi-scheme.1 $(DESTDIR)$(MANDIR)/chibi-ffi.1 $(DESTDIR)$(MANDIR)/chibi-doc.1
 	-$(RM) $(DESTDIR)$(PKGCONFDIR)/chibi-scheme.pc
 
-dist: dist-clean
+dist: distclean
 	$(RM) chibi-scheme-$(CHIBI_VERSION).tgz
 	$(MKDIR) chibi-scheme-$(CHIBI_VERSION)
 	@for f in `git ls-files | grep -v ^benchmarks/`; do $(MKDIR) chibi-scheme-$(CHIBI_VERSION)/`dirname $$f`; $(SYMLINK) `pwd`/$$f chibi-scheme-$(CHIBI_VERSION)/$$f; done
 	$(TAR) cphzvf chibi-scheme-$(CHIBI_VERSION).tgz chibi-scheme-$(CHIBI_VERSION)
 	$(RM) -r chibi-scheme-$(CHIBI_VERSION)
 
-mips-dist: dist-clean
+mips-dist: distclean
 	$(RM) chibi-scheme-`date +%Y%m%d`-`git log HEAD^..HEAD | head -1 | cut -c8-`.tgz
 	$(MKDIR) chibi-scheme-`date +%Y%m%d`-`git log HEAD^..HEAD | head -1 | cut -c8-`
 	@for f in `git ls-files | grep -v ^benchmarks/`; do $(MKDIR) chibi-scheme-`date +%Y%m%d`-`git log HEAD^..HEAD | head -1 | cut -c8-`/`dirname $$f`; $(SYMLINK) `pwd`/$$f chibi-scheme-`date +%Y%m%d`-`git log HEAD^..HEAD | head -1 | cut -c8-`/$$f; done
--- chibi-scheme-0.9.1.orig/Makefile.detect
+++ chibi-scheme-0.9.1/Makefile.detect
@@ -9,6 +9,7 @@ PLATFORM=macosx
 else
 ifeq ($(shell uname),FreeBSD)
 PLATFORM=bsd
+LIBCHIBI_FLAGS = -Wl,-soname,libchibi-scheme$(SO).$(SOVERSION_MAJOR)
 else
 ifeq ($(shell uname),NetBSD)
 PLATFORM=bsd
@@ -57,6 +58,7 @@ endif
 LIBDL = -ldl
 SO_VERSIONED_SUFFIX = $(SO).$(SOVERSION)
 SO_MAJOR_VERSIONED_SUFFIX = $(SO).$(SOVERSION_MAJOR)
+STATIC_LDFLAGS = -lm -ldl -lutil
 
 ifeq ($(PLATFORM),macosx)
 SO  = .dylib
@@ -93,6 +95,7 @@ CLINKFLAGS = -shared
 CPPFLAGS += -DSEXP_USE_STRING_STREAMS=0 -DSEXP_USE_GREEN_THREADS=0 -DSEXP_USE_GC_FILE_DESCRIPTORS=0 -DBUILDING_DLL
 LIBCHIBI_FLAGS = -Wl,--out-implib,libchibi-scheme$(SO).a
 STATICFLAGS =
+STATIC_LDFLAGS = -lm -ldl
 LIBDL = -lws2_32
 else
 ifeq ($(PLATFORM),msys)
@@ -103,6 +106,7 @@ CLIBFLAGS =
 CLINKFLAGS = -shared
 CPPFLAGS += -DSEXP_USE_STRING_STREAMS=0
 LIBCHIBI_FLAGS = -Wl,--out-implib,libchibi-scheme$(SO).a
+STATIC_LDFLAGS = -lm -ldl
 else
 ifeq ($(PLATFORM),cygwin)
 SO  = .dll
@@ -112,6 +116,7 @@ CLIBFLAGS =
 CLINKFLAGS = -shared
 CPPFLAGS += -DSEXP_USE_STRING_STREAMS=0
 LIBCHIBI_FLAGS = -Wl,--out-implib,libchibi-scheme$(SO).a
+STATIC_LDFLAGS = -lm -ldl
 else
 SO  = .so
 EXE =
@@ -126,6 +131,10 @@ endif
 endif
 endif
 
+ifeq ($(PLATFORM),emscripten)
+STATIC_LDFLAGS = -lm -ldl
+endif
+
 ifeq ($(PLATFORM),unix)
 #RLDFLAGS=-rpath $(LIBDIR)
 RLDFLAGS=-Wl,-R$(LIBDIR)
--- chibi-scheme-0.9.1.orig/Makefile.libs
+++ chibi-scheme-0.9.1/Makefile.libs
@@ -27,23 +27,37 @@ FIND      ?= find
 SYMLINK   ?= ln -s
 LDCONFIG  ?= ldconfig
 
-PREFIX    ?= /usr/local
-BINDIR    ?= $(PREFIX)/bin
-LIBDIR    ?= $(PREFIX)/lib
-SOLIBDIR  ?= $(LIBDIR)
-INCDIR    ?= $(PREFIX)/include/chibi
-MODDIR    ?= $(PREFIX)/share/chibi
-BINMODDIR ?= $(SOLIBDIR)/chibi
-PKGCONFDIR ?= $(SOLIBDIR)/pkgconfig
-MANDIR    ?= $(PREFIX)/share/man/man1
+# gnu coding standards
+prefix      ?= /usr/local
+PREFIX      ?= $(prefix)
+exec_prefix ?= $(PREFIX)
+bindir      ?= $(exec_prefix)/bin
+libdir      ?= $(exec_prefix)/lib
+includedir  ?= $(PREFIX)/include
+datarootdir ?= $(PREFIX)/share
+datadir     ?= $(datarootdir)
+mandir      ?= $(datarootdir)/man
+man1dir     ?= $(mandir)/man1
 
+# hysterical raisins
+BINDIR      ?= $(bindir)
+LIBDIR      ?= $(libdir)
+SOLIBDIR    ?= $(libdir)
+INCDIR      ?= $(includedir)/chibi
+MODDIR      ?= $(datadir)/chibi
+BINMODDIR   ?= $(SOLIBDIR)/chibi
+PKGCONFDIR  ?= $(SOLIBDIR)/pkgconfig
+MANDIR      ?= $(man1dir)
+
+# allow snow to be configured separately
 SNOWPREFIX    ?= /usr/local
 SNOWLIBDIR    ?= $(SNOWPREFIX)/lib
 SNOWSOLIBDIR  ?= $(SNOWLIBDIR)
 SNOWMODDIR    ?= $(SNOWPREFIX)/share/snow
 SNOWBINMODDIR ?= $(SNOWSOLIBDIR)/snow
 
-DESTDIR   ?=
+# for packaging tools
+DESTDIR       ?=
 
 ########################################################################
 # System configuration - if not using GNU make, set PLATFORM and the
--- chibi-scheme-0.9.1.orig/README.md
+++ chibi-scheme-0.9.1/README.md
@@ -16,7 +16,7 @@ Despite the small size, Chibi-Scheme att
 The default settings include:
 
 * a full numeric tower, with rational and complex numbers
-* full and seemless Unicode support
+* full and seamless Unicode support
 * low-level and high-level hygienic macros
 * an extensible module system
 
--- chibi-scheme-0.9.1.orig/doc/chibi-scheme.1
+++ chibi-scheme-0.9.1/doc/chibi-scheme.1
@@ -231,7 +231,7 @@ This feature is still experimental.
 .B CHIBI_MODULE_PATH
 A colon separated list of directories to search for module
 files, inserted before the system default load paths.  chibi-scheme
-searchs for modules in directories in the following order:
+searches for modules in directories in the following order:
 
 .TP
           directories included with the -I path option
@@ -243,7 +243,13 @@ searchs for modules in directories in th
           directories included with -A path option
 
 If CHIBI_MODULE_PATH is unset, the directories "./lib", and "." are
-search in order.
+searched in order. Set to empty to only consider -I, system
+directories and -A.
+
+.TP
+.B CHIBI_IGNORE_SYSTEM_PATH
+If set to anything but "0", system directories (as listed above) are
+not included in the search paths.
 
 .SH AUTHORS
 .PP
--- chibi-scheme-0.9.1.orig/doc/chibi.scrbl
+++ chibi-scheme-0.9.1/doc/chibi.scrbl
@@ -938,16 +938,27 @@ NULL in which case the pointers are neve
 procedure of one argument which should release any resources.
 }}
 
-\item{\ccode{sexp sexp_make_cpointer(sexp ctx, sexp_uint_t type_id, void* value, sexp parent, int freep)}
+\item{\ccode{sexp sexp_make_cpointer(sexp ctx, sexp_uint_t type_tag, void* value, sexp parent, int freep)}
 \p{
-Creates a new instance of the type indicated by type_id wrapping
+Creates a new instance of the type indicated by type_tag wrapping
 value. If parent is provided, references to the child will also
 preserve the parent, important e.g. to preserve an enclosing struct
 when wrapped references to nested structs are still in use.  If freep
 is true, then when reclaimed by the GC the finalizer for this type,
 if any, will be called on the instance.
 
-You can retrieve the id from a type object with sexp_type_tag(type).
+You can retrieve the tag from a type object with sexp_type_tag(type).
+}}
+
+\item{\ccode{sexp sexp_lookup_type(sexp ctx, sexp name, sexp tag_or_id)}
+\p{
+Returns the type whose name matches the string \var{name}.  If
+\var{tag_or_id} is an integer, it is taken as the tag and requires the
+numeric type tag (as from sexp_type_tag) to also match.
+}
+\p{If \var{tag_or_id} is a string, it is taken as the unique id of the
+type, and must match sexp_type_id(type).  However, currently
+sexp_type_id(type) is never set.
 }}
 
 ]
@@ -1272,7 +1283,7 @@ snow-fort):
 \item{\hyperlink["http://srfi.schemers.org/srfi-160/srfi-160.html"]{(srfi 160) - homogeneous numeric vector libraries}}
 \item{\hyperlink["http://srfi.schemers.org/srfi-165/srfi-165.html"]{(srfi 165) - the environment Monad}}
 \item{\hyperlink["http://srfi.schemers.org/srfi-166/srfi-166.html"]{(srfi 166) - monadic formatting}}
-\item{\hyperlink["http://srfi.schemers.org/srfi-166/srfi-188.html"]{(srfi 188) - splicing binding constructs for syntactic keywords}}
+\item{\hyperlink["http://srfi.schemers.org/srfi-188/srfi-188.html"]{(srfi 188) - splicing binding constructs for syntactic keywords}}
 
 ]
 
@@ -1343,6 +1354,8 @@ namespace.
 
 \item{\hyperlink["lib/chibi/net/servlet.html"]{(chibi net servlet) - HTTP servlets for http-server or CGI}}
 
+\item{\hyperlink["lib/chibi/optional.html"]{(chibi optional) - Syntax to support optional and named keyword arguments}}
+
 \item{\hyperlink["lib/chibi/parse.html"]{(chibi parse) - Parser combinators with convenient syntax}}
 
 \item{\hyperlink["lib/chibi/pathname.html"]{(chibi pathname) - Utilities to decompose and manipulate pathnames}}
@@ -1394,7 +1407,9 @@ with image files on your platform you ca
 
 By default \scheme{snow-chibi} looks for packages in the public
 repository \hyperlink["http://snow-fort.org/"]{http://snow-fort.org/},
-though you can customize this with the \scheme{--repository-uri} option.
+though you can customize this with the \scheme{--repository-uri} or
+\scheme{--repo} option (e.g. "http://snow-fort.org/s/repo.scm").
+
 Packages can be browsed on the site, but you can also search and query
 from the command-line tool.
 
@@ -1426,6 +1441,11 @@ older version, a warning is printed.}}
 The basic package management functionality, installing upgrading and
 removing packages.
 
+By default the packages will be managed for Chibi. You can specify
+what Scheme implementation to install, upgrade... with
+\scheme{--implementations} or \scheme{--impls} option. Specify "all"
+to manage all supported implementations.
+
 \itemlist[
 
 \item{install names ... - install packages
@@ -1434,8 +1454,10 @@ use the dotted shorthand.  Explicit name
 as a package can always be referred to by the name of any library it
 contains.  If multiple packages provide libraries with the same name,
 you will be asked to confirm which implementation to install.}
+
 \p{You can also bypass the repository and install a manually downloaded
-snowball by giving a path to that file instead of a name.}}
+snowball by giving a path to that file instead of a name. No package
+dependencies will be checked for install in this case}}
 
 \item{upgrade names ... - upgrade installed packages
 \p{Upgrade the packages if new versions are available.
@@ -1457,6 +1479,10 @@ update with this command.}}
 Creating packages can be done with the \scheme{package} command,
 though other commands allow for uploading to public repositories.
 
+By default the public repository is
+\hyperlink["http://snow-fort.org/"]{http://snow-fort.org/} but you can
+customize this with the \scheme{--host} option.
+
 \itemlist[
 
 \item{package files ... - create a package
@@ -1556,8 +1582,10 @@ are currently supported:
 \itemlist[
 \item{chibi - native support as of version 0.7.3}
 \item{chicken - version >= 4.9.0 with the \scheme{r7rs} egg}
+\item{cyclone - version >= 0.5.3}
 \item{foment - version >= 0.4}
 \item{gauche - version >= 0.9.4}
 \item{kawa - version >= 2.0; you need to add the install dir to the search path, e.g. \scheme{-Dkawa.import.path=/usr/local/share/kawa}}
 \item{larceny - version 0.98; you need to add "lib/Snow" to the paths in startup.sch}
+\item{sagittarius - version >= 0.98}
 ]
--- chibi-scheme-0.9.1.orig/eval.c
+++ chibi-scheme-0.9.1/eval.c
@@ -206,7 +206,7 @@ sexp sexp_env_exports_op (sexp ctx, sexp
   res = SEXP_NULL;
 #if SEXP_USE_RENAME_BINDINGS
   for (ls=sexp_env_renames(env); sexp_pairp(ls); ls=sexp_env_next_cell(ls))
-    sexp_push(ctx, res, sexp_cadr(ls));
+    sexp_push(ctx, res, sexp_car(ls));
 #endif
   for (ls=sexp_env_bindings(env); sexp_pairp(ls); ls=sexp_env_next_cell(ls))
     if (sexp_env_value(ls) != SEXP_UNDEF)
@@ -1662,8 +1662,10 @@ sexp sexp_exact_sqrt (sexp ctx, sexp sel
 #endif
 
 sexp sexp_sqrt (sexp ctx, sexp self, sexp_sint_t n, sexp z) {
-#if SEXP_USE_BIGNUMS
+#if SEXP_USE_BIGNUMS || SEXP_USE_RATIOS
   sexp_gc_var2(res, rem);
+#endif
+#if SEXP_USE_BIGNUMS
   if (sexp_bignump(z)) {
     sexp_gc_preserve2(ctx, res, rem);
     res = sexp_bignum_sqrt(ctx, z, &rem);
@@ -1673,6 +1675,20 @@ sexp sexp_sqrt (sexp ctx, sexp self, sex
     sexp_gc_release2(ctx);
     return res;
   }
+#endif
+#if SEXP_USE_RATIOS
+  if (sexp_ratiop(z)) {
+    sexp_gc_preserve2(ctx, res, rem);
+    res = sexp_sqrt(ctx, self, n, sexp_ratio_numerator(z));
+    rem = sexp_sqrt(ctx, self, n, sexp_ratio_denominator(z));
+    if (sexp_exactp(res) && sexp_exactp(rem)) {
+      res = sexp_make_ratio(ctx, res, rem);
+    } else {
+      res = sexp_inexact_sqrt(ctx, self, n, z);
+    }
+    sexp_gc_release2(ctx);
+    return res;
+  }
 #endif
   return sexp_inexact_sqrt(ctx, self, n, z);
 }
--- chibi-scheme-0.9.1.orig/include/chibi/gc_heap.h
+++ chibi-scheme-0.9.1/include/chibi/gc_heap.h
@@ -7,6 +7,8 @@
 
 #include "chibi/sexp.h"
 
+#if SEXP_USE_IMAGE_LOADING
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -98,4 +100,6 @@ SEXP_API char* sexp_load_image_err();
 }
 #endif
 
+#endif  /* SEXP_USE_IMAGE_LOADING */
+
 #endif  /* ! SEXP_GC_HEAP_H */
--- chibi-scheme-0.9.1.orig/include/chibi/sexp.h
+++ chibi-scheme-0.9.1/include/chibi/sexp.h
@@ -82,6 +82,12 @@ typedef long long off_t;
 #define exit(x)           exits(TOSTRING(x))
 #define fabsl          fabs
 #define M_LN10         2.30258509299404568402  /* log_e 10 */
+#define FLT_RADIX 2
+#define isfinite(x) !(isNaN(x) || isInf(x,0))
+typedef u32int uint32_t;
+typedef s32int int32_t;
+typedef u64int uint64_t;
+typedef s64int int64_t;
 #else
 #include <stddef.h>
 #include <stdlib.h>
@@ -568,7 +574,7 @@ struct sexp_struct {
       unsigned char* ip;
       struct timeval tval;
 #endif
-      char tailp, tracep, timeoutp, waitp, errorp;
+      char tailp, tracep, timeoutp, waitp, errorp, interruptp;
       sexp_uint_t last_fp;
       sexp_uint_t gc_count;
 #if SEXP_USE_TIME_GC
@@ -1373,6 +1379,7 @@ enum sexp_uniform_vector_type {
 
 #define sexp_context_result(x)   (sexp_field(x, context, SEXP_CONTEXT, result))
 #define sexp_context_errorp(x)   (sexp_field(x, context, SEXP_CONTEXT, errorp))
+#define sexp_context_interruptp(x) (sexp_field(x, context, SEXP_CONTEXT, interruptp))
 
 /* during compilation, sexp_context_specific is set to a vector */
 /* containing the following elements: */
@@ -1509,6 +1516,7 @@ enum sexp_context_globals {
   SEXP_G_OOM_ERROR,             /* out of memory exception object */
   SEXP_G_OOS_ERROR,             /* out of stack exception object */
   SEXP_G_ABI_ERROR,             /* incompatible ABI loading library */
+  SEXP_G_INTERRUPT_ERROR,       /* C-c in the repl */
   SEXP_G_OPTIMIZATIONS,
   SEXP_G_SIGNAL_HANDLERS,
   SEXP_G_META_ENV,
--- chibi-scheme-0.9.1.orig/lib/chibi/ast.c
+++ chibi-scheme-0.9.1/lib/chibi/ast.c
@@ -488,6 +488,12 @@ sexp sexp_set_atomic (sexp ctx, sexp sel
 }
 #endif
 
+sexp sexp_thread_interrupt (sexp ctx, sexp self, sexp_sint_t n, sexp thread) {
+  sexp_assert_type(ctx, sexp_contextp, SEXP_CONTEXT, thread);
+  sexp_context_interruptp(thread) = 1;
+  return sexp_make_boolean(ctx == thread);
+}
+
 sexp sexp_thread_list (sexp ctx, sexp self, sexp_sint_t n) {
   sexp_gc_var1(res);
   sexp_gc_preserve1(ctx, res);
@@ -738,6 +744,7 @@ sexp sexp_init_library (sexp ctx, sexp s
 #if SEXP_USE_GREEN_THREADS
   sexp_define_foreign(ctx, env, "%set-atomic!", 1, sexp_set_atomic);
 #endif
+  sexp_define_foreign(ctx, env, "%thread-interrupt!", 1, sexp_thread_interrupt);
   sexp_define_foreign(ctx, env, "thread-list", 0, sexp_thread_list);
   sexp_define_foreign_opt(ctx, env, "string-contains", 3, sexp_string_contains, sexp_make_string_cursor(0));
   sexp_define_foreign(ctx, env, "string-cursor-copy!", 5, sexp_string_cursor_copy);
--- chibi-scheme-0.9.1.orig/lib/chibi/ast.scm
+++ chibi-scheme-0.9.1/lib/chibi/ast.scm
@@ -408,3 +408,7 @@
  (else
   (define-syntax atomically
     (syntax-rules () ((atomically . body) (begin . body))))))
+
+(define (thread-interrupt! thread)
+  (if (%thread-interrupt! thread)
+      (yield!)))
--- chibi-scheme-0.9.1.orig/lib/chibi/ast.sld
+++ chibi-scheme-0.9.1/lib/chibi/ast.sld
@@ -40,6 +40,7 @@
    string-contains string-cursor-copy! errno integer->error-string
    flatten-dot update-free-vars! setenv unsetenv safe-setenv
    immutable? make-immutable!
+   thread-interrupt!
    chibi-version)
   (import (chibi))
   (include-shared "ast")
--- chibi-scheme-0.9.1.orig/lib/chibi/diff-test.sld
+++ chibi-scheme-0.9.1/lib/chibi/diff-test.sld
@@ -1,7 +1,31 @@
 
 (define-library (chibi diff-test)
-  (import (scheme base) (chibi diff) (chibi test))
+  (import (scheme base) (chibi diff))
   (export run-tests)
+  (cond-expand
+   (chibi (import (chibi test)))
+   (else
+    (import (scheme write))
+    ;; inline (chibi test) to avoid circular dependencies in snow
+    ;; installations
+    (begin
+      (define-syntax test
+        (syntax-rules ()
+          ((test expect expr)
+           (test 'expr expect expr))
+          ((test name expect expr)
+           (guard (exn (else (display "!\nERROR: ") (write name) (newline)
+                             (write exn) (newline)))
+             (let* ((res expr)
+                    (pass? (equal? expect expr)))
+               (display (if pass? "." "x"))
+               (cond
+                ((not pass?)
+                 (display "\nFAIL: ") (write name) (newline))))))))
+      (define (test-begin name)
+        (display name))
+      (define (test-end)
+        (newline)))))
   (begin
     (define (run-tests)
       (test-begin "diff")
--- chibi-scheme-0.9.1.orig/lib/chibi/doc.scm
+++ chibi-scheme-0.9.1/lib/chibi/doc.scm
@@ -177,9 +177,11 @@
 (define (print-module-docs mod-name . o)
   (let ((out (if (pair? o) (car o) (current-output-port)))
         (render (or (and (pair? o) (pair? (cdr o)) (cadr o))
-                    sxml-display-as-text)))
+                    sxml-display-as-text))
+        (unexpanded?
+         (and (pair? o) (pair? (cdr o)) (pair? (cddr o)) (car (cddr o)))))
     (render
-     (generate-docs
+     ((if unexpanded? (lambda (sxml env) (fixup-docs sxml)) generate-docs)
       `((title ,(write-to-string mod-name))
         ,@(extract-module-docs mod-name #f))
       (make-module-doc-env mod-name))
@@ -425,7 +427,7 @@
     sxml)))
 
 (define (expand-procedure sxml env)
-  ((expand-section 'h3) `(,(car sxml) (rawcode ,@(cdr sxml))) env))
+  ((expand-section 'h4) `(,(car sxml) (rawcode ,@(cdr sxml))) env))
 
 (define (expand-macro sxml env)
   (expand-procedure sxml env))
@@ -464,52 +466,64 @@
 (define (get-contents x)
   (if (null? x)
       '()
-      (let ((d (caar x)))
-        (let lp ((ls (cdr x)) (parent (car (cdar x))) (kids '()) (res '()))
-          (define (collect)
-            (cons `(li ,parent ,(get-contents (reverse kids))) res))
-          ;; take a span of all sub-headers, recurse and repeat on next span
-          (cond
-           ((null? ls)
-            `(ol ,@(reverse (collect))))
-           ((> (caar ls) d)
-            (lp (cdr ls) parent (cons (car ls) kids) res))
-           (else
-            (lp (cdr ls) (car (cdar ls)) '() (collect))))))))
+      (let lp ((ls (cdr x))
+               (depth (caar x))
+               (parent (cadr (car x)))
+               (kids '())
+               (res '()))
+        (define (collect)
+          (cons `(li ,parent ,(get-contents (reverse kids))) res))
+        ;; take a span of all sub-headers, recurse and repeat on next span
+        (cond
+         ((null? ls)
+          `(ol ,@(reverse (collect))))
+         ((> (caar ls) depth)
+          (lp (cdr ls) depth parent (cons (car ls) kids) res))
+         (else
+          (lp (cdr ls) (caar ls) (cadr (car ls)) '() (collect)))))))
 
 (define (fix-header x)
-  `(html (head ,@(cond ((assq 'title x) => (lambda (x) (list x)))
-                       (else '()))
-               "\n"
-               (style (@ (type . "text/css"))
-                 "
-body {color: #000; background-color: #FFF}
-div#menu  {font-size: smaller; position: absolute; top: 50px; left: 0; width: 190px; height: 100%}
-div#main  {position: absolute; top: 0; left: 200px; width: 540px; height: 100%}
-div#notes {position: relative; top: 2em; left: 570px; max-width: 200px; height: 0px; font-size: smaller;}
+  `((!DOCTYPE html)
+    (html (head ,@(cond ((assq 'title x) => (lambda (x) (list x)))
+                        (else '()))
+                "\n"
+                (meta (@ (charset . "UTF-8")))
+                (style (@ (type . "text/css"))
+                  "
+body {color: #000; background-color: #FFFFF8;}
+div#menu  {font-size: smaller; position: absolute; top: 50px; left: 0; width: 250px; height: 100%}
+div#menu a:link {text-decoration: none}
+div#main  {font-size: large; position: absolute; top: 0; left: 260px; max-width: 590px; height: 100%}
+div#notes {position: relative; top: 2em; left: 620px; width: 200px; height: 0px; font-size: smaller;}
 div#footer {padding-bottom: 50px}
+div#menu ol {list-style-position:inside; padding-left: 5px; margin-left: 5px}
+div#menu ol ol {list-style: lower-alpha; padding-left: 15px; margin-left: 15px}
+div#menu ol ol ol {list-style: decimal; padding-left: 5px; margin-left: 5px}
+h2 { color: #888888; border-top: 3px solid #4588ba; }
+h3 { color: #666666; border-top: 2px solid #4588ba; }
+h4 { color: #222288; border-top: 1px solid #4588ba; }
 .result { color: #000; background-color: #FFEADF; width: 100%; padding: 3px}
 .output { color: #000; background-color: beige; width: 100%; padding: 3px}
 .error { color: #000; background-color: #F0B0B0; width: 100%; padding: 3px}
 .command { color: #000; background-color: #FFEADF; width: 100%; padding: 5px}
 "
-                 ,(highlight-style))
-               "\n")
-         (body
-          (div (@ (id . "menu"))
-               ,(let ((contents (get-contents (extract-contents x))))
-                  (match contents
-                    ;; flatten if we have only a single heading
-                    (('ol (li y sections ...))
-                     sections)
-                    (else contents))))
-          (div (@ (id . "main"))
-               ,@(map (lambda (x)
-                        (if (and (pair? x) (eq? 'title (car x)))
-                            (cons 'h1 (cdr x))
-                            x))
-                      x)
-               (div (@ (id . "footer")))))))
+                  ,(highlight-style))
+                "\n")
+          (body
+           (div (@ (id . "menu"))
+                ,(let ((contents (get-contents (extract-contents x))))
+                   (match contents
+                     ;; flatten if we have only a single heading
+                     (('ol (li y sections ...))
+                      sections)
+                     (else contents))))
+           (div (@ (id . "main"))
+                ,@(map (lambda (x)
+                         (if (and (pair? x) (eq? 'title (car x)))
+                             (cons 'h1 (cdr x))
+                             x))
+                       x)
+                (div (@ (id . "footer"))))))))
 
 (define (fix-paragraphs x)
   (let lp ((ls x) (p '()) (res '()))
@@ -735,7 +749,7 @@ div#footer {padding-bottom: 50px}
   (let ((sections '(section subsection subsubsection subsubsubsection)))
     (lambda (x)
       (cond ((memq x sections) => length)
-            ((memq x '(procedure macro)) (section-number 'subsection))
+            ((memq x '(procedure macro)) (section-number 'subsubsection))
             (else 0)))))
 
 (define (section>=? x n)
@@ -806,15 +820,16 @@ div#footer {padding-bottom: 50px}
       (let lp ((ls orig-ls) (rev-pre '()))
         (cond
          ((or (null? ls)
-              (section>=? (car ls) (section-number 'subsection)))
+              (section>=? (car ls) (section-number 'subsubsection)))
           `(,@(reverse rev-pre)
             ,@(if (and (pair? ls)
                        (section-describes?
-                        (extract-sxml '(subsection procedure macro)
-                                      (car ls))
+                        (extract-sxml
+                         '(subsubsection procedure macro)
+                         (car ls))
                         name))
                   '()
-                  `((subsection
+                  `((subsubsection
                      tag: ,(write-to-string name)
                      (rawcode
                       ,@(if (and (pair? (car sig)) (eq? 'const: (caar sig)))
--- chibi-scheme-0.9.1.orig/lib/chibi/loop/loop.scm
+++ chibi-scheme-0.9.1/lib/chibi/loop/loop.scm
@@ -368,14 +368,14 @@
      (accumulating (kons final i) ((var cursor) x) n . rest))
     ((accumulating (kons final init) ((var cursor) (expr (if check))) n . rest)
      (n ((tmp-kons kons))
-        ((cursor '() (if check (tmp-kons expr cursor) cursor)))
+        ((cursor init (if check (tmp-kons expr cursor) cursor)))
         ()
         ()
         ((var (final cursor)))
         . rest))
     ((accumulating (kons final init) ((var cursor) (expr)) n . rest)
      (n ((tmp-kons kons))
-        ((cursor '() (tmp-kons expr cursor)))
+        ((cursor init (tmp-kons expr cursor)))
         ()
         ()
         ((var (final cursor)))
--- chibi-scheme-0.9.1.orig/lib/chibi/match-test.sld
+++ chibi-scheme-0.9.1/lib/chibi/match-test.sld
@@ -31,19 +31,26 @@
       (test "or empty" 'ok (match '(o k) ((or) 'fail) (else 'ok)))
       (test "or single" 'ok (match 'ok ((or x) 'ok)))
       (test "or double" 'ok (match 'ok ((or (? symbol? y) y) y)))
+      (test "or unbalanced" 1  (match 1 ((or (and 1 x) (and 2 y)) x)))
       (test "not" 'ok (match 28 ((not (a . b)) 'ok)))
+      (test "not fail" 'bad (match 28 ((not a) 'ok) (else 'bad)))
+      (test "not and" #t (match 1 ((and (not 2)) #t)))
       (test "pred" 'ok (match 28 ((? number?) 'ok)))
       (test "named pred" 29 (match 28 ((? number? x) (+ x 1))))
 
       (test "duplicate symbols pass" 'ok (match '(ok . ok) ((x . x) x)))
       (test "duplicate symbols fail" 'ok
         (match '(ok . bad) ((x . x) 'bad) (else 'ok)))
+      (test "duplicate symbols fail 2" 'ok
+        (match '(ok bad) ((x x) 'bad) (else 'ok)))
       (test "duplicate symbols samth" 'ok
         (match '(ok . ok) ((x . 'bad) x) (('ok . x) x)))
       (test "duplicate symbols bound" 3
         (let ((a '(1 2))) (match a ((and (a 2) (1 b)) (+ a b)) (_ #f))))
       (test "duplicate quasiquote" 'ok
         (match '(a b) ((or `(a ,x) `(,x b)) 'ok) (_ #f)))
+      (test "duplicate before ellipsis" #f
+          (match '(1 2) ((a a ...) a) (else #f)))
 
       (test "ellipses" '((a b c) (1 2 3))
         (match '((a . 1) (b . 2) (c . 3))
@@ -105,6 +112,9 @@
         (match '((a . 1) (b . 2) 3)
           (((x . y) ... last) (list x y last))))
 
+      (test "single duplicate tail" #f
+        (match '(1 2) ((foo ... foo) foo) (_ #f)))
+
       (test "multiple tail" '((a b) (1 2) (c . 3) (d . 4) (e . 5))
         (match '((a . 1) (b . 2) (c . 3) (d . 4) (e . 5))
           (((x . y) ... u v w) (list x y u v w))))
@@ -178,50 +188,50 @@
       (test "joined tail" '(1 2)
         (match '(1 2 3) ((and (a ... b) x) a)))
 
-      (test "list ..1" '(a b c)
-        (match '(a b c) ((x ..1) x)))
+      (test "list **1" '(a b c)
+        (match '(a b c) ((x **1) x)))
 
-      (test "list ..1 failed" #f
+      (test "list **1 failed" #f
         (match '()
-          ((x ..1) x)
+          ((x **1) x)
           (else #f)))
 
-      (test "list ..1 with predicate" '(a b c)
+      (test "list **1 with predicate" '(a b c)
         (match '(a b c)
-          (((and x (? symbol?)) ..1) x)))
+          (((and x (? symbol?)) **1) x)))
 
-      (test "list ..1 with failed predicate" #f
+      (test "list **1 with failed predicate" #f
         (match '(a b 3)
-          (((and x (? symbol?)) ..1) x)
+          (((and x (? symbol?)) **1) x)
           (else #f)))
 
-      (test "list ..= too few" #f
-        (match (list 1 2) ((a b ..= 2) b) (else #f)))
-      (test "list ..=" '(2 3)
-        (match (list 1 2 3) ((a b ..= 2) b) (else #f)))
-      (test "list ..= too many" #f
-        (match (list 1 2 3 4) ((a b ..= 2) b) (else #f)))
-      (test "list ..= tail" 4
-        (match (list 1 2 3 4) ((a b ..= 2 c) c) (else #f)))
-      (test "list ..= tail fail" #f
-        (match (list 1 2 3 4 5 6) ((a b ..= 2 c) c) (else #f)))
-
-      (test "list ..* too few" #f
-        (match (list 1 2) ((a b ..* 2 4) b) (else #f)))
-      (test "list ..* lo" '(2 3)
-        (match (list 1 2 3) ((a b ..* 2 4) b) (else #f)))
-      (test "list ..* hi" '(2 3 4 5)
-        (match (list 1 2 3 4 5) ((a b ..* 2 4) b) (else #f)))
-      (test "list ..* too many" #f
-        (match (list 1 2 3 4 5 6) ((a b ..* 2 4) b) (else #f)))
-      (test "list ..* tail" 4
-        (match (list 1 2 3 4) ((a b ..* 2 4 c) c) (else #f)))
-      (test "list ..* tail 2" 5
-        (match (list 1 2 3 4 5) ((a b ..* 2 4 c d) d) (else #f)))
-      (test "list ..* tail" 6
-        (match (list 1 2 3 4 5 6) ((a b ..* 2 4 c) c) (else #f)))
-      (test "list ..* tail fail" #f
-        (match (list 1 2 3 4 5 6 7) ((a b ..* 2 4 c) c) (else #f)))
+      (test "list =.. too few" #f
+        (match (list 1 2) ((a b =.. 2) b) (else #f)))
+      (test "list =.." '(2 3)
+        (match (list 1 2 3) ((a b =.. 2) b) (else #f)))
+      (test "list =.. too many" #f
+        (match (list 1 2 3 4) ((a b =.. 2) b) (else #f)))
+      (test "list =.. tail" 4
+        (match (list 1 2 3 4) ((a b =.. 2 c) c) (else #f)))
+      (test "list =.. tail fail" #f
+        (match (list 1 2 3 4 5 6) ((a b =.. 2 c) c) (else #f)))
+
+      (test "list *.. too few" #f
+        (match (list 1 2) ((a b *.. 2 4) b) (else #f)))
+      (test "list *.. lo" '(2 3)
+        (match (list 1 2 3) ((a b *.. 2 4) b) (else #f)))
+      (test "list *.. hi" '(2 3 4 5)
+        (match (list 1 2 3 4 5) ((a b *.. 2 4) b) (else #f)))
+      (test "list *.. too many" #f
+        (match (list 1 2 3 4 5 6) ((a b *.. 2 4) b) (else #f)))
+      (test "list *.. tail" 4
+        (match (list 1 2 3 4) ((a b *.. 2 4 c) c) (else #f)))
+      (test "list *.. tail 2" 5
+        (match (list 1 2 3 4 5) ((a b *.. 2 4 c d) d) (else #f)))
+      (test "list *.. tail" 6
+        (match (list 1 2 3 4 5 6) ((a b *.. 2 4 c) c) (else #f)))
+      (test "list *.. tail fail" #f
+        (match (list 1 2 3 4 5 6 7) ((a b *.. 2 4 c) c) (else #f)))
 
       (test "match-named-let" 6
         (match-let loop (((x . rest) '(1 2 3))
@@ -231,10 +241,20 @@
                 sum
                 (loop rest sum)))))
 
-      '(test "match-letrec" '(2 1 1 2)
+      (test "match-letrec" '(2 1 1 2)
           (match-letrec (((x y) (list 1 (lambda () (list a x))))
                          ((a b) (list 2 (lambda () (list x a)))))
                         (append (y) (b))))
+      (test "match-letrec quote" #t
+        (match-letrec (((x 'x) (list #t 'x))) x))
+      (let-syntax
+        ((foo
+          (syntax-rules ()
+            ((foo x)
+             (match-letrec (((x y) (list 1 (lambda () (list a x))))
+                            ((a b) (list 2 (lambda () (list x a)))))
+                           (append (y) (b)))))))
+        (test "match-letrec mnieper" '(2 1 1 2) (foo a)))
 
       (cond-expand
        (chibi
--- chibi-scheme-0.9.1.orig/lib/chibi/match/match.scm
+++ chibi-scheme-0.9.1/lib/chibi/match/match.scm
@@ -86,19 +86,26 @@
 ;;> \scheme{___} is provided as an alias for \scheme{...} when it is
 ;;> inconvenient to use the ellipsis (as in a syntax-rules template).
 
-;;> The \scheme{..1} syntax is exactly like the \scheme{...} except
+;;> The \scheme{**1} syntax is exactly like the \scheme{...} except
 ;;> that it matches one or more repetitions (like a regexp "+").
 
-;;> \example{(match (list 1 2) ((a b c ..1) c))}
-;;> \example{(match (list 1 2 3) ((a b c ..1) c))}
+;;> \example{(match (list 1 2) ((a b c **1) c))}
+;;> \example{(match (list 1 2 3) ((a b c **1) c))}
 
-;;> The \scheme{..=} syntax is like \scheme{...} except that it takes
-;;> a tailing integer \scheme{<n>} and requires the pattern to match
-;;> exactly \scheme{<n>} times.
-
-;;> \example{(match (list 1 2) ((a b ..= 2) b))}
-;;> \example{(match (list 1 2 3) ((a b ..= 2) b))}
-;;> \example{(match (list 1 2 3 4) ((a b ..= 2) b))}
+;;> The \scheme{*..} syntax is like \scheme{...} except that it takes
+;;> two trailing integers \scheme{<n>} and \scheme{<m>}, and requires
+;;> the pattern to match from \scheme{<n>} times.
+
+;;> \example{(match (list 1 2 3) ((a b *.. 2 4) b))}
+;;> \example{(match (list 1 2 3 4 5 6) ((a b *.. 2 4) b))}
+;;> \example{(match (list 1 2 3 4) ((a b *.. 2 4 c) c))}
+
+;;> The \scheme{(<expr> =.. <n>)} syntax is a shorthand for
+;;> \scheme{(<expr> *.. <n> <n>)}.
+
+;;> \example{(match (list 1 2) ((a b =.. 2) b))}
+;;> \example{(match (list 1 2 3) ((a b =.. 2) b))}
+;;> \example{(match (list 1 2 3 4) ((a b =.. 2) b))}
 
 ;;> The boolean operators \scheme{and}, \scheme{or} and \scheme{not}
 ;;> can be used to group and negate patterns analogously to their
@@ -235,7 +242,9 @@
 ;; performance can be found at
 ;;   http://synthcode.com/scheme/match-cond-expand.scm
 ;;
-;; 2020/07/06 - adding `..=' and `..*' patterns; fixing ,@ patterns
+;; 2020/09/04 - perf fix for `not`; rename `..=', `..=', `..1' per SRFI 204
+;; 2020/08/21 - fixing match-letrec with unhygienic insertion
+;; 2020/07/06 - adding `..=' and `..=' patterns; fixing ,@ patterns
 ;; 2016/10/05 - treat keywords as literals, not identifiers, in Chicken
 ;; 2016/03/06 - fixing named match-let (thanks to Stefan Israelsson Tampe)
 ;; 2015/05/09 - fixing bug in var extraction of quasiquote patterns
@@ -265,7 +274,7 @@
 
 (define-syntax match-syntax-error
   (syntax-rules ()
-    ((_) (match-syntax-error "invalid match-syntax-error usage"))))
+    ((_) (syntax-error "invalid match-syntax-error usage"))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -361,7 +370,7 @@
 ;; pattern so far.
 
 (define-syntax match-two
-  (syntax-rules (_ ___ ..1 ..= ..* *** quote quasiquote ? $ struct @ object = and or not set! get!)
+  (syntax-rules (_ ___ **1 =.. *.. *** quote quasiquote ? $ struct @ object = and or not set! get!)
     ((match-two v () g+s (sk ...) fk i)
      (if (null? v) (sk ... i) fk))
     ((match-two v (quote p) g+s (sk ...) fk i)
@@ -377,7 +386,8 @@
     ((match-two v (or p ...) g+s sk fk i)
      (match-extract-vars (or p ...) (match-gen-or v (p ...) g+s sk fk i) i ()))
     ((match-two v (not p) g+s (sk ...) fk i)
-     (match-one v p g+s (match-drop-ids fk) (sk ... i) i))
+     (let ((fk2 (lambda () (sk ... i))))
+       (match-one v p g+s (match-drop-ids fk) (fk2) i)))
     ((match-two v (get! getter) (g s) (sk ...) fk i)
      (let ((getter (lambda () g))) (sk ... i)))
     ((match-two v (set! setter) (g (s ...)) (sk ...) fk i)
@@ -397,15 +407,15 @@
      (match-extract-vars p (match-gen-search v p q g+s sk fk i) i ()))
     ((match-two v (p *** . q) g+s sk fk i)
      (match-syntax-error "invalid use of ***" (p *** . q)))
-    ((match-two v (p ..1) g+s sk fk i)
+    ((match-two v (p **1) g+s sk fk i)
      (if (pair? v)
          (match-one v (p ___) g+s sk fk i)
          fk))
-    ((match-two v (p ..= n . r) g+s sk fk i)
+    ((match-two v (p =.. n . r) g+s sk fk i)
      (match-extract-vars
       p
       (match-gen-ellipsis/range n n v p r g+s sk fk i) i ()))
-    ((match-two v (p ..* n m . r) g+s sk fk i)
+    ((match-two v (p *.. n m . r) g+s sk fk i)
      (match-extract-vars
       p
       (match-gen-ellipsis/range n m v p r g+s sk fk i) i ()))
@@ -523,7 +533,8 @@
 (define-syntax match-gen-or
   (syntax-rules ()
     ((_ v p g+s (sk ...) fk (i ...) ((id id-ls) ...))
-     (let ((sk2 (lambda (id ...) (sk ... (i ... id ...)))))
+     (let ((sk2 (lambda (id ...) (sk ... (i ... id ...))))
+           (id (if #f #f)) ...)
        (match-gen-or-step v p g+s (match-drop-ids (sk2 id ...)) fk (i ...))))))
 
 (define-syntax match-gen-or-step
@@ -553,26 +564,27 @@
 
 (define-syntax match-gen-ellipsis
   (syntax-rules ()
-    ((_ v p () g+s (sk ...) fk i ((id id-ls) ...))
-     (match-check-identifier p
-       ;; simplest case equivalent to (p ...), just bind the list
-       (let ((p v))
-         (if (list? p)
-             (sk ... i)
-             fk))
-       ;; simple case, match all elements of the list
-       (let loop ((ls v) (id-ls '()) ...)
-         (cond
-           ((null? ls)
-            (let ((id (reverse id-ls)) ...) (sk ... i)))
-           ((pair? ls)
-            (let ((w (car ls)))
-              (match-one w p ((car ls) (set-car! ls))
-                         (match-drop-ids (loop (cdr ls) (cons id id-ls) ...))
-                         fk i)))
-           (else
-            fk)))))
-    ((_ v p r g+s (sk ...) fk i ((id id-ls) ...))
+    ;; TODO: restore fast path when p is not already bound
+    ;; ((_ v p () g+s (sk ...) fk i ((id id-ls) ...))
+    ;;  (match-check-identifier p
+    ;;    ;; simplest case equivalent to (p ...), just bind the list
+    ;;    (let ((p v))
+    ;;      (if (list? p)
+    ;;          (sk ... i)
+    ;;          fk))
+    ;;    ;; simple case, match all elements of the list
+    ;;    (let loop ((ls v) (id-ls '()) ...)
+    ;;      (cond
+    ;;        ((null? ls)
+    ;;         (let ((id (reverse id-ls)) ...) (sk ... i)))
+    ;;        ((pair? ls)
+    ;;         (let ((w (car ls)))
+    ;;           (match-one w p ((car ls) (set-car! ls))
+    ;;                      (match-drop-ids (loop (cdr ls) (cons id id-ls) ...))
+    ;;                      fk i)))
+    ;;        (else
+    ;;         fk)))))
+    ((_ v p r g+s sk fk (i ...) ((id id-ls) ...))
      ;; general case, trailing patterns to match, keep track of the
      ;; remaining list length so we don't need any backtracking
      (match-verify-no-ellipsis
@@ -586,14 +598,14 @@
               (cond
                 ((= n tail-len)
                  (let ((id (reverse id-ls)) ...)
-                   (match-one ls r (#f #f) (sk ...) fk i)))
+                   (match-one ls r (#f #f) sk fk (i ... id ...))))
                 ((pair? ls)
                  (let ((w (car ls)))
                    (match-one w p ((car ls) (set-car! ls))
                               (match-drop-ids
                                (loop (cdr ls) (- n 1) (cons id id-ls) ...))
                               fk
-                              i)))
+                              (i ...))))
                 (else
                  fk)))))))))
 
@@ -601,7 +613,7 @@
 
 (define-syntax match-gen-ellipsis/qq
   (syntax-rules ()
-    ((_ v p r g+s (sk ...) fk i ((id id-ls) ...))
+    ((_ v p r g+s (sk ...) fk (i ...) ((id id-ls) ...))
      (match-verify-no-ellipsis
       r
       (let* ((tail-len (length 'r))
@@ -613,14 +625,14 @@
               (cond
                ((= n tail-len)
                 (let ((id (reverse id-ls)) ...)
-                  (match-quasiquote ls r g+s (sk ...) fk i)))
+                  (match-quasiquote ls r g+s (sk ...) fk (i ... id ...))))
                ((pair? ls)
                 (let ((w (car ls)))
                   (match-one w p ((car ls) (set-car! ls))
                              (match-drop-ids
                               (loop (cdr ls) (- n 1) (cons id id-ls) ...))
                              fk
-                             i)))
+                             (i ...))))
                (else
                 fk)))))))))
 
@@ -630,7 +642,7 @@
 
 (define-syntax match-gen-ellipsis/range
   (syntax-rules ()
-    ((_ %lo %hi v p r g+s (sk ...) fk i ((id id-ls) ...))
+    ((_ %lo %hi v p r g+s (sk ...) fk (i ...) ((id id-ls) ...))
      ;; general case, trailing patterns to match, keep track of the
      ;; remaining list length so we don't need any backtracking
      (match-verify-no-ellipsis
@@ -645,14 +657,14 @@
               (cond
                 ((= j len)
                  (let ((id (reverse id-ls)) ...)
-                   (match-one ls r (#f #f) (sk ...) fk i)))
+                   (match-one ls r (#f #f) (sk ...) fk (i ... id ...))))
                 ((pair? ls)
                  (let ((w (car ls)))
                    (match-one w p ((car ls) (set-car! ls))
                               (match-drop-ids
                                (loop (cdr ls) (+ j 1) (cons id id-ls) ...))
                               fk
-                              i)))
+                              (i ...))))
                 (else
                  fk)))
             fk))))))
@@ -822,7 +834,7 @@
 ;; (match-extract-vars pattern continuation (ids ...) (new-vars ...))
 
 (define-syntax match-extract-vars
-  (syntax-rules (_ ___ ..1 ..= ..* *** ? $ struct @ object = quote quasiquote and or not get! set!)
+  (syntax-rules (_ ___ **1 =.. *.. *** ? $ struct @ object = quote quasiquote and or not get! set!)
     ((match-extract-vars (? pred . p) . x)
      (match-extract-vars p . x))
     ((match-extract-vars ($ rec . p) . x)
@@ -859,9 +871,9 @@
     ((match-extract-vars _ (k ...) i v)    (k ... v))
     ((match-extract-vars ___ (k ...) i v)  (k ... v))
     ((match-extract-vars *** (k ...) i v)  (k ... v))
-    ((match-extract-vars ..1 (k ...) i v)  (k ... v))
-    ((match-extract-vars ..= (k ...) i v)  (k ... v))
-    ((match-extract-vars ..* (k ...) i v)  (k ... v))
+    ((match-extract-vars **1 (k ...) i v)  (k ... v))
+    ((match-extract-vars =.. (k ...) i v)  (k ... v))
+    ((match-extract-vars *.. (k ...) i v)  (k ... v))
     ;; This is the main part, the only place where we might add a new
     ;; var if it's an unbound symbol.
     ((match-extract-vars p (k ...) (i ...) v)
@@ -939,34 +951,24 @@
 (define-syntax match-let
   (syntax-rules ()
     ((_ ((var value) ...) . body)
-     (match-let/helper let () () ((var value) ...) . body))
+     (match-let/aux () () ((var value) ...) . body))
     ((_ loop ((var init) ...) . body)
      (match-named-let loop () ((var init) ...) . body))))
 
-;;> Similar to \scheme{match-let}, but analogously to \scheme{letrec}
-;;> matches and binds the variables with all match variables in scope.
-
-(define-syntax match-letrec
+(define-syntax match-let/aux
   (syntax-rules ()
-    ((_ ((var value) ...) . body)
-     (match-let/helper letrec () () ((var value) ...) . body))))
-
-(define-syntax match-let/helper
-  (syntax-rules ()
-    ((_ let ((var expr) ...) () () . body)
+    ((_ ((var expr) ...) () () . body)
      (let ((var expr) ...) . body))
-    ((_ let ((var expr) ...) ((pat tmp) ...) () . body)
+    ((_ ((var expr) ...) ((pat tmp) ...) () . body)
      (let ((var expr) ...)
        (match-let* ((pat tmp) ...)
          . body)))
-    ((_ let (v ...) (p ...) (((a . b) expr) . rest) . body)
-     (match-let/helper
-      let (v ... (tmp expr)) (p ... ((a . b) tmp)) rest . body))
-    ((_ let (v ...) (p ...) ((#(a ...) expr) . rest) . body)
-     (match-let/helper
-      let (v ... (tmp expr)) (p ... (#(a ...) tmp)) rest . body))
-    ((_ let (v ...) (p ...) ((a expr) . rest) . body)
-     (match-let/helper let (v ... (a expr)) (p ...) rest . body))))
+    ((_ (v ...) (p ...) (((a . b) expr) . rest) . body)
+     (match-let/aux (v ... (tmp expr)) (p ... ((a . b) tmp)) rest . body))
+    ((_ (v ...) (p ...) ((#(a ...) expr) . rest) . body)
+     (match-let/aux (v ... (tmp expr)) (p ... (#(a ...) tmp)) rest . body))
+    ((_ (v ...) (p ...) ((a expr) . rest) . body)
+     (match-let/aux (v ... (a expr)) (p ...) rest . body))))
 
 (define-syntax match-named-let
   (syntax-rules ()
@@ -990,6 +992,87 @@
     ((_ ((pat expr) . rest) . body)
      (match expr (pat (match-let* rest . body))))))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Challenge stage - unhygienic insertion.
+;;
+;; It's possible to implement match-letrec without unhygienic
+;; insertion by building the let+set! logic directly into the match
+;; code above (passing a parameter to distinguish let vs letrec).
+;; However, it makes the code much more complicated, so we religate
+;; the complexity here.
+
+;;> Similar to \scheme{match-let}, but analogously to \scheme{letrec}
+;;> matches and binds the variables with all match variables in scope.
+
+(define-syntax match-letrec
+  (syntax-rules ()
+    ((_ ((pat val) ...) . body)
+     (match-letrec-one (pat ...) (((pat val) ...) . body) ()))))
+
+;; 1: extract all ids in all patterns
+(define-syntax match-letrec-one
+  (syntax-rules ()
+    ((_ (pat . rest) expr ((id tmp) ...))
+     (match-extract-vars
+      pat (match-letrec-one rest expr) (id ...) ((id tmp) ...)))
+    ((_ () expr ((id tmp) ...))
+     (match-letrec-two expr () ((id tmp) ...)))))
+
+;; 2: rewrite ids
+(define-syntax match-letrec-two
+  (syntax-rules ()
+    ((_ (() . body) ((var2 val2) ...) ((id tmp) ...))
+     ;; We know the ids, their tmp names, and the renamed patterns
+     ;; with the tmp names - expand to the classic letrec pattern of
+     ;; let+set!.  That is, we bind the original identifiers written
+     ;; in the source with let, run match on their renamed versions,
+     ;; then set! the originals to the matched values.
+     (let ((id (if #f #f)) ...)
+       (match-let ((var2 val2) ...)
+          (set! id tmp) ...
+          . body)))
+    ((_ (((var val) . rest) . body) ((var2 val2) ...) ids)
+     (match-rewrite
+      var
+      ids
+      (match-letrec-two-step (rest . body) ((var2 val2) ...) ids val)))))
+
+(define-syntax match-letrec-two-step
+  (syntax-rules ()
+    ((_ next (rewrites ...) ids val var)
+     (match-letrec-two next (rewrites ... (var val)) ids))))
+
+;; This is where the work is done.  To rewrite all occurrences of any
+;; id with its tmp, we need to walk the expression, using CPS to
+;; restore the original structure.  We also need to be careful to pass
+;; the tmp directly to the macro doing the insertion so that it
+;; doesn't get renamed.  This trick was originally found by Al*
+;; Petrofsky in a message titled "How to write seemingly unhygienic
+;; macros using syntax-rules" sent to comp.lang.scheme in Nov 2001.
+
+(define-syntax match-rewrite
+  (syntax-rules (quote)
+    ((match-rewrite (quote x) ids (k ...))
+     (k ... (quote x)))
+    ((match-rewrite (p . q) ids k)
+     (match-rewrite p ids (match-rewrite2 q ids (match-cons k))))
+    ((match-rewrite () ids (k ...))
+     (k ... ()))
+    ((match-rewrite p () (k ...))
+     (k ... p))
+    ((match-rewrite p ((id tmp) . rest) (k ...))
+     (match-bound-identifier=? p id (k ... tmp) (match-rewrite p rest (k ...))))
+    ))
+
+(define-syntax match-rewrite2
+  (syntax-rules ()
+    ((match-rewrite2 q ids (k ...) p)
+     (match-rewrite q ids (k ... p)))))
+
+(define-syntax match-cons
+  (syntax-rules ()
+    ((match-cons (k ...) p q)
+     (k ... (p . q)))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Otherwise COND-EXPANDed bits.
@@ -1007,7 +1090,13 @@
      (lambda (expr rename compare)
        (if (identifier? (cadr expr))
            (car (cddr expr))
-           (cadr (cddr expr)))))))
+           (cadr (cddr expr))))))
+  (define-syntax match-bound-identifier=?
+    (er-macro-transformer
+     (lambda (expr rename compare)
+       (if (eq? (cadr expr) (car (cddr expr)))
+           (cadr (cddr expr))
+           (car (cddr (cddr expr))))))))
 
  (chicken
   (define-syntax match-check-ellipsis
@@ -1021,7 +1110,13 @@
      (lambda (expr rename compare)
        (if (and (symbol? (cadr expr)) (not (keyword? (cadr expr))))
            (car (cddr expr))
-           (cadr (cddr expr)))))))
+           (cadr (cddr expr))))))
+  (define-syntax match-bound-identifier=?
+    (er-macro-transformer
+     (lambda (expr rename compare)
+       (if (eq? (cadr expr) (car (cddr expr)))
+           (cadr (cddr expr))
+           (car (cddr (cddr expr))))))))
 
  (else
   ;; Portable versions
@@ -1070,4 +1165,16 @@
                ((sym? x sk fk) sk)
                ;; otherwise x is a non-symbol datum
                ((sym? y sk fk) fk))))
-         (sym? abracadabra success-k failure-k)))))))
+         (sym? abracadabra success-k failure-k)))))
+
+  ;; This check is inlined in some cases above, but included here for
+  ;; the convenience of match-rewrite.
+  (define-syntax match-bound-identifier=?
+    (syntax-rules ()
+      ((match-bound-identifier=? a b sk fk)
+       (let-syntax ((b (syntax-rules ())))
+         (let-syntax ((eq (syntax-rules (b)
+                            ((eq b) sk)
+                            ((eq _) fk))))
+           (eq a))))))
+  ))
--- chibi-scheme-0.9.1.orig/lib/chibi/net/http-server.scm
+++ chibi-scheme-0.9.1/lib/chibi/net/http-server.scm
@@ -40,16 +40,28 @@
         (cond
          ((= 2 (length ls))
           (let ((request
-                 (make-request command (car ls) (cadr ls) in out sock addr)))
-            (log-info `(request: ,command ,(car ls) ,(cadr ls)
-                                 ,(request-headers request)))
-            (protect (exn
+                 (protect
+                     (exn
                       (else
-                       (log-error "internal error: " exn)
-                       (print-stack-trace exn)
-                       (servlet-respond request 500 "Internal server error")))
-              (let restart ((request request))
-                (servlet cfg request servlet-bad-request restart)))))
+                       ;; error parsing headers, can't use servlet-respond
+                       (log-error "request error: " exn ls
+                                  (sockaddr-name (address-info-address addr)))
+                       (servlet-write-status out 500 "Internal server error")
+                       (mime-write-headers `((Status . "500")) out)
+                       (display "\r\n" out)
+                       #f))
+                   (make-request command (car ls) (cadr ls) in out sock addr))))
+            (cond
+             (request
+              (log-info `(request: ,command ,(car ls) ,(cadr ls)
+                                   ,(request-headers request)))
+              (protect (exn
+                        (else
+                         (log-error "internal error: " exn)
+                         (print-stack-trace exn)
+                         (servlet-respond request 500 "Internal server error")))
+                (let restart ((request request))
+                  (servlet cfg request servlet-bad-request restart)))))))
          (else
           (let ((request (make-request command #f #f in out sock addr)))
             (servlet-respond request 400 "bad request")))))))))
--- chibi-scheme-0.9.1.orig/lib/chibi/net/http-server.sld
+++ chibi-scheme-0.9.1/lib/chibi/net/http-server.sld
@@ -9,10 +9,11 @@
    http-regexp-servlet http-path-regexp-servlet http-uri-regexp-servlet
    http-host-regexp-servlet http-redirect-servlet http-rewrite-servlet
    http-cgi-bin-dir-servlet http-scheme-script-dir-servlet)
-  (import (scheme time) (srfi 39) (srfi 95)
-          (chibi) (chibi mime) (chibi regexp) (chibi pathname) (chibi uri)
-          (chibi filesystem) (chibi io) (chibi string) (chibi process)
-          (chibi net server) (chibi net server-util) (chibi net servlet)
-          (chibi app) (chibi ast) (chibi config) (chibi log) (chibi memoize)
-          (chibi temp-file))
+  (import
+   (scheme time) (srfi 39) (srfi 95)
+   (chibi) (chibi mime) (chibi regexp) (chibi pathname) (chibi uri)
+   (chibi filesystem) (chibi io) (chibi string) (chibi process)
+   (chibi net) (chibi net server) (chibi net server-util) (chibi net servlet)
+   (chibi app) (chibi ast) (chibi config) (chibi log) (chibi memoize)
+   (chibi temp-file))
   (include "http-server.scm"))
--- chibi-scheme-0.9.1.orig/lib/chibi/net/servlet.sld
+++ chibi-scheme-0.9.1/lib/chibi/net/servlet.sld
@@ -17,7 +17,7 @@
    request-uri-string request-with-uri request-path
    copy-request make-request make-cgi-request
    ;; servlets
-   servlet-write servlet-respond servlet-parse-body!
+   servlet-write servlet-write-status servlet-respond servlet-parse-body!
    make-status-servlet servlet-handler servlet-run
    servlet-bad-request)
   (import
--- chibi-scheme-0.9.1.orig/lib/chibi/optional-test.sld
+++ chibi-scheme-0.9.1/lib/chibi/optional-test.sld
@@ -1,6 +1,37 @@
 
 (define-library (chibi optional-test)
-  (import (scheme base) (chibi optional) (chibi test))
+  (import (scheme base) (chibi optional))
+  (cond-expand
+   (chibi (import (chibi test)))
+   (else
+    (import (scheme write))
+    ;; inline (chibi test) to avoid circular dependencies in snow
+    ;; installations
+    (begin
+      (define-syntax test
+       (syntax-rules ()
+         ((test expect expr)
+          (test 'expr expect expr))
+         ((test name expect expr)
+          (guard (exn (else (display "!\nERROR: ") (write name) (newline)
+                            (write exn) (newline)))
+            (let* ((res expr)
+                   (pass? (equal? expect expr)))
+              (display (if pass? "." "x"))
+              (cond
+               ((not pass?)
+                (display "\nFAIL: ") (write name) (newline))))))))
+      (define-syntax test-assert
+        (syntax-rules ()
+          ((test-assert expr) (test #t expr))))
+      (define-syntax test-error
+        (syntax-rules ()
+          ((test-error expr)
+           (test-assert (guard (exn (else #t)) expr #f)))))
+      (define (test-begin name)
+        (display name))
+      (define (test-end)
+        (newline)))))
   (export run-tests)
   (begin
     (define (run-tests)
@@ -22,13 +53,18 @@
       (test '(0 1 (2 3 4))
           (let-optionals '(0 1 2 3 4) ((a 10) (b 11) . c)
             (list a b c)))
-      (test-error '(0 11 12)
-          ((opt-lambda (a (b 11) (c 12))
-             (list a b c))))
+      (cond-expand
+       (gauche)     ; gauche detects this at compile-time, can't catch
+       (else (test-error '(0 11 12)
+                         ((opt-lambda (a (b 11) (c 12))
+                            (list a b c))))))
       (let ()
         (define-opt (f a (b 11) (c 12))
           (list a b c))
-        (test-error (f))
+        (cond-expand
+         (gauche)
+         (else
+          (test-error (f))))
         (test '(0 11 12) (f 0))
         (test '(0 1 12) (f 0 1))
         (test '(0 1 2) (f 0 1 2))
--- chibi-scheme-0.9.1.orig/lib/chibi/repl.scm
+++ chibi-scheme-0.9.1/lib/chibi/repl.scm
@@ -401,48 +401,38 @@
         (else (push-history-value! value))))
 
 (define (repl/eval rp expr-list)
-  (let ((out (repl-out rp)))
-    (protect (exn (else (print-exception exn out)))
-      (let ((thread
-             (make-thread
-              (lambda ()
-                ;; The inner protect in the child thread catches errors
-                ;; from eval.
-                (protect (exn
-                          (else
-                           (print-exception exn out)
-                           (repl-advise-exception exn (current-error-port))))
+  (let ((thread (current-thread))
+        (out (repl-out rp)))
+    (with-signal-handler
+     signal/interrupt
+     (lambda (n) (thread-interrupt! thread))
+     (lambda ()
+       (protect (exn
+                 (else
+                  (print-exception exn out)
+                  (repl-advise-exception exn (current-error-port))))
+         (for-each
+          (lambda (expr)
+            (call-with-values
+                (lambda ()
+                  (if (or (identifier? expr)
+                          (pair? expr)
+                          (null? expr))
+                      (eval expr (repl-env rp))
+                      expr))
+              (lambda res-list
+                (cond
+                 ((not (or (null? res-list)
+                           (equal? res-list (list (if #f #f)))))
+                  (push-history-value-maybe! res-list)
+                  (write/ss (car res-list) out)
                   (for-each
-                   (lambda (expr)
-                     (call-with-values
-                         (lambda ()
-                           (if (or (identifier? expr)
-                                   (pair? expr)
-                                   (null? expr))
-                               (eval expr (repl-env rp))
-                               expr))
-                       (lambda res-list
-                         (cond
-                          ((not (or (null? res-list)
-                                    (equal? res-list (list (if #f #f)))))
-                           (push-history-value-maybe! res-list)
-                           (write/ss (car res-list) out)
-                           (for-each
-                            (lambda (res)
-                              (write-char #\space out)
-                              (write/ss res out))
-                            (cdr res-list))
-                           (newline out))))))
-                   expr-list))))))
-        ;; If an interrupt occurs while the child thread is
-        ;; still running, terminate it, otherwise wait for it
-        ;; to complete.
-        (with-signal-handler
-         signal/interrupt
-         (lambda (n)
-           (display "\nInterrupt\n" out)
-           (thread-terminate! thread))
-         (lambda () (thread-join! (thread-start! thread))))))))
+                   (lambda (res)
+                     (write-char #\space out)
+                     (write/ss res out))
+                   (cdr res-list))
+                  (newline out))))))
+          expr-list))))))
 
 (define (repl/eval-string rp str)
   (repl/eval
--- chibi-scheme-0.9.1.orig/lib/chibi/repl.sld
+++ chibi-scheme-0.9.1/lib/chibi/repl.sld
@@ -5,5 +5,10 @@
           (chibi ast) (chibi modules) (chibi doc)
           (chibi string) (chibi io) (chibi optional)
           (chibi process) (chibi term edit-line)
-          (srfi 1) (srfi 9) (srfi 18) (srfi 38) (srfi 95) (srfi 98))
+          (srfi 1)
+          (srfi 9)
+          (only (srfi 18) current-thread)
+          (srfi 38)
+          (srfi 95)
+          (srfi 98))
   (include "repl.scm"))
--- chibi-scheme-0.9.1.orig/lib/chibi/show/c.scm
+++ chibi-scheme-0.9.1/lib/chibi/show/c.scm
@@ -7,7 +7,7 @@
     ((define-state-variables var ...)
      (begin
        (define var
-         (make-computation-environment-variable 'var #f #f))
+         (make-state-variable 'var #f #f))
        ...))))
 
 (define-state-variables
--- chibi-scheme-0.9.1.orig/lib/chibi/show/c.sld
+++ chibi-scheme-0.9.1/lib/chibi/show/c.sld
@@ -21,5 +21,5 @@
    cpp-error cpp-warning cpp-stringify cpp-sym-cat
    c-comment c-block-comment c-attribute)
   (import (chibi) (chibi string) (chibi show) (chibi show pretty)
-          (srfi 1) (srfi 165) (scheme cxr))
+          (srfi 1) (scheme cxr))
   (include "c.scm"))
--- chibi-scheme-0.9.1.orig/lib/chibi/snow/commands.scm
+++ chibi-scheme-0.9.1/lib/chibi/snow/commands.scm
@@ -3,31 +3,10 @@
 ;; This code was written by Alex Shinn in 2014 and placed in the
 ;; Public Domain.  All warranties are disclaimed.
 
-(define known-implementations
-  '((chibi "chibi-scheme" (chibi-scheme -V) "0.7.3")
-    (chicken "chicken" (csi -release) "4.9.0")
-    (cyclone "cyclone" (icyc -vn) "0.5.3")
-    (foment "foment")
-    (gauche "gosh" (gosh -E "print (gauche-version)" -E exit) "0.9.4")
-    (kawa "kawa" (kawa --version) "2.0")
-    (larceny "larceny" (larceny --version) "v0.98")
-    (sagittarius "sagittarius")))
-
-(define (impl->version impl cmd)
-  (let* ((lines (process->string-list cmd))
-         (line (and (pair? lines) (string-split (car lines)))))
-    (and (pair? line)
-         (if (and (pair? (cdr line))
-                  (let ((x (string-downcase (car line)))
-                        (name (symbol->string impl)))
-                    (or (equal? x name)
-                        (equal? x (string-append name "-scheme")))))
-             (cadr line)
-             (car line)))))
-
 (define (impl-available? cfg spec confirm?)
   (if (find-in-path (cadr spec))
       (or (null? (cddr spec))
+          (not (third spec))
           (conf-get cfg 'skip-version-checks?)
           (let ((version (impl->version (car spec) (third spec))))
             (or (and version (version>=? version (fourth spec)))
@@ -968,9 +947,12 @@
    ((package-file? (car o))
     (if (not (every package-file? (cdr o)))
         (non-homogeneous))
-    (for-each
-     (lambda (package) (upload-package cfg spec package))
-     o))
+    ;; TODO: include a summary (version, file size, etc.)
+    (if (yes-or-no? cfg "Upload " o " to "
+                    (remote-uri cfg '(command package uri) "/?"))
+      (for-each
+       (lambda (package) (upload-package cfg spec package))
+       o)))
    (else
     (if (any package-file? (cdr o))
         (non-homogeneous))
@@ -979,7 +961,10 @@
            (package (create-package (car spec+files)
                                     (cdr spec+files)
                                     package-file)))
-      (upload-package cfg spec package package-file)))))
+      ;; TODO: include a summary (version, file size, etc.)
+      (if (yes-or-no? cfg "Upload " o " to "
+                      (remote-uri cfg '(command package uri) "/?"))
+        (upload-package cfg spec package package-file))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Remove - removes the listed libraries.
@@ -1168,7 +1153,7 @@
          (local-tmp (string-append local-path ".tmp."
                                    (number->string (current-second)) "-"
                                    (number->string (current-process-id))))
-         (repo-str (utf8->string (resource->bytevector repo-uri)))
+         (repo-str (utf8->string (resource->bytevector cfg repo-uri)))
          (repo (guard (exn (else #f))
                  (let ((repo (read (open-input-string repo-str))))
                    `(,(car repo) (url ,repo-uri) ,@(cdr repo))))))
@@ -1580,7 +1565,9 @@
           ((and (equal? "meta" (path-extension file))
                 (guard (exn (else #f))
                   (let ((pkg (call-with-input-file file read)))
-                    (and (package? pkg) pkg))))
+                    (and (package? pkg)
+                         (every file-exists? (package-installed-files pkg))
+                         pkg))))
            => (lambda (pkg)
                 (append
                  (map
@@ -2128,7 +2115,7 @@
     (install-file cfg (make-path dir src) dest)))
 
 (define (fetch-package cfg url)
-  (resource->bytevector url))
+  (resource->bytevector cfg url))
 
 (define (path-strip-top file)
   (let ((pos (string-find file #\/)))
--- chibi-scheme-0.9.1.orig/lib/chibi/snow/package.scm
+++ chibi-scheme-0.9.1/lib/chibi/snow/package.scm
@@ -443,8 +443,10 @@
     #t)
   (cond
    ((symbol? test)
-    (or (eq? 'else test) (eq? impl test)
-        (memq test (conf-get-list config 'features))))
+    (or (eq? test 'else)
+        (eq? test impl)
+        (memq test (conf-get-list config 'features))
+        (memq test (impl->features impl))))
    ((pair? test)
     (case (car test)
       ((not) (not (check-cond-expand impl config (cadr test))))
--- chibi-scheme-0.9.1.orig/lib/chibi/snow/package.sld
+++ chibi-scheme-0.9.1/lib/chibi/snow/package.sld
@@ -30,12 +30,14 @@
           (srfi 1)
           (srfi 115)
           (chibi snow interface)
+          (chibi snow utils)
           (chibi bytevector)
           (chibi config)
           (chibi crypto md5)
           (chibi crypto rsa)
           (chibi crypto sha2)
           (chibi pathname)
+          (chibi process)
           (chibi string)
           (chibi tar)
           (chibi uri)
--- chibi-scheme-0.9.1.orig/lib/chibi/snow/utils.scm
+++ chibi-scheme-0.9.1/lib/chibi/snow/utils.scm
@@ -1,3 +1,72 @@
+(define (write-to-string x)
+  (call-with-output-string (lambda (out) (write x out))))
+
+(define known-implementations
+  `((chibi "chibi-scheme" (chibi-scheme -V) "0.7.3"
+           ,(delay
+              (process->sexp
+               '(chibi-scheme -p "(features)"))))
+    (chicken "chicken" (csi -release) "4.9.0"
+             ;; work around Chicken's write() not quoting 64bit and
+             ;; 32bit properly
+             ,(delay
+                (process->sexp
+                 `(csi -R r7rs -R srfi-1 -e ,(write-to-string
+                                              '(write
+                                                (filter (lambda (x)
+                                                          (not (or (eq? x '|64bit|)
+                                                                   (eq? x '|32bit|))))
+                                                        (features))))))))
+    (cyclone "cyclone" (icyc -vn) "0.5.3"
+             ,(delay
+                (process->sexp
+                 '(icyc -p "(features)"))))
+    (foment "foment" #f #f
+            ,(delay
+               (process->sexp
+                '(foment -e "(write (features))"))))
+    (gauche "gosh" (gosh -E "print (gauche-version)") "0.9.4"
+            ,(delay
+               (process->sexp
+                '(gosh -uscheme.base -e "(write (features))"))))
+    (kawa "kawa" (kawa --version) "2.0"
+          ,(delay
+             (process->sexp
+              '(kawa -e "(write (features))"))))
+    (larceny "larceny" (larceny --version) "v0.98"
+             ,(delay '()))
+    (sagittarius "sagittarius" #f #f
+                 ,(delay
+                    (process->sexp
+                     '(sagittarius -I "(scheme base)" -e "(write (features))"))))))
+
+(define (impl->version impl cmd)
+  (let* ((lines (process->string-list cmd))
+         (line (and (pair? lines) (string-split (car lines)))))
+    (and (pair? line)
+         (if (and (pair? (cdr line))
+                  (let ((x (string-downcase (car line)))
+                        (name (symbol->string impl)))
+                    (or (equal? x name)
+                        (equal? x (string-append name "-scheme")))))
+             (cadr line)
+             (car line)))))
+
+(define (target-is-host? impl)
+  (case impl
+    ((chibi) (cond-expand (chibi #t) (else #f)))
+    ((gauche) (cond-expand (gauche #t) (else #f)))
+    ((sagittarius) (cond-expand (sagittarius #t) (else #f)))
+    (else #f)))
+
+(define (impl->features impl)
+  (cond
+   ((target-is-host? impl)
+    (features))
+   ((assq impl known-implementations)
+    => (lambda (impl)
+         (force (fifth impl))))
+   (else '())))
 
 (define (find-in-path file . o)
   (any (lambda (dir)
@@ -17,18 +86,17 @@
                       (and (pred x) x))))))
          dirs)))
 
-(define (write-to-string x)
-  (call-with-output-string (lambda (out) (write x out))))
-
 (define (display-to-string x)
   (call-with-output-string
     (lambda (out)
       (if (bytevector? x) (write-bytevector x out) (display x out)))))
 
-(define (resource->bytevector uri)
+(define (resource->bytevector cfg uri)
   (let ((uri (if (uri? uri) uri (string->path-uri 'http uri))))
     (if (uri-host uri)
-        (call-with-input-url uri port->bytevector)
+        (if (conf-get cfg 'use-curl?)
+            (process->bytevector `(curl --silent ,(uri->string uri)))
+            (call-with-input-url uri port->bytevector))
         (file->bytevector (uri-path uri)))))
 
 ;; path-normalize either a uri or path, and return the result as a string
@@ -57,7 +125,7 @@
 (define (version-split str)
   (if str
       (map (lambda (x) (or (string->number x) x))
-        (string-split str #\.))
+        (string-split str (string->char-set "._")))
       '()))
 
 (define (version-compare a b)
--- chibi-scheme-0.9.1.orig/lib/chibi/snow/utils.sld
+++ chibi-scheme-0.9.1/lib/chibi/snow/utils.sld
@@ -4,15 +4,21 @@
           write-to-string display-to-string
           resource->bytevector uri-normalize uri-directory
           version-split version-compare version>? version>=?
-          topological-sort)
+          topological-sort
+          known-implementations impl->version impl->features)
   (import (scheme base)
+          (scheme char)
           (scheme file)
+          (scheme lazy)
           (scheme read)
           (scheme write)
           (scheme process-context)
           (srfi 1)
+          (chibi config)
+          (chibi char-set)
           (chibi net http)
           (chibi pathname)
+          (chibi process)
           (chibi string)
           (chibi uri))
   (cond-expand
--- chibi-scheme-0.9.1.orig/lib/chibi/sxml.scm
+++ chibi-scheme-0.9.1/lib/chibi/sxml.scm
@@ -52,6 +52,9 @@
         (apply string-append (reverse (cons ">" res)))
         (lp (cdr ls) (cons (html-attr->string (car ls)) (cons " " res))))))
 
+(define void-elements
+  '(area base br col embed hr img input keygen link meta param source track wbr))
+
 (define (html-display-escaped-string x . o)
   (let* ((str (display-to-string x))
          (start 0)
@@ -81,27 +84,39 @@
 ;;> \var{@raw} tag is considered safe text and not processed or escaped.
 (define (sxml-display-as-html sxml . o)
   (let ((out (if (pair? o) (car o) (current-output-port))))
-    (let lp ((sxml sxml))
+    (let lp ((sxml (if (and (pair? sxml) (eq? '*TOP* (car sxml)))
+                       (cdr sxml)
+                       sxml)))
       (cond
        ((pair? sxml)
-        (let ((tag (car sxml)))
-          (if (symbol? tag)
-              (let ((rest (cdr sxml)))
-                (cond
-                 ((and (pair? rest)
-                       (pair? (car rest))
-                       (eq? '@ (caar rest)))
-                  (display (html-tag->string tag (cdar rest)) out)
-                  (for-each lp (cdr rest))
-                  (display "</" out) (display tag out) (display ">" out))
-                 ((and (eq? '@raw tag)
-                       (string? (car rest)))
-                  (display (car rest) out))
-                 (else
-                  (display (html-tag->string tag '()) out)
-                  (for-each lp rest)
-                  (display "</" out) (display tag out) (display ">" out))))
-              (for-each lp sxml))))
+        (let ((tag (car sxml))
+              (rest (cdr sxml)))
+          (cond
+           ((symbol? tag)
+            (cond
+             ((eqv? #\! (string-ref (symbol->string tag) 0))
+              (display "<" out) (display tag out)
+              (for-each (lambda (x) (display " " out) (display x out)) rest)
+              (display ">\n" out))
+             ((and (eq? '@raw tag)
+                   (string? (car rest)))
+              (if (not (null? (cdr rest)))
+                  (error "@raw takes only one value" sxml))
+              (display (car rest) out))
+             ((and (pair? rest)
+                   (pair? (car rest))
+                   (eq? '@ (caar rest)))
+              (display (html-tag->string tag (cdar rest)) out)
+              (for-each lp (cdr rest))
+              (unless (and (null? (cdr rest)) (memq tag void-elements))
+                (display "</" out) (display tag out) (display ">" out)))
+             (else
+              (display (html-tag->string tag '()) out)
+              (for-each lp rest)
+              (unless (and (null? rest) (memq tag void-elements))
+                (display "</" out) (display tag out) (display ">" out)))))
+           (else
+            (for-each lp sxml)))))
        ((null? sxml))
        (else (html-display-escaped-string sxml out))))))
 
@@ -127,7 +142,9 @@
 ;;> Render \var{sxml} as text for viewing in a terminal.
 (define (sxml-display-as-text sxml . o)
   (let ((out (if (pair? o) (car o) (current-output-port))))
-    (let lp ((sxml sxml))
+    (let lp ((sxml (if (and (pair? sxml) (eq? '*TOP* (car sxml)))
+                       (cdr sxml)
+                       sxml)))
       (cond
        ((pair? sxml)
         (let ((tag (car sxml)))
--- chibi-scheme-0.9.1.orig/lib/chibi/trace.scm
+++ chibi-scheme-0.9.1/lib/chibi/trace.scm
@@ -34,7 +34,7 @@
         (show-trace-result cell args res)
         res))))
 
-;;> Write a trace of all calls to the procedure \var{proc} to
+;;> Write a trace of all calls to the procedure \var{id} to
 ;;> \scheme{(current-error-port)}.
 
 (define-syntax trace
@@ -42,7 +42,7 @@
     ((trace id)
      (trace-cell (env-cell (interaction-environment) 'id)))))
 
-;;> Remove any active traces on the procedure \var{proc}.
+;;> Remove any active traces on the procedure \var{id}.
 
 (define-syntax untrace
   (syntax-rules ()
--- chibi-scheme-0.9.1.orig/lib/init-7.scm
+++ chibi-scheme-0.9.1/lib/init-7.scm
@@ -1273,7 +1273,7 @@
 
 (define (load file . o)
   (let* ((env (if (pair? o) (car o) (interaction-environment)))
-         (len (string-length file))
+         (len (if (port? file) 0 (string-length file)))
          (ext *shared-object-extension*)
          (ext-len (string-length ext)))
     (cond
@@ -1284,15 +1284,16 @@
         (dynamic-wind
           (lambda () (set-current-environment! env))
           (lambda ()
-            (call-with-input-file file
-              (lambda (in)
-                (set-port-line! in 1)
-                (let lp ()
-                  (let ((x (read in)))
-                    (cond
-                     ((not (eof-object? x))
-                      (eval x env)
-                      (lp))))))))
+            (let ((in (if (port? file) file (open-input-file file))))
+              (set-port-line! in 1)
+              (let lp ((res (if #f #f)))
+                (let ((x (read in)))
+                  (cond
+                   ((eof-object? x)
+                    (if (not (port? file))
+                        (close-input-port in)))
+                   (else
+                    (lp (eval x env))))))))
           (lambda () (set-current-environment! old-env))))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
--- chibi-scheme-0.9.1.orig/lib/meta-7.scm
+++ chibi-scheme-0.9.1/lib/meta-7.scm
@@ -91,13 +91,13 @@
         ((pred (to-id (car ls))) (cons (car ls) (id-filter pred (cdr ls))))
         (else (id-filter pred (cdr ls)))))
 
-(define (resolve-import x)
+(define (%resolve-import x)
   (cond
    ((not (and (pair? x) (list? x)))
     (error "invalid import syntax" x))
    ((and (memq (car x) '(prefix drop-prefix))
          (symbol? (car (cddr x))) (list? (cadr x)))
-    (let ((mod-name+imports (resolve-import (cadr x))))
+    (let ((mod-name+imports (%resolve-import (cadr x))))
       (cons (car mod-name+imports)
             (map (lambda (i)
                    (cons ((if (eq? (car x) 'drop-prefix)
@@ -110,7 +110,7 @@
                      (module-exports (find-module (car mod-name+imports))))))))
    ((and (pair? (cdr x)) (pair? (cadr x)))
     (if (memq (car x) '(only except rename))
-        (let* ((mod-name+imports (resolve-import (cadr x)))
+        (let* ((mod-name+imports (%resolve-import (cadr x)))
                (imp-ids (or (cdr mod-name+imports)
                             (and (not (eq? 'only (car x)))
                                  (module-exports
@@ -135,6 +135,29 @@
    (else
     (error "couldn't find import" x))))
 
+;; slightly roundabout, using eval since we don't have env-define! here
+(define (auto-generate-bindings ls)
+  (let ((bound (env-exports *auto-env*))
+        (def-aux
+          (make-syntactic-closure *chibi-env* '() 'define-auxiliary-syntax)))
+    (let lp ((ls ls) (new '()))
+      (cond
+       ((null? ls)
+        (if (pair? new)
+            (eval `(,(make-syntactic-closure *chibi-env* '() 'begin) ,@new)
+                  *auto-env*)))
+       (else
+        (let ((from-id (if (pair? (car ls)) (cdar ls) (car ls))))
+          (if (memq from-id bound)
+              (lp (cdr ls) new)
+              (lp (cdr ls) `((,def-aux ,from-id) ,@new)))))))))
+
+(define (resolve-import x)
+  (let ((x (%resolve-import x)))
+    (if (equal? '(auto) (car x))
+        (auto-generate-bindings (cdr x)))
+    x))
+
 (define (resolve-module-imports env meta)
   (for-each
    (lambda (x)
@@ -415,18 +438,29 @@
               (else
                (error "couldn't find module" (car ls))))))))))))
 
+;; capture a static copy of the current environment to serve
+;; as the (chibi) module
+(define *chibi-env*
+  (let ((env (make-environment)))
+    (%import env (interaction-environment) #f #t)
+    (env-parent env)))
+
+(define *auto-env*
+  (let ((env (make-environment)))
+    (%import env (interaction-environment)
+             '(_ => ... else unquote unquote-splicing) #t)
+    (env-parent env)))
+
 (define *modules*
   (list
    (cons '(chibi)
-         ;; capture a static copy of the current environment to serve
-         ;; as the (chibi) module
-         (let ((env (make-environment)))
-           (%import env (interaction-environment) #f #t)
-           (make-module #f (env-parent env) '((include "init-7.scm")))))
+         (make-module #f *chibi-env* '((include "init-7.scm"))))
    (cons '(chibi primitive)
          (make-module #f #f (lambda (env) (primitive-environment 7))))
    (cons '(meta)
          (make-module #f (current-environment) '((include "meta-7.scm"))))
+   (cons '(auto)
+         (make-module #f *auto-env* '()))
    (cons '(srfi 0)
          (make-module (list 'cond-expand)
                       (current-environment)
--- chibi-scheme-0.9.1.orig/lib/srfi/145.sld
+++ chibi-scheme-0.9.1/lib/srfi/145.sld
@@ -1,30 +1,23 @@
-
 (define-library (srfi 145)
   (export assume)
   (import (scheme base))
   (cond-expand
-   (elide-assumptions
-    (begin
-      (define-syntax assume
-        (syntax-rules ()
-          ((assume expression objs ...)
-           expression)
-          ((assume)
-           (syntax-error "assume requires an expression"))))))
-   (else
-    (begin
-      (define-syntax assume
-        (syntax-rules ()
-          ((assume expression objs ...)
-           (or expression
-               (fatal-error "invalid assumption" 'expression objs ...)))
-          ((assume)
-           (syntax-error "assume requires an expression")))))))
-  (cond-expand
-   (debug
-    (begin
-      (define fatal-error error)))
-   (else
-    (begin
-      (define (fatal-error message . objs)
-        (car 0))))))
+    ((or elide-assumptions
+         (and (not assumptions)
+              (not debug)))
+     (begin
+       (define-syntax assume
+         (syntax-rules ()
+           ((assume expression objs ...)
+            expression)
+           ((assume)
+            (syntax-error "assume requires an expression"))))))
+    (else
+     (begin
+       (define-syntax assume
+         (syntax-rules ()
+           ((assume expression objs ...)
+            (or expression
+                (error "invalid assumption" 'expression objs ...)))
+           ((assume)
+            (syntax-error "assume requires an expression"))))))))
--- chibi-scheme-0.9.1.orig/lib/srfi/158.scm
+++ chibi-scheme-0.9.1/lib/srfi/158.scm
@@ -486,10 +486,8 @@
 ;; generator-find
 (define (generator-find pred g)
   (let loop ((v (g)))
-   ; A literal interpretation might say it only terminates on #eof if (pred #eof) but I think this makes more sense...
-   (if (or (pred v) (eof-object? v))
-     v
-     (loop (g)))))
+    (and (not (eof-object? v))
+         (if (pred v) v (loop (g))))))
 
 
 ;; generator-count
--- chibi-scheme-0.9.1.orig/lib/srfi/160/test.sld
+++ chibi-scheme-0.9.1/lib/srfi/160/test.sld
@@ -27,6 +27,10 @@
         (test '#u32(0 1 2 3) (u32vector-concatenate '(#u32(0 1) #u32(2 3))))
         (test '#u32(0 1 6 7)
           (u32vector-append-subvectors '#u32(0 1 2 3 4) 0 2 '#u32(4 5 6 7 8) 2 4))
+        (test '#u32(1 2)
+          (vector->u32vector '#(0 1 2 3) 1 3))
+        (test '#(1 2)
+          (u32vector->vector '#u32(0 1 2 3) 1 3))
         )
 
       (test-group "uvectors/predicates"
--- chibi-scheme-0.9.1.orig/lib/srfi/160/uvector.scm
+++ chibi-scheme-0.9.1/lib/srfi/160/uvector.scm
@@ -318,11 +318,11 @@
 (define (uvector->list vec . o)
   (reverse (apply reverse-vector->list vec o)))
 
-(define (uvector->vector vec)
-  (list->vector (uvector->list vec)))
+(define (uvector->vector vec . o)
+  (list->vector (apply uvector->list vec o)))
 
-(define (vector->uvector vec)
-  (list->uvector (vector->list vec)))
+(define (vector->uvector vec . o)
+  (list->uvector (apply vector->list vec o)))
 
 (define make-vector-generator
   (let ((eof (read-char (open-input-string ""))))
--- chibi-scheme-0.9.1.orig/lib/srfi/166.sld
+++ chibi-scheme-0.9.1/lib/srfi/166.sld
@@ -17,6 +17,7 @@
    ;; computations
    fn with with! forked call-with-output
    ;; state variables
+   make-state-variable
    port row col width output writer pad-char ellipsis
    string-width substring/width substring/preserve
    radix precision decimal-sep decimal-align sign-rule
--- chibi-scheme-0.9.1.orig/lib/srfi/166/base.sld
+++ chibi-scheme-0.9.1/lib/srfi/166/base.sld
@@ -12,7 +12,8 @@
           (rename (srfi 165)
                   (computation-each sequence)
                   (computation-with! with!)
-                  (computation-forked forked))
+                  (computation-forked forked)
+                  (make-computation-environment-variable make-state-variable))
           (chibi show shared))
   (cond-expand
    (chibi
@@ -45,6 +46,7 @@
    ;; computations
    fn with with! forked call-with-output
    ;; state variables
+   make-state-variable
    port row col width output writer pad-char ellipsis
    string-width substring/width substring/preserve
    radix precision decimal-sep decimal-align sign-rule
--- chibi-scheme-0.9.1.orig/lib/srfi/166/color.scm
+++ chibi-scheme-0.9.1/lib/srfi/166/color.scm
@@ -8,6 +8,11 @@
     ((dark) "2")
     ((italic) "3")
     ((underline) "4")
+
+    ((bold-off) "22")
+    ((italic-off) "23")
+    ((underline-off) "24")
+
     ((black) "30")
     ((red) "31")
     ((green) "32")
@@ -16,7 +21,8 @@
     ((magenta) "35")
     ((cyan) "36")
     ((white) "37")
-    ((reset) "39")
+    ((default-fg) "39")
+
     ((on-black) "40")
     ((on-red) "41")
     ((on-green) "42")
@@ -25,45 +31,47 @@
     ((on-magenta) "45")
     ((on-cyan) "46")
     ((on-white) "47")
-    ((on-reset) "49")
-    (else "0")))
+    ((default-bg) "49")))
 
 (define (ansi-escape color)
   (if (string? color)
       color
       (string-append "\x1B;[" (color->ansi color) "m")))
 
-(define (colored new-color . args)
-  (fn ((orig-color color))
-    (with ((color new-color))
-      (each (ansi-escape new-color)
-            (each-in-list args)
-            (if (or (memq new-color '(bold underline))
-                    (memq orig-color '(bold underline)))
-                (ansi-escape 'reset)
-                nothing)
-            (ansi-escape orig-color)))))
-
-(define (as-red . args) (colored 'red (each-in-list args)))
-(define (as-blue . args) (colored 'blue (each-in-list args)))
-(define (as-green . args) (colored 'green (each-in-list args)))
-(define (as-cyan . args) (colored 'cyan (each-in-list args)))
-(define (as-yellow . args) (colored 'yellow (each-in-list args)))
-(define (as-magenta . args) (colored 'magenta (each-in-list args)))
-(define (as-white . args) (colored 'white (each-in-list args)))
-(define (as-black . args) (colored 'black (each-in-list args)))
-(define (as-bold . args) (colored 'bold (each-in-list args)))
-(define (as-italic . args) (colored 'italic (each-in-list args)))
-(define (as-underline . args) (colored 'underline (each-in-list args)))
-
-(define (on-red . args) (colored 'on-red (each-in-list args)))
-(define (on-blue . args) (colored 'on-blue (each-in-list args)))
-(define (on-green . args) (colored 'on-green (each-in-list args)))
-(define (on-cyan . args) (colored 'on-cyan (each-in-list args)))
-(define (on-yellow . args) (colored 'on-yellow (each-in-list args)))
-(define (on-magenta . args) (colored 'on-magenta (each-in-list args)))
-(define (on-white . args) (colored 'on-white (each-in-list args)))
-(define (on-black . args) (colored 'on-black (each-in-list args)))
+(define color (make-state-variable 'color 'default-fg #f))
+(define background (make-state-variable 'background 'default-bg #f))
+(define bold (make-state-variable 'bold 'bold-off #f))
+(define italic (make-state-variable 'bold 'italic-off #f))
+(define underline (make-state-variable 'bold 'underline-off #f))
+
+(define (with-attr var new-attr . args)
+  (fn ((orig-attr var))
+      (with ((var new-attr))
+            (each (ansi-escape new-attr)
+                  (each-in-list args)
+                  (ansi-escape orig-attr)))))
+
+(define (as-bold . args) (with-attr bold 'bold (each-in-list args)))
+(define (as-italic . args) (with-attr italic 'italic (each-in-list args)))
+(define (as-underline . args) (with-attr underline 'underline (each-in-list args)))
+
+(define (as-red . args) (with-attr color 'red (each-in-list args)))
+(define (as-blue . args) (with-attr color 'blue (each-in-list args)))
+(define (as-green . args) (with-attr color 'green (each-in-list args)))
+(define (as-cyan . args) (with-attr color 'cyan (each-in-list args)))
+(define (as-yellow . args) (with-attr color 'yellow (each-in-list args)))
+(define (as-magenta . args) (with-attr color 'magenta (each-in-list args)))
+(define (as-white . args) (with-attr color 'white (each-in-list args)))
+(define (as-black . args) (with-attr color 'black (each-in-list args)))
+
+(define (on-red . args) (with-attr background 'on-red (each-in-list args)))
+(define (on-blue . args) (with-attr background 'on-blue (each-in-list args)))
+(define (on-green . args) (with-attr background 'on-green (each-in-list args)))
+(define (on-cyan . args) (with-attr background 'on-cyan (each-in-list args)))
+(define (on-yellow . args) (with-attr background 'on-yellow (each-in-list args)))
+(define (on-magenta . args) (with-attr background 'on-magenta (each-in-list args)))
+(define (on-white . args) (with-attr background 'on-white (each-in-list args)))
+(define (on-black . args) (with-attr background 'on-black (each-in-list args)))
 
 (define (rgb-escape red-level green-level blue-level bg?)
   (when (not (and (exact-integer? red-level) (<= 0 red-level 5)))
@@ -92,13 +100,13 @@
    "m"))
 
 (define (as-color red green blue . fmt)
-  (colored (rgb-escape red green blue #f) (each-in-list fmt)))
+  (with-attr color (rgb-escape red green blue #f) (each-in-list fmt)))
 
 (define (as-true-color red green blue . fmt)
-  (colored (rgb24-escape red green blue #f) (each-in-list fmt)))
+  (with-attr color (rgb24-escape red green blue #f) (each-in-list fmt)))
 
 (define (on-color red green blue . fmt)
-  (colored (rgb-escape red green blue #t) (each-in-list fmt)))
+  (with-attr background (rgb-escape red green blue #t) (each-in-list fmt)))
 
 (define (on-true-color red green blue . fmt)
-  (colored (rgb24-escape red green blue #t) (each-in-list fmt)))
+  (with-attr background (rgb24-escape red green blue #t) (each-in-list fmt)))
--- chibi-scheme-0.9.1.orig/lib/srfi/166/color.sld
+++ chibi-scheme-0.9.1/lib/srfi/166/color.sld
@@ -1,6 +1,6 @@
 
 (define-library (srfi 166 color)
-  (import (scheme base) (srfi 130) (srfi 165) (srfi 166 base))
+  (import (scheme base) (srfi 130) (srfi 166 base))
   (export
    ;; foreground
    as-red as-blue as-green as-cyan as-yellow
@@ -12,7 +12,4 @@
    on-magenta on-white on-black
    on-color on-true-color
    )
-  (begin
-    (define color
-      (make-computation-environment-variable 'color #f #f)))
   (include "color.scm"))
--- chibi-scheme-0.9.1.orig/lib/srfi/166/test.sld
+++ chibi-scheme-0.9.1/lib/srfi/166/test.sld
@@ -749,11 +749,15 @@ def | 6
                              (each "123\n45\n6\n")))))
 
       ;; color
-      (test "\x1B;[31mred\x1B;[0m" (show #f (as-red "red")))
-      (test "\x1B;[31mred\x1B;[34mblue\x1B;[31mred\x1B;[0m"
+      (test "\x1B;[31mred\x1B;[39m" (show #f (as-red "red")))
+      (test "\x1B;[31mred\x1B;[34mblue\x1B;[31mred\x1B;[39m"
           (show #f (as-red "red" (as-blue "blue") "red")))
-      (test "\x1b;[31m1234567\x1b;[0m col: 7"
+      (test "\x1b;[31m1234567\x1b;[39m col: 7"
             (show #f (terminal-aware (as-red "1234567") (fn (col) (each " col: " col)))))
+      (test "\x1b;[31m\x1b;[4m\x1b;[1mabc\x1b;[22mdef\x1b;[24mghi\x1b;[39m"
+            (show #f (as-red (each (as-underline (as-bold "abc") "def") "ghi"))))
+      (test "\x1b;[44m\x1b;[33mabc\x1b;[39mdef\x1b;[49m"
+            (show #f (on-blue (each (as-yellow "abc") "def"))))
 
       ;; unicode
       (test "〜日本語〜"
@@ -768,7 +772,7 @@ def | 6
           (show #f (trimmed/right 2 "日本語")))
       (test "日"
           (show #f (terminal-aware (trimmed/right 2 "日本語"))))
-      (test "\x1B;[31m日\x1B;[46m\x1B;[31m\x1B;[0m"
+      (test "\x1B;[31m日\x1B;[46m\x1B;[49m\x1B;[39m"
           (show #f (terminal-aware
                     (trimmed/right 2 (as-red "日本語" (on-cyan "!!!!"))))))
       (test "日本語"
--- chibi-scheme-0.9.1.orig/lib/srfi/2.sld
+++ chibi-scheme-0.9.1/lib/srfi/2.sld
@@ -5,8 +5,10 @@
   (begin
    (define-syntax and-let*
      (syntax-rules ()
+       ((and-let* ())
+        #t)
        ((and-let* () . body)
-        (begin #t . body))
+        (let () . body))
        ((and-let* ((var expr)))
         expr)
        ((and-let* ((expr)))
--- chibi-scheme-0.9.1.orig/lib/srfi/2/test.sld
+++ chibi-scheme-0.9.1/lib/srfi/2/test.sld
@@ -42,4 +42,6 @@
           (let ((x #f)) (and-let* (x (y (- x 1)) ((positive? y))) (/ x y))))
       (test 3/2
           (let ((x 3)) (and-let* (x (y (- x 1)) ((positive? y))) (/ x y))))
+      (test 5 (and-let* () (define x 5) x))
+      (test 6 (and-let* ((x 6)) (define y x) y))
       (test-end))))
--- chibi-scheme-0.9.1.orig/sexp.c
+++ chibi-scheme-0.9.1/sexp.c
@@ -440,7 +440,7 @@ sexp sexp_lookup_type_op(sexp ctx, sexp
       if (sexp_stringp(id)
           && !(sexp_stringp(sexp_type_id(res))
                && strcmp(sexp_string_data(id), sexp_string_data(sexp_type_id(res))) == 0))
-        return SEXP_FALSE;
+        continue;
       return res;
     }
   return SEXP_FALSE;
@@ -549,6 +549,7 @@ void sexp_init_context_globals (sexp ctx
   sexp_global(ctx, SEXP_G_OOM_ERROR) = sexp_user_exception(ctx, SEXP_FALSE, "out of memory", SEXP_NULL);
   sexp_global(ctx, SEXP_G_OOS_ERROR) = sexp_user_exception(ctx, SEXP_FALSE, "out of stack space", SEXP_NULL);
   sexp_global(ctx, SEXP_G_ABI_ERROR) = sexp_user_exception(ctx, SEXP_FALSE, "incompatible ABI", SEXP_NULL);
+  sexp_global(ctx, SEXP_G_INTERRUPT_ERROR) = sexp_user_exception(ctx, SEXP_FALSE, "interrupt", SEXP_NULL);
   sexp_global(ctx, SEXP_G_QUOTE_SYMBOL) = sexp_intern(ctx, "quote", -1);
   sexp_global(ctx, SEXP_G_QUASIQUOTE_SYMBOL) = sexp_intern(ctx, "quasiquote", -1);
   sexp_global(ctx, SEXP_G_UNQUOTE_SYMBOL) = sexp_intern(ctx, "unquote", -1);
@@ -1805,6 +1806,8 @@ static sexp* sexp_fileno_cell(sexp ctx,
   if (!sexp_vectorp(vec))
     return NULL;
   len = sexp_vector_length(vec);
+  if (len == 0)
+    return NULL;
   data = sexp_vector_data(vec);
   for (i = 0, cell = (fd * FNV_PRIME) % len; i < len; i++, cell=(cell+1)%len)
     if (!sexp_ephemeronp(data[cell])
@@ -1905,8 +1908,10 @@ sexp sexp_make_input_port (sexp ctx, FIL
   /* here to avoid gc timing issues */
   if (in && fileno(in) >= 0) {
     sexp_port_fd(p) = sexp_lookup_fileno(ctx, fileno(in));
-    if (sexp_filenop(sexp_port_fd(p)))
+    if (sexp_filenop(sexp_port_fd(p))) {
       sexp_fileno_openp(sexp_port_fd(p)) = 1;
+      ++sexp_fileno_count(sexp_port_fd(p));
+    }
   }
 #endif
   sexp_port_cookie(p) = SEXP_VOID;
@@ -2737,6 +2742,10 @@ sexp sexp_read_float_tail (sexp ctx, sex
     if (c=='i' || c=='I' || c=='+' || c=='-') {
       sexp_push_char(ctx, c, in);
       res = sexp_read_complex_tail(ctx, in, res);
+#if SEXP_USE_MATH
+    } else if (c=='@') {
+      return sexp_read_polar_tail(ctx, in, res);
+#endif
     } else
 #endif
     if ((c!=EOF) && ! sexp_is_separator(c))
@@ -2792,10 +2801,13 @@ sexp sexp_ratio_normalize (sexp ctx, sex
 
 sexp sexp_read_number (sexp ctx, sexp in, int base, int exactp) {
   sexp_sint_t val = 0, tmp = -1;
-  int c, digit, negativep = 0;
+  int c, digit, negativep = 0, inexactp = 0;
 #if SEXP_USE_PLACEHOLDER_DIGITS
   double whole = 0.0, scale = 0.1;
 #endif
+#if SEXP_USE_COMPLEX && SEXP_USE_MATH
+  double rho, theta;
+#endif
   sexp_gc_var2(res, den);
 
   c = sexp_read_char(ctx, in);
@@ -2803,7 +2815,7 @@ sexp sexp_read_number (sexp ctx, sexp in
     switch ((c = sexp_tolower(sexp_read_char(ctx, in)))) {
       case 'b': base = 2; break;   case 'o': base = 8; break;
       case 'd': base = 10; break;  case 'x': base = 16; break;
-      case 'i': exactp = 0; break; case 'e': exactp = 1; break;
+      case 'i': inexactp = 1; break; case 'e': exactp = 1; break;
       default: return sexp_read_error(ctx, "unexpected numeric # code", sexp_make_character(c), in);
     }
     c = sexp_read_char(ctx, in);
@@ -2898,6 +2910,18 @@ sexp sexp_read_number (sexp ctx, sexp in
         res = sexp_make_ratio(ctx, res, sexp_complex_imag(den));
         res = sexp_ratio_normalize(ctx, res, in);
         sexp_complex_imag(den) = res;
+#if SEXP_USE_MATH
+      } else if (sexp_flonump(sexp_complex_real(den))) { /* assume polar */
+        rho = sqrt(sexp_flonum_value(sexp_complex_real(den)) *
+                   sexp_flonum_value(sexp_complex_real(den)) +
+                   sexp_to_double(ctx, sexp_complex_imag(den)) +
+                   sexp_to_double(ctx, sexp_complex_imag(den)));
+        theta = atan(sexp_to_double(ctx, sexp_complex_imag(den)) /
+                     sexp_flonum_value(sexp_complex_real(den)));
+        rho = sexp_to_double(ctx, sexp_div(ctx, res, sexp_make_fixnum((sexp_sint_t)round(rho))));
+        sexp_complex_real(den) = sexp_make_flonum(ctx, rho * cos(theta));
+        sexp_complex_imag(den) = sexp_make_flonum(ctx, rho * sin(theta));
+#endif
       } else {
         res = sexp_make_ratio(ctx, res, sexp_complex_real(den));
         res = sexp_ratio_normalize(ctx, res, in);
@@ -2917,6 +2941,8 @@ sexp sexp_read_number (sexp ctx, sexp in
                              / (double)sexp_unbox_fixnum(den));
 #endif
     }
+    if (inexactp)
+      res = sexp_exact_to_inexact(ctx, NULL, 2, res);
     sexp_gc_release2(ctx);
     return res;
 #if SEXP_USE_COMPLEX
@@ -2939,7 +2965,8 @@ sexp sexp_read_number (sexp ctx, sexp in
     sexp_push_char(ctx, c, in);
   }
 
-  return sexp_make_fixnum(negativep ? -val : val);
+  return inexactp ? sexp_make_flonum(ctx, negativep ? -val : val)
+    : sexp_make_fixnum(negativep ? -val : val);
 }
 
 #if SEXP_USE_UTF8_STRINGS
--- chibi-scheme-0.9.1.orig/tests/r7rs-tests.scm
+++ chibi-scheme-0.9.1/tests/r7rs-tests.scm
@@ -2398,6 +2398,9 @@
 ;; Combination of prefixes
 (test-numeric-syntax "#e#x10" 16 "16")
 (test-numeric-syntax "#i#x10" 16.0 "16.0" "16.")
+(test-numeric-syntax "#x#i10" 16.0 "16.0" "16.")
+(test-numeric-syntax "#i#x1/10" 0.0625 "0.0625")
+(test-numeric-syntax "#x#i1/10" 0.0625 "0.0625")
 ;; (Attempted) decimal notation with base prefixes
 (test-numeric-syntax "#d1." 1.0 "1.0" "1.")
 (test-numeric-syntax "#d.1" 0.1 "0.1" ".1" "100.0e-3")
--- chibi-scheme-0.9.1.orig/tools/chibi-doc
+++ chibi-scheme-0.9.1/tools/chibi-doc
@@ -28,7 +28,7 @@
        (string-split str #\.)))
 
 ;; main
-(define (run args render)
+(define (run args render unexpanded?)
   (case (length args)
     ((0)
      (convert-scribble render (current-input-port)))
@@ -43,7 +43,7 @@
         (else
          ;; load the module so that examples work
          (let ((mod-name (split-module-name name)))
-           (print-module-docs mod-name (current-output-port) render))))))
+           (print-module-docs mod-name (current-output-port) render unexpanded?))))))
     ((2)
      (let* ((name (car args))
             (var (cadr args))
@@ -55,16 +55,18 @@
 
 ;; parse the command-line
 (let lp ((args (cdr (command-line)))
-         (render sxml-display-as-text))
+         (render sxml-display-as-text)
+         (unexpanded? #f))
   (cond
    ((and (pair? args) (not (equal? "" (car args)))
          (eqv? #\- (string-ref (car args) 0)))
     (case (string->symbol (substring (car args) 1))
-      ((h -html) (lp (cdr args) sxml-display-as-html))
-      ((s -sxml) (lp (cdr args) write))
-      ((t -text) (lp (cdr args) sxml-display-as-text))
+      ((h -html) (lp (cdr args) sxml-display-as-html #f))
+      ((s -sxml) (lp (cdr args) write #f))
+      ((r -raw)  (lp (cdr args) write #t))
+      ((t -text) (lp (cdr args) sxml-display-as-text #f))
       ((-) (run (cdr args) render))
       (else (die "unknown option: " (car args)))))
    (else
-    (run args render)))
+    (run args render unexpanded?)))
   (newline))
--- chibi-scheme-0.9.1.orig/vm.c
+++ chibi-scheme-0.9.1/vm.c
@@ -1031,6 +1031,12 @@ sexp sexp_apply (sexp ctx, sexp proc, se
  loop:
 #if SEXP_USE_GREEN_THREADS
   if (--fuel <= 0) {
+    if (sexp_context_interruptp(ctx)) {
+      fuel = sexp_context_refuel(ctx);
+      sexp_context_interruptp(ctx) = 0;
+      _ARG1 = sexp_global(ctx, SEXP_G_INTERRUPT_ERROR);
+      goto call_error_handler;
+    }
     tmp1 = sexp_global(ctx, SEXP_G_THREADS_SCHEDULER);
     if (sexp_applicablep(tmp1) && sexp_not(sexp_global(ctx, SEXP_G_ATOMIC_P))) {
       /* save thread */
