shithub: femtolisp

Download patch

ref: 7965ff00950c33760a8153e29173ac1b82b6009f
parent: 008d2886ab8f7bd5138019ec48b75bbaf88fc769
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Nov 25 14:21:59 EST 2024

incorporate closure representation changes from Julia's flisp

This is most of f21780ccb0ef3625f6056902894b723a12477e62 and
d323f404c99aa543d2938a59f7caebd6deec81c4 with some stuff unchanged
and a couple extras. Original commits by Jeff Bezanson.

--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -5,6 +5,6 @@
 test -x $F || { echo no $F found; exit 1; }
 $F gen.lsp && \
 cp flisp.boot flisp.boot.bak && \
-$F mkboot0.lsp system.lsp compiler.lsp > flisp.boot && \
+$F mkboot0.lsp builtins.lsp instructions.lsp system.lsp compiler.lsp > flisp.boot && \
 $F mkboot1.lsp && \
 ninja -C build || { cp flisp.boot.bak flisp.boot; exit 1; }
--- a/compiler.lsp
+++ b/compiler.lsp
@@ -2,11 +2,11 @@
 
 ;; code generation state, constant tables, bytecode encoding
 
-(define (make-code-emitter) (vector () (table) 0 +inf.0))
+(define (make-code-emitter) (vector () (table) 0 ()))
 (define (bcode:code   b) (aref b 0))
 (define (bcode:ctable b) (aref b 1))
 (define (bcode:nconst b) (aref b 2))
-(define (bcode:cdepth b d) (aset! b 3 (min (aref b 3) d)))
+(define (bcode:cenv   b) (aref b 3))
 
 ;; get an index for a referenced value in a bytecode object
 (define (bcode:indexfor b v)
@@ -29,15 +29,13 @@
             (set! args (list (bcode:indexfor e (car args)))))
         (let ((longform
                (assq inst '((loadv loadv.l) (loadg loadg.l) (setg setg.l)
-                            (loada loada.l) (seta  seta.l)))))
+                            (loada loada.l) (seta  seta.l)  (box  box.l)))))
           (if (and longform
                    (> (car args) 255))
               (set! inst (cadr longform))))
         (let ((longform
-               (assq inst '((loadc loadc.l) (setc setc.l)))))
-          (if (and longform
-                   (or (> (car  args) 255)
-                       (> (cadr args) 255)))
+               (assq inst '((loadc loadc.l)))))
+          (if (and longform (> (car  args) 255))
               (set! inst (cadr longform))))
         (if (eq? inst 'loada)
             (cond ((equal? args '(0))
@@ -47,11 +45,11 @@
                    (set! inst 'loada1)
                    (set! args ()))))
         (if (eq? inst 'loadc)
-            (cond ((equal? args '(0 0))
-                   (set! inst 'loadc00)
+            (cond ((equal? args '(0))
+                   (set! inst 'loadc0)
                    (set! args ()))
-                  ((equal? args '(0 1))
-                   (set! inst 'loadc01)
+                  ((equal? args '(1))
+                   (set! inst 'loadc1)
                    (set! args ()))))
 
         (let ((lasti (if (pair? (aref e 0))
@@ -128,17 +126,11 @@
                       ((number? nxt)
                        (case vi
                          ((loadv.l loadg.l setg.l loada.l seta.l
-                           largc lvargc call.l tcall.l)
+                           largc lvargc call.l tcall.l loadc.l box.l)
                           (io-write bcode (int32 nxt))
                           (set! i (+ i 1)))
 
-                         ((loadc setc)  ; 2 uint8 args
-                          (io-write bcode (uint8 nxt))
-                          (set! i (+ i 1))
-                          (io-write bcode (uint8 (aref v i)))
-                          (set! i (+ i 1)))
-
-                         ((loadc.l setc.l optargs keyargs)  ; 2 int32 args
+                         ((optargs keyargs)  ; 2 int32 args
                           (io-write bcode (int32 nxt))
                           (set! i (+ i 1))
                           (io-write bcode (int32 (aref v i)))
@@ -170,8 +162,20 @@
 
 ;; variables
 
+(define (vinfo sym heap? index) (list sym heap? index))
+(define vinfo:sym car)
+(define vinfo:heap? cadr)
+(define vinfo:index caddr)
+
 (define (quoted? e) (eq? (car e) 'quote))
 
+(define (capture-var! g sym)
+  (let ((ce (bcode:cenv g)))
+    (let ((n (index-of sym ce 0)))
+      (or n
+          (prog1 (length ce)
+                 (aset! g 3 (nconc ce (list sym))))))))
+
 (define (index-of item lst start)
   (cond ((null? lst) #f)
         ((eq? item (car lst)) start)
@@ -179,41 +183,60 @@
 
 (define (in-env? s env)
   (and (pair? env)
-       (or (memq s (car env))
+       (or (assq s (car env))
            (in-env? s (cdr env)))))
 
-(define (lookup-sym s env lev arg?)
+(define (lookup-sym s env lev)
   (if (null? env)
-      '(global)
+      'global
       (let* ((curr (car env))
-             (i    (index-of s curr 0)))
-        (if i
-            (if arg?
-                i
-                (cons lev i))
+             (vi   (assq s curr)))
+        (if vi
+            (cons lev vi)
             (lookup-sym s
                         (cdr env)
-                        (if (or arg? (null? curr)) lev (+ lev 1))
-                        #f)))))
+                        (+ lev 1))))))
 
-; number of non-nulls
-(define (nnn e) (count (λ (x) (not (null? x))) e))
-
 (define (printable? x) (not (or (iostream? x)
                                 (eof-object? x))))
 
-(define (compile-sym g env s Is)
-  (let ((loc (lookup-sym s env 0 #t)))
-    (cond ((number? loc)       (emit g (aref Is 0) loc))
-          ((number? (car loc)) (emit g (aref Is 1) (car loc) (cdr loc))
-                               ; update index of most distant captured frame
-                               (bcode:cdepth g (- (nnn (cdr env)) 1 (car loc))))
-          (else
+(define (compile-sym g env s deref)
+  (let ((loc (lookup-sym s env 0)))
+    (cond ((eq? loc 'global)
            (if (and (constant? s)
                     (printable? (top-level-value s)))
                (emit g 'loadv (top-level-value s))
-               (emit g (aref Is 2) s))))))
+               (emit g 'loadg s)))
 
+          ((= (car loc) 0)
+           (emit g 'loada (vinfo:index (cdr loc)))
+           (if (and deref (vinfo:heap? (cdr loc)))
+               (emit g 'car)))
+
+          (else
+           (emit g 'loadc (capture-var! g s))
+           (if (and deref (vinfo:heap? (cdr loc)))
+               (emit g 'car))))))
+
+(define (compile-set! g env s rhs)
+  (let ((loc (lookup-sym s env 0)))
+    (if (eq? loc 'global)
+        (begin (compile-in g env #f rhs)
+               (emit g 'setg s))
+        (let ((arg?   (= (car loc) 0)))
+          (let ((h?   (vinfo:heap? (cdr loc)))
+                (idx  (if arg?
+                          (vinfo:index (cdr loc))
+                          (capture-var! g s))))
+            (if h?
+                (begin (emit g (if arg? 'loada 'loadc) idx)
+                       (compile-in g env #f rhs)
+                       (emit g 'set-car!))
+
+                (begin (compile-in g env #f rhs)
+                       (if (not arg?) (error (string "internal error: misallocated var " s)))
+                       (emit g 'seta idx))))))))
+
 ;; control flow
 
 (define (compile-if g env tail? x)
@@ -396,7 +419,7 @@
 (define (fits-i8 x) (and (fixnum? x) (>= x -128) (<= x 127)))
 
 (define (compile-in g env tail? x)
-  (cond ((symbol? x) (compile-sym g env x #(loada loadc loadg)))
+  (cond ((symbol? x) (compile-sym g env x #t))
         ((atom? x)
          (cond ((eq? x 0)   (emit g 'load0))
                ((eq? x 1)   (emit g 'load1))
@@ -417,11 +440,14 @@
            (if       (compile-if g env tail? x))
            (begin    (compile-begin g env tail? (cdr x)))
            (prog1    (compile-prog1 g env x))
-           (λ        (receive (the-f dept) (compile-f- env x)
+           (λ        (receive (the-f cenv) (compile-f- env x)
                        (begin (emit g 'loadv the-f)
-                              (bcode:cdepth g dept)
-                              (if (< dept (nnn env))
-                                  (emit g 'closure)))))
+                              (if (not (null? cenv))
+                                  (begin
+                                    (for-each (lambda (var)
+                                                (compile-sym g env var #f))
+                                              cenv)
+                                    (emit g 'closure (length cenv)))))))
            (and      (compile-and g env tail? (cdr x)))
            (or       (compile-or  g env tail? (cdr x)))
            (while    (compile-while g env (cadr x) (cons 'begin (cddr x))))
@@ -430,8 +456,7 @@
                      (emit g 'ret))
            (set!     (unless (symbol? (cadr x))
                              (error "set!: second argument must be a symbol"))
-                     (compile-in g env #f (caddr x))
-                     (compile-sym g env (cadr x) #(seta setc setg)))
+                     (compile-set! g env (cadr x) (caddr x)))
            (trycatch (compile-in g env #f `(λ () ,(cadr x)))
                      (unless (1arg-lambda? (caddr x))
                              (error "trycatch: second form must be a 1-argument lambda"))
@@ -485,7 +510,7 @@
       (let ((nxt (make-label g)))
         (emit g 'brbound i)
         (emit g 'brt nxt)
-        (compile-in g (cons (list-head vars i) env) #f (cadar opta))
+        (compile-in g (extend-env env (list-head vars i) '()) #f (cadar opta))
         (emit g 'seta i)
         (emit g 'pop)
         (mark-label g nxt)
@@ -547,6 +572,52 @@
         (else
          (map lower-define e))))
 
+;; closure analysis
+
+(define (lambda:body e) (caddr e))
+(define (lambda:vars e) (lambda-vars (cadr e)))
+
+(define (diff s1 s2)
+  (cond ((null? s1)         '())
+        ((memq (car s1) s2) (diff (cdr s1) s2))
+        (else               (cons (car s1) (diff (cdr s1) s2)))))
+
+;; bindings that are both captured and set!'d
+(define (complex-bindings- e vars head nested capt setd)
+  (cond ((null? vars) #f)
+        ((symbol? e)
+         (if (and nested (memq e vars))
+             (put! capt e #t)))
+        ((or (atom? e) (quoted? e)) #f)
+        ((eq? (car e) 'set!)
+         (if (memq (cadr e) vars)
+             (begin (put! setd (cadr e) #t)
+                    (if nested (put! capt (cadr e) #t))))
+         (complex-bindings- (caddr e) vars #f nested capt setd))
+        ((is-lambda? (car e))
+         (complex-bindings- (lambda:body e)
+                            (diff vars (lambda:vars e))
+                            #f
+                            #t #;(or (not head) nested)
+                            capt setd))
+        (else
+         (cons (complex-bindings- (car e) vars #t nested capt setd)
+               (map (lambda (x)
+                      (complex-bindings- x vars #f nested capt setd))
+                    (cdr e))))))
+
+(define (complex-bindings e vars)
+  (let ((capt (table))
+        (setd (table)))
+    (complex-bindings- e vars #f #f capt setd)
+    (filter (λ (x) (has? capt x))
+            (table-keys setd))))
+
+(define (extend-env env vars cb)
+  (cons (map (λ (var i) (vinfo var (not (not (memq var cb))) i))
+             vars (iota (length vars)))
+        env))
+
 ;; main entry points
 
 (define (compile f) (compile-f () (lower-define f)))
@@ -565,10 +636,11 @@
   (let ((g     (make-code-emitter))
         (args  (cadr f))
         (atail (lastcdr (cadr f)))
-        (vars  (lambda-vars (cadr f)))
+        (vars  (lambda:vars f))
         (opta  (filter pair? (cadr f)))
         (last  (lastcdr f)))
-    (let* ((name  (if (null? last) 'λ last))
+    (let* ((cb (complex-bindings (lambda:body f) vars))
+           (name  (if (null? last) 'lambda last))
            (nargs (if (atom? args) 0 (length args)))
            (nreq  (- nargs (length opta)))
            (kwa   (filter keyword-arg? opta)))
@@ -594,13 +666,21 @@
             ((not (null? atail))     (emit g 'vargc nargs))
             ((null? opta)            (emit g 'argc  nargs)))
 
-      ;; compile body and return
-      (compile-in g (cons vars env) #t (caddr f))
-      (emit g 'ret)
-      (values (function (encode-byte-code (bcode:code g))
-                        (const-to-idx-vec g) name)
-              (aref g 3)))))
+      (let ((newenv (extend-env env vars cb)))
+        (let loop ((e (car newenv))
+                   (i 0))
+          (if (pair? e)
+              (begin (if (cadr (car e))
+                         (emit g 'box i))
+                     (loop (cdr e) (+ i 1)))))
 
+        ;; compile body and return
+        (compile-in g newenv #t (lambda:body f))
+        (emit g 'ret)
+        (values (function (encode-byte-code (bcode:code g))
+                          (const-to-idx-vec g) name)
+                (bcode:cenv g))))))
+
 ;; disassembler
 
 (define (ref-int32-LE a i)
@@ -656,25 +736,18 @@
                   (print-val (aref vals (aref code i)))
                   (set! i (+ i 1)))
 
-                 ((loada seta call tcall list + - * / vector
-                   argc vargc loadi8 apply tapply)
+                 ((loada seta loadc call tcall list + - * / vector
+                   argc vargc loadi8 apply tapply closure box)
                   (print-inst inst i 1)
                   (princ (number->string (aref code i)))
                   (set! i (+ i 1)))
 
-                 ((loada.l seta.l largc lvargc call.l tcall.l)
+                 ((loada.l seta.l loadc.l largc lvargc call.l tcall.l box.l)
                   (print-inst inst i 4)
                   (princ (number->string (ref-int32-LE code i)))
                   (set! i (+ i 4)))
 
-                 ((loadc setc)
-                  (print-inst inst i 2)
-                  (princ (number->string (aref code i)) " ")
-                  (set! i (+ i 1))
-                  (princ (number->string (aref code i)))
-                  (set! i (+ i 1)))
-
-                 ((loadc.l setc.l optargs keyargs)
+                 ((optargs keyargs)
                   (print-inst inst i (+ 8 (if (eq? inst 'keyargs) 4 0)))
                   (princ (number->string (ref-int32-LE code i)) " ")
                   (set! i (+ i 4))
--- a/flisp.boot
+++ b/flisp.boot
@@ -1,65 +1,65 @@
-(*builtins* #(0 0 0 0 0 0 0 0 0 0 0 0 #fn("6000n10<:" #())
-	      #fn("6000n10=:" #()) 0 0 0 0 #fn("6000n10B:" #()) 0 0 0 0 #fn("7000n201G:" #())
-	      #fn("6000n10H:" #()) 0 0 0 #fn("7000n201L:" #()) 0 #fn("7000n201N:" #())
-	      0 #fn("7000n201P:" #()) #fn("7000n201Q:" #())
-	      #fn("6000n10R:" #()) #fn("6000n10S:" #())
-	      #fn("6000n10T:" #()) 0 #fn("6000n10V:" #())
-	      #fn("6000n10W:" #()) #fn("6000n10X:" #())
-	      #fn("6000n10Y:" #()) #fn("6000n10Z:" #())
-	      #fn("6000n10[:" #()) #fn("6000n10\\:" #())
-	      #fn("6000n10]:" #()) 0 #fn("7000n201_:" #()) 0 0 0 #fn("7000n201c:" #())
-	      #fn("7000n201d:" #()) #fn("8000|00:" #())
-	      #fn("9000|0200\x7f2:" #(#.apply))
-	      #fn("9000|0200\x7f2:" #(#.+))
-	      #fn("9000|0200\x7f2:" #(#.-))
-	      #fn("9000|0200\x7f2:" #(#.*))
-	      #fn("9000|0200\x7f2:" #(#./))
-	      #fn("9000|0200\x7f2:" #(#.div0))
-	      #fn("7000n201l:" #()) #fn("7000n201m:" #()) 0 #fn("9000|0200\x7f2:" #(#.vector))
-	      #fn("8000n30182p:" #()) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-	      0 0 0 0 0 0 0 0 0 0 0)
+(*builtins* #(0 0 0 0 0 0 0 0 0 0 0 0 #fn("5000n10<:" #())
+	      #fn("5000n10=:" #()) 0 0 0 0 #fn("5000n10B:" #()) 0 0 0 0 #fn("6000n201G:" #())
+	      #fn("5000n10H:" #()) 0 0 0 #fn("6000n201L:" #()) 0 #fn("6000n201N:" #())
+	      0 #fn("6000n201P:" #()) #fn("6000n201Q:" #())
+	      #fn("5000n10R:" #()) #fn("5000n10S:" #())
+	      #fn("5000n10T:" #()) 0 #fn("5000n10V:" #())
+	      #fn("5000n10W:" #()) #fn("5000n10X:" #())
+	      #fn("5000n10Y:" #()) #fn("5000n10Z:" #())
+	      #fn("5000n10[:" #()) #fn("5000n10\\:" #())
+	      #fn("5000n10]:" #()) 0 #fn("6000n201_:" #()) 0 0 0 #fn("6000n201c:" #())
+	      #fn("6000n201d:" #()) #fn("7000|00:" #())
+	      #fn("8000|0200\x7f2:" #(#.apply))
+	      #fn("8000|0200\x7f2:" #(#.+))
+	      #fn("8000|0200\x7f2:" #(#.-))
+	      #fn("8000|0200\x7f2:" #(#.*))
+	      #fn("8000|0200\x7f2:" #(#./))
+	      #fn("8000|0200\x7f2:" #(#.div0))
+	      #fn("6000n201l:" #()) #fn("6000n201m:" #()) 0 #fn("8000|0200\x7f2:" #(#.vector))
+	      #fn("7000n30182p:" #()) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+	      0 0 0 0 0 0 0 0 0 0 0 0 0)
 	    *interactive* #f *syntax-environment*
-	    #table(with-input-from #fn("=000|12021e1220e2e1e12315163:" #(#fn(nconc)
-  with-bindings *input-stream* #fn(copy-list)))  unless #fn("=000|1200O211Pe4:" #(if
-  begin))  time #fn("7000n120>215061:" #(#fn(">000n120021e1e2e122A23242521e10e326e4e3e3:" #(let
+	    #table(with-input-from #fn("<000|12021e1220e2e1e12315163:" #(#fn(nconc)
+  with-bindings *input-stream* #fn(copy-list)))  unless #fn("<000|1200O211Pe4:" #(if
+  begin))  time #fn("6000n1200>1215061:" #(#fn("=000n120021e1e2e122A23242521e10e326e4e3e3:" #(let
   time-now prog1 princ "Elapsed time: " - " seconds\n"))
-					 #fn(gensym)))  cond #fn("9000|020>D61:" #(#fn("7000n120>?040A61:" #(#fn("7000n10H340O:20>0<61:" #(#fn(":000n10<20Q;I7040<DQ3@00=J500<:210=P:0=J@0220<910A=51e3:0T23CW07475051513A026>77750515161:28>295061:2:0<210=P910A=51e4:" #(else
-  begin or => 1arg-lambda? caddr #fn("=000n1200A<e2e1210227374A5151P920910=51e4e3:" #(let
-  if begin cddr caddr)) caadr #fn("<000n1200A<e2e121072A510e2920910=51e4e3:" #(let
-  if caddr)) #fn(gensym) if))) cond-clauses->if)))))  do #fn("A000|220>21501<22230522224052222505265:" #(#fn("B000n520021822212324e125F=51522324e12590251230e18452e153e4e3e2e1230e18352e3:" #(letrec
+					   #fn(gensym)))  cond #fn("8000|0200>1D61:" #(#fn("7000n1\x8c00200>1_40<A61:" #(#fn("7000n10H340O:20A0>20<61:" #(#fn("9000n10<20Q;I7040<DQ3@00=J500<:210=P:0=J?0220<A<F=51e3:0T23C_07475051513E0260AF>377750515161:280AF>3295061:2:0<210=PA<F=51e4:" #(else
+  begin or => 1arg-lambda? caddr #fn("<000n1200A<e2e1210227374A5151PF<92=51e4e3:" #(let
+  if begin cddr caddr)) caadr #fn(";000n1200A<e2e121072A510e2F<92=51e4e3:" #(let
+  if caddr)) #fn(gensym) if))) cond-clauses->if)))))  do #fn("@000|220182>221501<22230522224052222505265:" #(#fn("A000n520021822212324e125A=51522324e125F51230e18452e153e4e3e2e1230e18352e3:" #(letrec
   λ if #fn(nconc) begin #fn(copy-list))) #fn(gensym)
-  #fn(map) #.car #.cadr #fn("7000n170051B38071061:0<:" #(cddr caddr))))  with-bindings #fn(">000|120>21220522123052212405263:" #(#fn("B000n32021e1222382053e1242225015351262027e124F51522027e1242228082535152e3e164:" #(#fn(nconc)
-  let #fn(map) #.list #fn(copy-list) #fn("8000n22001e3:" #(set!))
-  unwind-protect begin #fn("8000n22001e3:" #(set!))))
-  #fn(map) #.car #.cadr #fn("6000n12060:" #(#fn(gensym)))))  let #fn(":000|120>O61:" #(#fn("<000n1AR3D0A?04F<z004F=z01@30D420>2122e12324A52e125F51532326A5262:" #(#fn("8000n2A3@020A0e2e1Ae3@3001P:" #(letrec))
-  #fn(nconc) λ #fn(map) #fn("6000n10B3500<:0:" #())
-  #fn(copy-list) #fn("6000n10B3500T:7060:" #(void))))))  define-macro #fn("?000|120210<e22223e10=e12415153e3:" #(set-syntax!
-  quote #fn(nconc) λ #fn(copy-list)))  quasiquote #fn("8000n1700E62:" #(bq-process))  when #fn("<000|1200211POe4:" #(if
-  begin))  with-output-to #fn("=000|12021e1220e2e1e12315163:" #(#fn(nconc)
+  #fn(map) #.car #.cadr #fn("6000n170051B38071061:0<:" #(cddr caddr))))  with-bindings #fn("=000|1201>121220522123052212405263:" #(#fn("A000n32021e1222382053e1242225015351262027e124A51522027e1242228082535152e3e164:" #(#fn(nconc)
+  let #fn(map) #.list #fn(copy-list) #fn("7000n22001e3:" #(set!))
+  unwind-protect begin #fn("7000n22001e3:" #(set!))))
+  #fn(map) #.car #.cadr #fn("5000n12060:" #(#fn(gensym)))))  let #fn(":000|1\x8c0\x8c12001>2O61:" #(#fn(";000n1\x8c0A<R3E00A<_4AF<<_4FF<=_@30D4200>12122e12324A<52e125F<51532326A<5262:" #(#fn("7000n2A<3B020A<0e2e1A<e3@3001P:" #(letrec))
+  #fn(nconc) λ #fn(map) #fn("5000n10B3500<:0:" #())
+  #fn(copy-list) #fn("5000n10B3500T:7060:" #(void))))))  define-macro #fn(">000|120210<e22223e10=e12415153e3:" #(set-syntax!
+  quote #fn(nconc) λ #fn(copy-list)))  quasiquote #fn("7000n1700E62:" #(bq-process))  when #fn(";000|1200211POe4:" #(if
+  begin))  with-output-to #fn("<000|12021e1220e2e1e12315163:" #(#fn(nconc)
 								with-bindings
 								*output-stream*
-								#fn(copy-list)))  catch #fn("7000n220>215061:" #(#fn("@000n120F210e12223240e225260e22728e2e325290e2Ae3e42:0e22;0e2e4e3e3:" #(trycatch
+								#fn(copy-list)))  catch #fn("7000n22010>2215061:" #(#fn("?000n120A210e12223240e225260e22728e2e325290e2Fe3e42:0e22;0e2e4e3e3:" #(trycatch
   λ if and pair? eq? car quote thrown-value cadr caddr raise))
-  #fn(gensym)))  let* #fn("A000|10H3E02021e1qe12215153e1:2021e173051e1e1220=B3H02024e10=e12215153e1@301515375051e2:" #(#fn(nconc)
-  λ #fn(copy-list) caar let* cadar))  letrec #fn("?000|1202021e12223052e122240522515154e1222605262:" #(#fn(nconc)
-  λ #fn(map) #.car #fn("9000n12021e12205162:" #(#fn(nconc) set! #fn(copy-list)))
-  #fn(copy-list) #fn("6000n17060:" #(void))))  assert #fn("<000n1200D2122230e2e2e2e4:" #(if
-  raise quote assert-failed))  case #fn(":000|120>D61:" #(#fn("7000n120?0421>225061:" #(#fn("9000n2120C5020:1J40O:1R3=021072151e3:1H3=023072151e3:1=J>0230721<51e3:74251523=0260271e2e3:280271e2e3:" #(else
+  #fn(gensym)))  let* #fn("@000|10H3E02021e1qe12215153e1:2021e173051e1e1220=B3H02024e10=e12215153e1@301515375051e2:" #(#fn(nconc)
+  λ #fn(copy-list) caar let* cadar))  letrec #fn(">000|1202021e12223052e122240522515154e1222605262:" #(#fn(nconc)
+  λ #fn(map) #.car #fn("8000n12021e12205162:" #(#fn(nconc) set! #fn(copy-list)))
+  #fn(copy-list) #fn("5000n17060:" #(void))))  assert #fn(";000n1200D2122230e2e2e2e4:" #(if
+  raise quote assert-failed))  case #fn(":000|12001>2D61:" #(#fn("8000n1\x8c0020_421A0F>3225061:" #(#fn("8000n2120C5020:1J40O:1R3=021072151e3:1H3=023072151e3:1=J>0230721<51e3:74251523=0260271e2e3:280271e2e3:" #(else
   eq? quote-value eqv? every #.symbol? memq quote memv) vals->cond)
-  #fn("<000n1200910e2e12122e12324>9115252e3:" #(let #fn(nconc) cond #fn(map)
-						#fn("8000n1910A0<520=P:" #())))
-  #fn(gensym)))))  receive #fn("@000|22021q1e32221e10e123825153e3:" #(call-with-values
-  λ #fn(nconc) #fn(copy-list)))  dotimes #fn(";000|120>0<0T62:" #(#fn("=000n220E211Ke32223e10e1e124F5153e4:" #(for
-  - #fn(nconc) λ #fn(copy-list)))))  unwind-protect #fn("8000n220>2150215062:" #(#fn("@000n220121qFe3e2e12223A210e1241e1250e2e3e3e31e1e3e3:" #(let
-  λ prog1 trycatch begin raise)) #fn(gensym)))  throw #fn(":000n220212223e201e4e2:" #(raise
+  #fn("<000n1200Ae2e12122e12324F0>2925252e3:" #(let #fn(nconc) cond #fn(map)
+						#fn("7000n1A<F0<520=P:" #())))
+  #fn(gensym)))))  receive #fn("?000|22021q1e32221e10e123825153e3:" #(call-with-values
+  λ #fn(nconc) #fn(copy-list)))  dotimes #fn(":000|1201>10<0T62:" #(#fn("<000n220E211Ke32223e10e1e124A5153e4:" #(for
+  - #fn(nconc) λ #fn(copy-list)))))  unwind-protect #fn("7000n22010>22150215062:" #(#fn("?000n220121qAe3e2e12223F210e1241e1250e2e3e3e31e1e3e3:" #(let
+  λ prog1 trycatch begin raise)) #fn(gensym)))  throw #fn("9000n220212223e201e4e2:" #(raise
   list quote thrown-value)))
-	    1+ #fn("7000n10KM:" #() 1+) 1-
-	    #fn("7000n10K\x80:" #() 1-) 1arg-lambda? #fn("8000n10B;3U04700<51;3J040=B;3B040TB;3:04710TK62:" #(is-lambda?
+	    1+ #fn("6000n10KM:" #() 1+) 1-
+	    #fn("6000n10K\x80:" #() 1-) 1arg-lambda? #fn("7000n10B;3U04700<51;3J040=B;3B040TB;3:04710TK62:" #(is-lambda?
   length=) 1arg-lambda?)
-	    <= #fn("7000n210L;IB0470051;380470151S:" #(nan?) <=) >
-	    #fn("7000n210L:" #() >) >= #fn("7000n201L;IB0470051;380470151S:" #(nan?) >=)
-	    Instructions #table(call.l 83  trycatch 77  largc 81  loadg.l 68  cadr 36  argc 62  setg 71  load0 21  vector? 45  fixnum? 41  loada0 0  div0 59  keyargs 91  call 5  loada.l 69  brt.l 50  pair? 18  sub2 80  add2 29  loadc.l 70  loadc 9  builtin? 43  set-car! 47  brt 25  ret 10  loadi8 66  tapply 79  loada1 1  boolean? 39  atom? 24  cdr 13  brne.l 85  / 58  loadf 31  equal? 52  apply 54  dup 11  loadt 20  jmp.l 48  null? 38  not 35  = 60  set-cdr! 30  loadc01 22  eq? 33  * 57  load1 27  dummy_t 93  bound? 42  brf 3  function? 44  setc.l 75  < 28  brnn.l 86  jmp 16  loadv 2  for 78  lvargc 82  dummy_eof 95  + 55  dummy_f 92  setc 74  brne 19  compare 61  neg 37  loadv.l 67  number? 40  vargc 76  brn 87  brbound 90  vector 63  setg.l 72  brf.l 49  aref 23  symbol? 34  aset! 64  car 12  cons 32  tcall.l 84  - 56  brn.l 88  optargs 89  nop 46  closure 14  pop 4  eqv? 51  list 53  seta 15  seta.l 73  brnn 26  loadnil 65  loadg 7  loadc00 17  loada 8  dummy_nil 94  tcall 6)
-	    __init_globals #fn("6000n020w1422w3474w5476w7478w9:" #("/"
+	    <= #fn("6000n210L;IB0470051;380470151S:" #(nan?) <=) >
+	    #fn("6000n210L:" #() >) >= #fn("6000n201L;IB0470051;380470151S:" #(nan?) >=)
+	    Instructions #table(call.l 83  trycatch 77  largc 81  loadg.l 68  box 92  cadr 36  argc 62  setg 71  load0 21  vector? 45  fixnum? 41  loadc0 17  loada0 0  div0 59  keyargs 91  call 5  loada.l 69  brt.l 50  pair? 18  sub2 80  add2 29  loadc.l 70  loadc 9  builtin? 43  set-car! 47  brt 25  ret 10  loadi8 66  tapply 79  loada1 1  boolean? 39  atom? 24  cdr 13  brne.l 85  / 58  loadf 31  equal? 52  apply 54  dup 11  loadt 20  jmp.l 48  null? 38  not 35  = 60  set-cdr! 30  eq? 33  * 57  load1 27  dummy_t 95  bound? 42  brf 3  function? 44  box.l 93  setc.l 75  < 28  brnn.l 86  jmp 16  loadv 2  for 78  lvargc 82  dummy_eof 97  + 55  dummy_f 94  setc 74  brne 19  compare 61  neg 37  loadv.l 67  number? 40  vargc 76  brn 87  brbound 90  vector 63  loadc1 22  setg.l 72  aref 23  brf.l 49  symbol? 34  aset! 64  car 12  cons 32  tcall.l 84  - 56  brn.l 88  optargs 89  nop 46  closure 14  pop 4  eqv? 51  list 53  seta 15  seta.l 73  brnn 26  loadnil 65  loadg 7  loada 8  dummy_nil 96  tcall 6)
+	    __init_globals #fn("5000n020w1422w3474w5476w7478w9:" #("/"
 								   *directory-separator*
 								   "\n"
 								   *linefeed*
@@ -69,267 +69,282 @@
 								   *input-stream*
 								   *stderr*
 								   *error-stream*) __init_globals)
-	    __rcscript #fn("8000n02021725161:" #(#fn("7000n12005138071061:D:" #(#fn(path-exists?)
-  load)) #fn("8000n1020c35021:022c3?0232425512662:232427512862:" #(unknown ""
+	    __rcscript #fn("7000n02021725161:" #(#fn("6000n12005138071061:D:" #(#fn(path-exists?)
+  load)) #fn("7000n1020c35021:022c3?0232425512662:232427512862:" #(unknown ""
 								   plan9 #fn(string)
 								   #fn(os-getenv)
 								   "home" "/lib/flisprc"
 								   "HOME" "/.flisprc"))
 						 *os-name*) __rcscript)
-	    __script #fn("7000n120>21}:" #(#fn("7000n070A61:" #(load))
-					   #fn("7000n170051421K61:" #(top-level-exception-handler
+	    __script #fn("6000n1200>121}:" #(#fn("6000n070A61:" #(load))
+					     #fn("6000n170051421K61:" #(top-level-exception-handler
   #fn(exit)))) __script)
-	    __start #fn("8000n1705040=B3D00=w14Ow24730T51@C00w14Dw24745047550426E61:" #(__init_globals
+	    __start #fn("7000n1705040=B3D00=w14Ow24730T51@C00w14Dw24745047550426E61:" #(__init_globals
   *argv* *interactive* __script __rcscript repl #fn(exit)) __start)
-	    abs #fn("7000n10EL3500U:0:" #() abs) any
-	    #fn("8000n21B;3D0401<51;I:047001=62:" #(any) any) arg-counts #table(bound? 1  function? 1  symbol? 1  aset! 3  car 1  cons 2  < 2  cadr 1  vector? 1  fixnum? 1  boolean? 1  atom? 1  cdr 1  div0 2  equal? 2  eqv? 2  pair? 1  compare 2  null? 1  not 1  number? 1  = 2  set-cdr! 2  eq? 2  builtin? 1  set-car! 2  aref 2)
-	    argc-error #fn("<000n2702102211Kl37023@402465:" #(error "compile error: "
+	    abs #fn("6000n10EL3500U:0:" #() abs) any
+	    #fn("7000n21B;3D0401<51;I:047001=62:" #(any) any) arg-counts #table(bound? 1  function? 1  symbol? 1  aset! 3  car 1  cons 2  < 2  cadr 1  vector? 1  fixnum? 1  boolean? 1  atom? 1  cdr 1  div0 2  equal? 2  eqv? 2  pair? 1  compare 2  null? 1  not 1  number? 1  = 2  set-cdr! 2  eq? 2  builtin? 1  set-car! 2  aref 2)
+	    argc-error #fn(";000n2702102211Kl37023@402465:" #(error "compile error: "
 							      " expects " " argument."
 							      " arguments.") argc-error)
-	    array? #fn("8000n10];I<04202105161:" #(#fn("7000n10B;38040<20Q:" #(array))
+	    array? #fn("7000n10];I<04202105161:" #(#fn("6000n10B;38040<20Q:" #(array))
 						   #fn(typeof)) array?)
-	    assoc #fn("8000n21H340O:701510d3501<:7101=62:" #(caar assoc) assoc)
-	    assv #fn("8000n21H340O:701510c3501<:7101=62:" #(caar assv) assv)
-	    bcode:cdepth #fn(":000n20r3700r3G152p:" #(min) bcode:cdepth)
-	    bcode:code #fn("7000n10EG:" #() bcode:code) bcode:ctable
-	    #fn("7000n10KG:" #() bcode:ctable) bcode:indexfor #fn("9000n220>710517205162:" #(#fn(":000n2200F52390210F62:220F15341Ar21KMp4:" #(#fn(has?)
+	    assoc #fn("7000n21H340O:701510d3501<:7101=62:" #(caar assoc) assoc)
+	    assv #fn("7000n21H340O:701510c3501<:7101=62:" #(caar assv) assv)
+	    bcode:cenv #fn("6000n10r3G:" #() bcode:cenv) bcode:code
+	    #fn("6000n10EG:" #() bcode:code) bcode:ctable #fn("6000n10KG:" #() bcode:ctable)
+	    bcode:indexfor #fn("8000n22010>2710517205162:" #(#fn("9000n2200A52390210A62:220A15341Fr21KMp4:" #(#fn(has?)
   #fn(get) #fn(put!))) bcode:ctable bcode:nconst) bcode:indexfor)
-	    bcode:nconst #fn("7000n10r2G:" #() bcode:nconst) bq-bracket
-	    #fn("<000n20H3=020710152e2:0<22CR01El380200=P:202324710=1K\x8052e3e2:0<25CS01El390260Te2:202027710T1K\x8052e3e2:0<28CO01El3500T:202029710T1K\x8052e3e2:20710152e2:" #(#.list
+	    bcode:nconst #fn("6000n10r2G:" #() bcode:nconst) bq-bracket
+	    #fn(";000n20H3=020710152e2:0<22CR01El380200=P:202324710=1K\x8052e3e2:0<25CS01El390260Te2:202027710T1K\x8052e3e2:0<28CO01El3500T:202029710T1K\x8052e3e2:20710152e2:" #(#.list
   bq-process unquote #.cons 'unquote unquote-splicing copy-list 'unquote-splicing
   unquote-nsplicing 'unquote-nsplicing) bq-bracket)
-	    bq-bracket1 #fn(";000n20B;38040<20Q3K01El3500T:2122730=1K\x8052e3:730162:" #(unquote
+	    bq-bracket1 #fn(":000n20B;38040<20Q3K01El3500T:2122730=1K\x8052e3:730162:" #(unquote
   #.cons 'unquote bq-process) bq-bracket1)
-	    bq-process #fn(";000n20R380200e2:0]3A021727305115261:0H3400:0<24CB02526720T1KM52e3:0<27CW01El;3:04780r2523500T:292:720=1K\x8052e3:7;7<052IE02=>7>0512?2@>05262:2A>D510q62:" #(quote
-  #fn("8000n10<20C80210=P:22210e3:" #(#.list #.vector #.apply)) bq-process
+	    bq-process #fn(":000n20R380200e2:0]3A021727305115261:0H3400:0<24CB02526720T1KM52e3:0<27CW01El;3:04780r2523500T:292:720=1K\x8052e3:7;7<052II02=1>17>0512?2@1>105262:2A1>1D510q62:" #(quote
+  #fn("7000n10<20C80210=P:22210e3:" #(#.list #.vector #.apply)) bq-process
   vector->list quasiquote #.list 'quasiquote unquote length= #.cons 'unquote
-  any splice-form? #fn(":000n20J70201P:1=J?0211<720F52e3:23241P720F52e162:" #(#.list
+  any splice-form? #fn("9000n20J70201P:1=J?0211<720A52e3:23241P720A52e162:" #(#.list
   #.cons bq-process #fn(nconc) #fn(list*))) lastcdr #fn(map)
-  #fn("8000n1700F62:" #(bq-bracket1)) #fn("6000n120>?040:" #(#fn(">000n20J;02071151P:0B3s00<22C[020731911El3700=@E02425e2760=911K\x8052e252P:A0=770<911521P62:2071760911521P51P:" #(nconc
+  #fn("7000n1700A62:" #(bq-bracket1)) #fn("8000n1\x8c0020A0>2_40<:" #(#fn("=000n20J;02071151P:0B3n00<22CW020731AEl3700=@C02425e2760=AK\x8052e252P:F<0=770<A521P62:2071760A521P51P:" #(nconc
   reverse! unquote nreconc #.list 'unquote bq-process bq-bracket))))) bq-process)
-	    builtin->instruction #fn("9000n120A0O63:" #(#fn(get)) #(#table(#.cadr cadr  #.aset! aset!  #.+ +  #.- -  #.equal? equal?  #.eq? eq?  #.builtin? builtin?  #.not not  #.pair? pair?  #.aref aref  #.cdr cdr  #./ /  #.div0 div0  #.set-car! set-car!  #.vector vector  #.set-cdr! set-cdr!  #.< <  #.cons cons  #.apply apply  #.eqv? eqv?  #.vector? vector?  #.list list  #.car car  #.bound? bound?  #.function? function?  #.null? null?  #.symbol? symbol?  #.compare compare  #.boolean? boolean?  #.fixnum? fixnum?  #.atom? atom?  #.= =  #.number? number?  #.* *)
-								    ()))
-	    caaaar #fn("6000n10<<<<:" #() caaaar) caaadr
-	    #fn("6000n10T<<:" #() caaadr) caaar #fn("6000n10<<<:" #() caaar)
-	    caadar #fn("6000n10<T<:" #() caadar) caaddr
-	    #fn("6000n10=T<:" #() caaddr) caadr #fn("6000n10T<:" #() caadr)
-	    caar #fn("6000n10<<:" #() caar) cadaar
-	    #fn("6000n10<<T:" #() cadaar) cadadr #fn("6000n10TT:" #() cadadr)
-	    cadar #fn("6000n10<T:" #() cadar) caddar
-	    #fn("6000n10<=T:" #() caddar) cadddr #fn("6000n10==T:" #() cadddr)
-	    caddr #fn("6000n10=T:" #() caddr) call-with-values
-	    #fn("7000n220>05061:" #(#fn("7000n10B;39049100<Q380F0=\x7f2:F061:" #())) #1=#((*values*)
-  ()))
-	    cdaaar #fn("6000n10<<<=:" #() cdaaar) cdaadr
-	    #fn("6000n10T<=:" #() cdaadr) cdaar #fn("6000n10<<=:" #() cdaar)
-	    cdadar #fn("6000n10<T=:" #() cdadar) cdaddr
-	    #fn("6000n10=T=:" #() cdaddr) cdadr #fn("6000n10T=:" #() cdadr)
-	    cdar #fn("6000n10<=:" #() cdar) cddaar
-	    #fn("6000n10<<==:" #() cddaar) cddadr #fn("6000n10T==:" #() cddadr)
-	    cddar #fn("6000n10<==:" #() cddar) cdddar
-	    #fn("6000n10<===:" #() cdddar) cddddr #fn("6000n10====:" #() cddddr)
-	    cdddr #fn("6000n10===:" #() cdddr) cddr
-	    #fn("6000n10==:" #() cddr) char? #fn("7000n12005121Q:" #(#fn(typeof)
+	    builtin->instruction #fn("8000n120A0O63:" #(#fn(get)) #(#table(#.cadr cadr  #.aset! aset!  #.+ +  #.- -  #.equal? equal?  #.eq? eq?  #.builtin? builtin?  #.not not  #.pair? pair?  #.aref aref  #.cdr cdr  #./ /  #.div0 div0  #.set-car! set-car!  #.vector vector  #.set-cdr! set-cdr!  #.< <  #.cons cons  #.apply apply  #.eqv? eqv?  #.vector? vector?  #.list list  #.car car  #.bound? bound?  #.function? function?  #.null? null?  #.symbol? symbol?  #.compare compare  #.boolean? boolean?  #.fixnum? fixnum?  #.atom? atom?  #.= =  #.number? number?  #.* *)))
+	    caaaar #fn("5000n10<<<<:" #() caaaar) caaadr
+	    #fn("5000n10T<<:" #() caaadr) caaar #fn("5000n10<<<:" #() caaar)
+	    caadar #fn("5000n10<T<:" #() caadar) caaddr
+	    #fn("5000n10=T<:" #() caaddr) caadr #fn("5000n10T<:" #() caadr)
+	    caar #fn("5000n10<<:" #() caar) cadaar
+	    #fn("5000n10<<T:" #() cadaar) cadadr #fn("5000n10TT:" #() cadadr)
+	    cadar #fn("5000n10<T:" #() cadar) caddar
+	    #fn("5000n10<=T:" #() caddar) cadddr #fn("5000n10==T:" #() cadddr)
+	    caddr #2=#fn("5000n10=T:" #() caddr) call-with-values
+	    #fn("7000n220A1>205061:" #(#fn("6000n10B;3704A0<Q380F0=\x7f2:F061:" #())) #(#1=(*values*)))
+	    capture-var! #fn("7000n22001>27105161:" #(#fn("9000n1200AF>371F0E5361:" #(#fn(":000n10;IF0420A51Fr321A92e152p4:" #(#fn(length)
+  #fn(nconc))) index-of)) bcode:cenv) capture-var!)
+	    cdaaar #fn("5000n10<<<=:" #() cdaaar) cdaadr
+	    #fn("5000n10T<=:" #() cdaadr) cdaar #fn("5000n10<<=:" #() cdaar)
+	    cdadar #fn("5000n10<T=:" #() cdadar) cdaddr
+	    #fn("5000n10=T=:" #() cdaddr) cdadr #fn("5000n10T=:" #() cdadr)
+	    cdar #fn("5000n10<=:" #() cdar) cddaar
+	    #fn("5000n10<<==:" #() cddaar) cddadr #fn("5000n10T==:" #() cddadr)
+	    cddar #fn("5000n10<==:" #() cddar) cdddar
+	    #fn("5000n10<===:" #() cdddar) cddddr #fn("5000n10====:" #() cddddr)
+	    cdddr #fn("5000n10===:" #() cdddr) cddr
+	    #fn("5000n10==:" #() cddr) char? #fn("6000n12005121Q:" #(#fn(typeof)
   rune) char?)
-	    closure? #fn("7000n10\\;36040[S:" #() closure?) compile
-	    #fn("9000n170q7105162:" #(compile-f lower-define) compile)
-	    compile-and #fn("<000n470018283D2166:" #(compile-short-circuit brf) compile-and)
-	    compile-app #fn("7000n420>83<61:" #(#fn("9000n120>0R;3V04710F52S;3J040Z;3C0422051;390423051[3:023051@30061:" #(#fn(":000n170913=21523S072910911O054423>74910911913=5361:25>0[;38047605161:" #(length>
-  255 compile-in #fn(":000n17092092237021@4022063:" #(emit tcall.l call.l))
-  compile-arglist #fn(";000n1A20Q;3X0471A92152S;3J0422205123d;3<0474923r2523L075920921O923T544769202062:0IA075920921OA54@30D427>78920921923=5361:" #(cadr
-  in-env? #fn(top-level-value) #.cadr length= compile-in emit #fn("=000n1A3H070930931932933910A067:7193093237022@4023063:" #(compile-builtin-call
+	    closure? #fn("6000n10\\;36040[S:" #() closure?) compile
+	    #fn("8000n170q7105162:" #(compile-f lower-define) compile)
+	    compile-and #fn(";000n470018283D2166:" #(compile-short-circuit brf) compile-and)
+	    compile-app #fn("9000n420830182>483<61:" #(#fn("9000n120AF9293>40R;3W047109252S;3J040Z;3C0422051;390423051[3:023051@30061:" #(#fn(":000n170A=21523O072F92O054423F93>274F92A=5361:25092AF93>50[;38047605161:" #(length>
+  255 compile-in #fn("9000n170AF37021@4022063:" #(emit tcall.l call.l))
+  compile-arglist #fn("<000n1A20Q;3U0471AF52S;3I0422205123d;3;047492r2523G07593FO92T54476932062:0I>07593FOA54@30D427093F9492A>67893F92=5361:" #(cadr
+  in-env? #fn(top-level-value) #.cadr length= compile-in emit #fn("<000n1A3B070F92939495A067:71F9337022@4023063:" #(compile-builtin-call
   emit tcall call)) compile-arglist)) builtin->instruction)) in-env? #fn(constant?)
   #fn(top-level-value)))) compile-app)
-	    compile-arglist #fn("8000n37021>82524228261:" #(for-each #fn(":000n170AFO064:" #(compile-in))
-							    #fn(length)) compile-arglist)
-	    compile-begin #fn(":000n483H3?0700182715064:83=H3>070018283<64:7001O83<5447202352474018283=64:" #(compile-in
+	    compile-arglist #fn("8000n3702101>282524228261:" #(for-each #fn("9000n170AFO064:" #(compile-in))
+							       #fn(length)) compile-arglist)
+	    compile-begin #fn("9000n483H3?0700182715064:83=H3>070018283<64:7001O83<5447202352474018283=64:" #(compile-in
   void emit pop compile-begin) compile-begin)
-	    compile-builtin-call #fn(":000n720>217284O5361:" #(#fn("8000n10;3=0470903=052S3=071905052@30D422>90561:" #(length=
-  argc-error #fn(":000n1020CR0916El3<0719102262:7191091591663:023Ce0916El3<0719102462:916r2l3<0719102562:7191091591663:026Cv0916El3;077915K62:916Kl3<0719102862:916r2l3<0719102962:7191091591663:02:CR0916El3<0719102;62:7191091591663:02<CQ0916El3;077915K62:7191091591663:02=CT0916El3>0719102>2?63:7191091591663:02@C]0916r2L3<077915r262:719109123702A@402@91663:7191091562:" #(list
+	    compile-builtin-call #fn(":000n720838586082>5217284O5361:" #(#fn(":000n10;3;0470A=052S3;071F052@30D4229293F94>4F61:" #(length=
+  argc-error #fn("9000n1020CI0AEl3:071F2262:71F92A63:023CX0AEl3:071F2462:Ar2l3:071F2562:71F92A63:026Cf0AEl3:07792K62:AKl3:071F2862:Ar2l3:071F2962:71F92A63:02:CI0AEl3:071F2;62:71F92A63:02<CI0AEl3:07792K62:71F92A63:02=CK0AEl3<071F2>2?63:71F92A63:02@CU0Ar2L3;07792r262:71F933702A@402@A63:71F9262:" #(list
   emit loadnil + load0 add2 - argc-error neg sub2 * load1 / vector loadv #()
   apply tapply)))) #fn(get) arg-counts) compile-builtin-call)
-	    compile-f #fn("8000n27021>2262:" #(call-with-values #fn("8000n070AF62:" #(compile-f-))
-					       #fn("6000n20:" #())) compile-f)
-	    compile-f- #fn("=000n220>71501T721T51731T5174251T527215166:" #(#fn("8000n620>85J7021@408561:" #(#fn("9000n120>FH360E@7021F5161:" #(#fn("9000n120>02191451\x8061:" #(#fn("9000n120>71729245261:" #(#fn("C000n1934\x87\xa900JO07093021A932J80910@60910U54@s072930732425242605277280515153515247093029A28051932J80910@60910U5547:930940934933A55@30D47;9102<523L070930932J702=@402>91053@]0932\x87A0709302?91053@H0934JA0709302@91053@30O47A930933940PD7B94151544709302C5247D2E7F7G93051517H9305192053930r3G62:" #(emit
+	    compile-f #fn("8000n2702101>22262:" #(call-with-values #fn("7000n070AF62:" #(compile-f-))
+						  #fn("5000n20:" #())) compile-f)
+	    compile-f- #fn("<000n22001>271501T721T517315174251T527215166:" #(#fn("=000n62084082A83F185>87172F51835261:" #(#fn("=000n120AF92939495096>897J7021@409761:" #(#fn("=000n120AF92939495096>897H360E@8021975161:" #(#fn(">000n120AF9209394959697>9021A51\x8061:" #(#fn("?000n120AF092939495969798>:7172A5261:" #(#fn("A000n1A\x87\x9a00JK070F219293J7094@5094U54@m072F7324252426052772805151535152470F29922805193J7094@5094U5547:F95A969255@30D47;942<523H070F93J702=@402>9453@T093\x87>070F2?9453@C0AJ>070F2@9453@30O42AF9798>37B9596995361:" #(emit
   optargs bcode:indexfor make-perfect-hash-table
   #fn(map) #.cons #.car iota #fn(length) keyargs emit-optional-arg-inits > 255
-  largc lvargc vargc argc compile-in caddr ret values #fn(function)
-  encode-byte-code bcode:code const-to-idx-vec)) filter keyword-arg?))
-  #fn(length))) #fn(length))) λ)) make-code-emitter lastcdr lambda-vars filter
-  #.pair?) compile-f-)
-	    compile-for #fn(":000n57084513X07101O825447101O835447101O845447202362:742561:" #(1arg-lambda?
+  largc lvargc vargc argc #fn(":000n120A>1D510<E52471A0D72F5154473A2452475267778A515179A5192537:A5162:" #(#fn("8000n1\x8c0020A0>2_40<:" #(#fn("9000n20B3O00<T3=070A21153@30D4F<0=1KM62:D:" #(emit
+  box)))) compile-in lambda:body emit ret values #fn(function) encode-byte-code
+  bcode:code const-to-idx-vec bcode:cenv)) extend-env)) filter keyword-arg?))
+  #fn(length))) #fn(length))) λ)) complex-bindings lambda:body))
+  make-code-emitter lastcdr lambda:vars filter #.pair?) compile-f-)
+	    compile-for #fn("9000n57084513X07101O825447101O835447101O845447202362:742561:" #(1arg-lambda?
   compile-in emit for error "for: third form must be a 1-argument lambda") compile-for)
-	    compile-if #fn("<000n420>710517105183T728351738351B3;0748351@60755065:" #(#fn(";000n582DC>070AF9028364:82OC>070AF9028464:70AFO8254471A22053470AF902835449023<071A2352@:071A24153475A052470AF9028454475A162:" #(compile-in
+	    compile-if #fn(";000n4200182>3710517105183T728351738351B3;0748351@60755065:" #(#fn(":000n582DC=070AF928364:82OC=070AF928464:70AFO8254471A22053470AF9283544923<071A2352@:071A24153475A052470AF928454475A162:" #(compile-in
   emit brf ret jmp mark-label)) make-label caddr cdddr cadddr void) compile-if)
-	    compile-in #fn(";000n483R3=07001832164:83H3\xaf083EC:07202362:83KC:07202462:83DC:07202562:83OC:07202662:83qC:07202762:7883513<0720298363:2:83513C07;01822<2=51e164:7202>8363:83<RS;ID0483<Z;I;047?83<1523=07@01828364:2A>83<61:" #(compile-sym
-  #(loada loadc loadg) emit load0 load1 loadt loadf loadnil fits-i8 loadi8 #fn(eof-object?)
-  compile-in #fn(top-level-value) eof-object loadv in-env? compile-app #fn("=000n1020CW071903T513@072AF902903T64:73A24903T63:025C?076AF90290364:027C@078AF902903=64:029C<07:AF90363:02;C=07<2=>2>>62:02?C@07@AF902903=64:02AC@07BAF902903=64:02CCG07DAF903T277E90351P64:02FCK07GAF903T7H903517I9035165:02JCF072AFD903T54473A2K62:02LCa0903TR360O@807M2N51472AFO7H903515447OAF903T2P64:02QCs072AFO2;q903Te35447R7H9035151360O@807M2S51472AFO7H9035154473A2Q62:7TAF90290364:" #(quote
+	    compile-in #fn(":000n483R3<0700183D64:83H3\xaf083EC:07102262:83KC:07102362:83DC:07102462:83OC:07102562:83qC:07102662:7783513<0710288363:2983513C07:01822;2<51e164:7102=8363:83<RS;ID0483<Z;I;047>83<1523=07?01828364:2@830182>483<61:" #(compile-sym
+  emit load0 load1 loadt loadf loadnil fits-i8 loadi8 #fn(eof-object?)
+  compile-in #fn(top-level-value) eof-object loadv in-env? compile-app #fn("<000n1020CQ071AT513>072F9293AT64:73F24AT63:025C=076F9293A64:027C>078F9293A=64:029C;07:F92A63:02;CE07<2=92A>22>F92>262:02?C>07@F9293A=64:02AC>07BF9293A=64:02CCD07DF92AT277EA51P64:02FCF07GF92AT7HA517IA5165:02JCE072F92DAT54473F2K62:02LCR0ATR360O@807M2N5147OF92AT7HA5164:02PCo072F92O2;qATe35447Q7HA5151360O@807M2R51472F92O7HA5154473F2P62:7SF9293A64:" #(quote
   self-evaluating? compile-in emit loadv if compile-if begin compile-begin
-  prog1 compile-prog1 λ call-with-values #fn("8000n07091191362:" #(compile-f-))
-  #fn("9000n27091021053472910152417391151L3<0709102462:D:" #(emit loadv
-							     bcode:cdepth nnn
-							     closure)) and
-  compile-and or compile-or while compile-while cddr for compile-for caddr
+  prog1 compile-prog1 λ call-with-values #fn("7000n070AF62:" #(compile-f-))
+  #fn("9000n270A2105341\x87K07223AF>2152470A242515163:D:" #(emit loadv for-each
+							    #fn("9000n170AF0O64:" #(compile-sym))
+							    closure #fn(length)))
+  and compile-and or compile-or while compile-while cddr for compile-for caddr
   cadddr return ret set! error "set!: second argument must be a symbol"
-  compile-sym #(seta setc setg) trycatch 1arg-lambda? "trycatch: second form must be a 1-argument lambda"
+  compile-set! trycatch 1arg-lambda? "trycatch: second form must be a 1-argument lambda"
   compile-app))) compile-in)
-	    compile-or #fn("<000n470018283O2166:" #(compile-short-circuit brt) compile-or)
-	    compile-prog1 #fn(";000n37001O82T544718251B3H07201O7182515447302462:D:" #(compile-in
+	    compile-or #fn(";000n470018283O2166:" #(compile-short-circuit brt) compile-or)
+	    compile-prog1 #fn(":000n37001O82T544718251B3H07201O7182515447302462:D:" #(compile-in
   cddr compile-begin emit pop) compile-prog1)
-	    compile-short-circuit #fn(":000n683H3=07001828464:83=H3>070018283<64:21>7205161:" #(compile-in
-  #fn("<000n170AFO903<54471A2252471A905053471A2352474AF902903=90490556475A062:" #(compile-in
+	    compile-set! #fn("9000n420018382>471821E5361:" #(#fn(":000n1020CF071AFO9254472A239363:24AF92930>50<El61:" #(global
+  compile-in emit setg #fn(":000n120A0F9293>57194=5103<07294=51@9073A935262:" #(#fn(":000n203W070AF37021@4022153473A92O9354470A2462:73A92O93544FIA0752627945251@30D470A28163:" #(emit
+  loada loadc compile-in set-car! error #fn(string)
+  "internal error: misallocated var " seta)) vinfo:heap? vinfo:index
+  capture-var!)))) lookup-sym) compile-set!)
+	    compile-short-circuit #fn(";000n683H3=07001828464:83=H3>070018283<64:210183858284>67205161:" #(compile-in
+  #fn(";000n170AFO92<54471A2252471A93053471A2352474AF9492=959356475A062:" #(compile-in
   emit dup pop compile-short-circuit mark-label)) make-label) compile-short-circuit)
-	    compile-sym #fn(";000n420>71821ED5461:" #(#fn(":000n10X3>070A903EG063:0<X3R070A903KG0<0=54471A72F=51K0<h362:2390251;3>04742590251513A070A26259025163:70A903r2G90263:" #(emit
-  bcode:cdepth nnn #fn(constant?) printable? #fn(top-level-value) loadv))
-						      lookup-sym) compile-sym)
-	    compile-thunk #fn(";000n170q21q72051e362:" #(compile-f λ
+	    compile-sym #fn("9000n42082083>371821E5361:" #(#fn(":000n1020C^021A51;3<047223A51513?074F2523A5163:74F26A63:0<El3Z074F27780=5153492;3904790=513:074F2:62:D:74F2;7<FA5253492;3904790=513:074F2:62:D:" #(global
+  #fn(constant?) printable? #fn(top-level-value) emit loadv loadg loada
+  vinfo:index vinfo:heap? car loadc capture-var!)) lookup-sym) compile-sym)
+	    compile-thunk #fn(":000n170q21q72051e362:" #(compile-f λ
 							 lower-define) compile-thunk)
-	    compile-while #fn("9000n420>710517105162:" #(#fn(":000n270AFO715054472A052470AFO90254473A24153473A2552470AFO90354473A26053472A162:" #(compile-in
+	    compile-while #fn("9000n420018283>4710517105162:" #(#fn("9000n270AFO715054472A052470AFO9254473A24153473A2552470AFO9354473A26053472A162:" #(compile-in
   void mark-label emit brf pop jmp)) make-label) compile-while)
-	    const-to-idx-vec #fn("9000n120>21720515161:" #(#fn("9000n17021>72A515240:" #(table-foreach
-  #fn("8000n2A10p:" #()) bcode:ctable)) #fn(vector-alloc) bcode:nconst) const-to-idx-vec)
-	    copy-tree #fn("8000n10H3400:700<51700=51P:" #(copy-tree) copy-tree)
-	    count #fn("7000n220>D61:" #(#fn("9000n120>?040AFE63:" #(#fn(":000n31J5082:A01=01<5139082KM@408263:" #() count-)))) count)
-	    delete-duplicates #fn("8000n1700rD523<021>225061:0H3400:230<0=62:" #(length>
-  #fn("8000n120>D51Aq62:" #(#fn("6000n120>?040:" #(#fn("9000n20H38070161:219100<52390A0=162:229100<D534A0=0<1P62:" #(reverse!
-  #fn(has?) #fn(put!))))))) #fn(table) #fn("8000n270015238071161:071151P:" #(member
+	    complex-bindings #fn("7000n22001>22150215062:" #(#fn(";000n270AFOO0156471220>17315162:" #(complex-bindings-
+  filter #fn("7000n120A062:" #(#fn(has?))) table-keys))
+							     #fn(table)) complex-bindings)
+	    complex-bindings- #fn("=000n61J40O:0R3M083;39042001523;021840D63:D:0H;I80472051340O:0<23Co0200T1523Q021850TD534833>021840TD53@30D@30D474750511O83848566:760<513L074770517817905152OD848566:740<1D838485562:2;1838485>40=52P:" #(#fn(memq)
+  #fn(put!) quoted? set! complex-bindings- caddr is-lambda? lambda:body diff
+  lambda:vars #fn(map) #fn(";000n1700AOF929366:" #(complex-bindings-))) complex-bindings-)
+	    const-to-idx-vec #fn("8000n1200>121720515161:" #(#fn("8000n170210>172A515240:" #(table-foreach
+  #fn("7000n2A10p:" #()) bcode:ctable)) #fn(vector-alloc) bcode:nconst) const-to-idx-vec)
+	    copy-tree #fn("7000n10H3400:700<51700=51P:" #(copy-tree) copy-tree)
+	    count #fn("7000n22001>2D61:" #(#fn("8000n1\x8c00200>1_40<AFE63:" #(#fn("9000n31J5082:A<01=01<5139082KM@408263:" #() count-)))) count)
+	    delete-duplicates #fn("7000n1700rD523>0210>1225061:0H3400:230<0=62:" #(length>
+  #fn("7000n1200>1D51Aq62:" #(#fn("8000n1\x8c0020A0>2_40<:" #(#fn("8000n20H38070161:21A0<523:0F<0=162:22A0<D534F<0=0<1P62:" #(reverse!
+  #fn(has?) #fn(put!))))))) #fn(table) #fn("7000n270015238071161:071151P:" #(member
   delete-duplicates))) delete-duplicates)
-	    disassemble #fn("?000\x891000.///\x8a1000I60O?14|282JD07001E53471504D:@30D422>82<230512405163:" #(disassemble
-  newline #fn("8000n320>DD62:" #(#fn("9000n220>?0421>?1422>r423F5162:" #(#fn(":000n10\\;36040[S3E07021514720O910KM63:73061:" #(princ
-  "\n" disassemble print) print-val) #fn("<000n370921;3V04910El;3L04719217215152;3;04921182ML37023@4024751r5\x80512602765:" #(princ
+	    diff #fn("8000n20J40q:200<1523:0710=162:0<710=152P:" #(#fn(memq)
+								   diff) diff)
+	    disassemble #fn(">000\x891000.///\x8a1000I60O?14|282JD07001E53471504D:@30D4221>182<230512405163:" #(disassemble
+  newline #fn("9000n3200A821>4DD62:" #(#fn(":000n2\x8c0\x8c1020A>1_4121FA>2_422A109293>5r423935162:" #(#fn("9000n10\\;36040[S3C07021514720OAKM63:73061:" #(princ
+  "\n" disassemble print) print-val) #fn(";000n370A;3P04FEl;3H0471A7215152;3904A182ML37023@4024751r5\x80512602765:" #(princ
   >= 1- " >" "  " hex5 ":  " " ") print-inst)
-  #fn(":000n2D01L3E0420>2122>O735351@\x19/:" #(#fn(";000n170Ar4523907150@30D4E920K\x8022~4AKMz00423>061:" #(>
-  newline #fn("7000n1702161:" #(princ "\t"))
-  #fn(">000n120021523\\0921A910r45349209327293191052G514910r4Mz10:20023523W0921A910K534920932931910GG514910KMz10:20024523V0921A910K5347526931910G51514910KMz10:20027523[0921A910r45347526729319105251514910r4Mz10:20028523r0921A910r25347526931910G5129524910KMz1047526931910G51514910KMz10:2002:523\xb50921A910r8A2;C70r4@30EM534752672931910525129524910r4Mz1047526729319105251514910r4Mz104A2;CX07529514752672931910525129524910r4Mz10:D:02<c3]0921A910r4534752672931910525129524910r4Mz10:2002=523d0921A910r2534752>7?910r,7@93191052g351524910r2Mz10:2002A523d0921A910r4534752>7?910r,7293191052g351524910r4Mz10:921A910E63:" #(#fn(memq)
+  #fn(";000n2\x8c0D0<1L3S04200AF929394>62122940>2O735351@\x0a/:" #(#fn("<000n170A<r4523907150@30D4EFK\x8022~4AA<KM_423920A939495>6061:" #(>
+  newline #fn("6000n1702161:" #(princ "\t"))
+  #fn("=000n120021523Y0A<F92<r453493<94729592<52G5149292<r4M_:20023523T0A<F92<K53493<949592<GG5149292<KM_:20024523T0A<F92<K53475269592<G515149292<KM_:20027523Y0A<F92<r45347526729592<52515149292<r4M_:20028523\xb10A<F92<r8F29C70r4@30EM5347526729592<52512:5249292<r4M_47526729592<52515149292<r4M_4F29CW0752:5147526729592<52512:5249292<r4M_:D:02;c3[0A<F92<r45347526729592<52512:5249292<r4M_:2002<523b0A<F92<r2534752=7>92<r,7?9592<52g3515249292<r2M_:2002@523b0A<F92<r4534752=7>92<r,729592<52g3515249292<r4M_:A<F92<E63:" #(#fn(memq)
   (loadv.l loadg.l setg.l) ref-int32-LE (loadv loadg setg)
-  (loada seta call tcall list + - * / vector argc vargc loadi8 apply tapply)
-  princ #fn(number->string) (loada.l seta.l largc lvargc call.l tcall.l) (loadc
-  setc) " " (loadc.l setc.l optargs keyargs) keyargs brbound (jmp brf brt brne
-								  brnn brn) "@"
-  hex5 ref-int16-LE (jmp.l brf.l brt.l brne.l brnn.l brn.l)))))
-					       #fn(table-foldl)
-					       #fn("8000n382;I@041921AGQ;34040:" #())
-					       Instructions))
+  (loada seta loadc call tcall list + - * / vector argc vargc loadi8 apply
+   tapply closure box) princ #fn(number->string)
+  (loada.l seta.l loadc.l largc lvargc call.l tcall.l box.l) (optargs keyargs)
+  keyargs " " brbound (jmp brf brt brne brnn brn) "@" hex5 ref-int16-LE (jmp.l
+  brf.l brt.l brne.l brnn.l brn.l))))) #fn(table-foldl)
+								   #fn("7000n382;I?041AF<GQ;34040:" #())
+								   Instructions))
   #fn(length))))) #fn(function:code) #fn(function:vals)) disassemble)
-	    div #fn("8000n201k0EL;3C041EL;3404K;I504r/;I404EM:" #() div) emit
-	    #fn("G000|282Jb0120Q;3C040EGB;3:040EG<21Q3;00EG22_@:00E10EGPp@\xe2023124523A075082<52e1?2@30D426>271285251429>2712:5251412;C\\0822<d3=02=?14q?2@F0822>d3=02??14q?2@30O@30D412@C\\0822Ad3=02B?14q?2@F0822Cd3=02D?14q?2@30O@30D42E>0EGB3900EG<@30q0EG5240:" #(car
-  cdr cadr #fn(memq) (loadv loadg setg) bcode:indexfor #fn("8000n10;3=0470902<21523800Tz01:D:" #(>
+	    div #fn("7000n201k0EL;3C041EL;3404K;I504r/;I404EM:" #() div) emit
+	    #fn("F000|2\x8c1\x8c282<Jd01<20Q;3C040EGB;3:040EG<21Q3;00EG22_@;00E1<0EGPp@\xfe0231<24523C08275082<<52e1_@30D426821>2271<285251429821>2271<2:525141<2;C`082<2<d3>012=_482q_@H082<2>d3>012?_482q_@30O@30D41<2@C`082<2<d3>012A_482q_@H082<2>d3>012B_482q_@30O@30D42C1082>30EGB3900EG<@30q0EG5240:" #(car
+  cdr cadr #fn(memq) (loadv loadg setg) bcode:indexfor #fn("7000n10;3<0470A<<2152370F0T_:D:" #(>
   255)) #fn(assq) ((loadv loadv.l) (loadg loadg.l) (setg setg.l) (loada loada.l)
-				   (seta seta.l))
-  #fn("8000n10;3L0470902<2152;I=0470902T21523800Tz01:D:" #(> 255))
-  ((loadc loadc.l) (setc setc.l)) loada (0) loada0 (1) loada1 loadc (0 0)
-  loadc00 (0 1) loadc01 #fn(">000n2F20Q;3\x9a04021Q;38041T22Q3E0AE902<2374151PPp@u0021CB0AE902<251=PPp@_0026CB0AE902<271=PPp@I0022CB0AE902<281=PPp@30O;I^04F25Q;3704022Q3@0AE902<231=PPp:AE79F902P152p:" #(brf
+				   (seta seta.l) (box box.l))
+  #fn("7000n10;3<0470A<<2152370F0T_:D:" #(> 255))
+  ((loadc loadc.l)) loada (0) loada0 (1) loada1 loadc loadc0 loadc1 #fn("=000n2A<20Q;3\x9a04021Q;38041T22Q3E0FE92<<2374151PPp@u0021CB0FE92<<251=PPp@_0026CB0FE92<<271=PPp@I0022CB0FE92<<281=PPp@30O;I`04A<25Q;3704022Q3@0FE92<<231=PPp:FE79A<92<P152p:" #(brf
   not null? brn cddr brt eq? brne brnn nreconc))) emit)
-	    emit-optional-arg-inits #fn("8000n582B3=020>7105161:D:" #(#fn("<000n170A2190453470A22053473A7490390452FPO759025154470A2690453470A2752478A052479AF902=903904KM65:" #(emit
-  brbound brt compile-in list-head cadar seta pop mark-label
+	    emit-optional-arg-inits #fn(":000n582B3F02008418382>57105161:D:" #(#fn(";000n170A21F53470A22053473A74927593F52q53O76945154470A27F53470A2852479A05247:A9294=93FKM65:" #(emit
+  brbound brt compile-in extend-env list-head cadar seta pop mark-label
   emit-optional-arg-inits)) make-label) emit-optional-arg-inits)
-	    encode-byte-code #fn("8000n1207105161:" #(#fn("8000n1207105161:" #(#fn(";000n120>7122051r322051r2ki2M235261:" #(#fn("=000n120>21A51E225022502350OO67:" #(#fn("?000n7208421524D10L3\xff049101G?548522CO023829101KMG2484515341r2M?1@\xcf02084752677A3<028>8551@408552515241KM?1410L3:09101G@30O?6429852:523^02383248451865342084A3707;@407<E515241KM?1@_0852=CG020847;86515241KM?1@C086X3<02>>8551@30O@_/47?2@>835242A8461:" #(#fn(io-write)
-  #int32(0) label #fn(put!) #fn(sizeof) byte #fn(get) Instructions #fn("7000n1020C5021:022C5023:024C5025:026C5027:028C5029:02:C502;:905:" #(jmp
+	    encode-byte-code #fn("7000n1207105161:" #(#fn("7000n1207105161:" #(#fn(":000n1200>17122051r322051r2ki2M235261:" #(#fn("<000n120A0>221A51E225022502350OO67:" #(#fn("@000n7\x8c1\x8c5\x8c6208421524D1<0L3\x180485A1<G_485<22CO02382A1<KMG24845153411<r2M_@\xe702084752677F3@02885>185<51@5085<525152411<KM_4861<0L390A1<G@30O_42985<2:523`0238324845186<5342084F3707;@407<E5152411<KM_@m085<2=CI020847;86<5152411<KM_@N086<X3F02>84861A85>585<51@30O@E/47?2@84F82>3835242A8461:" #(#fn(io-write)
+  #int32(0) label #fn(put!) #fn(sizeof) byte #fn(get) Instructions #fn("6000n1020C5021:022C5023:024C5025:026C5027:028C5029:02:C502;:A<:" #(jmp
   jmp.l brt brt.l brf brf.l brne brne.l brnn brnn.l brn brn.l))
-  #fn(memq) (jmp brf brt brne brnn brn) int32 int16 brbound #fn(":000n120021523H0229047390651524FKMz01:20024523`0229047590651524FKMz0142290475920FG51524FKMz01:20026523\x820229047390651524FKMz0142290473920FG51524FKMz01490527CJ02290473920FG51524FKMz01:D:229047590651524FKMz01:" #(#fn(memq)
-  (loadv.l loadg.l setg.l loada.l seta.l largc lvargc call.l tcall.l)
-  #fn(io-write) int32 (loadc setc) uint8 (loadc.l setc.l optargs keyargs)
-  keyargs)) table-foreach #fn("<000n22090405242190491037072@4073249021520\x805162:" #(#fn(io-seek)
-  #fn(io-write) int32 int16 #fn(get))) #fn(iostream->string)))
-  #fn(length) #fn(table) #fn(buffer))) >= #fn(length) 65536)) list->vector))
-						      reverse!) encode-byte-code)
-	    error #fn(":000|020210P61:" #(#fn(raise) error) error) eval
-	    #fn("8000n170710515160:" #(compile-thunk expand) eval) even? #fn("8000n1200K52El:" #(#fn(logand)) even?)
-	    every #fn("8000n21H;ID0401<51;3:047001=62:" #(every) every) expand
-	    #fn("A000n120>DDDDDDDDDDD6;:" #(#fn("8000n;20?0421>?1422e1?2423>?3424>?4425>?5426>?6427>?7428>?8429?942:>?:48:Aq62:" #(#fn("8000n20Z;I904200152S:" #(#fn(assq)) top?)
-  #fn("9000n10H3400:020d3400:0<B;3;047105122Q3D023F7405151F0=5162:0<F0=51P:" #(((begin))
-  caar begin #fn(append) cdar) splice-begin) *expanded* #fn("9000n20H3400:20>A21152390F051@30061:" #(#fn("9000n120>91021F5261:" #(#fn("8000n120>03:071A51@30q61:" #(#fn(":000n120>2122230529215261:" #(#fn("8000n1910I=02021>92062:22>23>D519205161:" #(#fn(map)
-  #fn("8000n195:0A62:" #()) #fn("7000n120>061:" #(#fn("9000n1D0B3]0496270051QIA0096:0<91052_@90071051_40=?0@\x02/4A:" #(caar
-  cdar)))) #fn("6000n120>?040:" #(#fn("9000n10H3400:0<B;3;042071051Q3;00<A0=51P:22>96:0<9105261:" #(define
-  caar #fn(":000n1202122730515292052z2049720P910A=51P:" #(#fn(nconc)
-							  #fn(map) #.list
-							  get-defined-vars))))))))
+  #fn(memq) (jmp brf brt brne brnn brn) int32 int16 brbound #fn("9000n120021523G022A73F<515249292<KM_:20024523\x83022A73F<515249292<KM_422A739392<G515249292<KM_494<25CK022A739392<G515249292<KM_:D:22A76F<515249292<KM_:" #(#fn(memq)
+  (loadv.l loadg.l setg.l loada.l seta.l largc lvargc call.l tcall.l loadc.l
+   box.l) #fn(io-write) int32 (optargs keyargs) keyargs uint8)) table-foreach
+  #fn(";000n220A052421AF37072@407324921520\x805162:" #(#fn(io-seek)
+						       #fn(io-write) int32
+						       int16 #fn(get)))
+  #fn(iostream->string))) #fn(length) #fn(table)
+  #fn(buffer))) >= #fn(length) 65536)) list->vector)) reverse!) encode-byte-code)
+	    error #fn("9000|020210P61:" #(#fn(raise) error) error) eval
+	    #fn("7000n170710515160:" #(compile-thunk expand) eval) even? #fn("7000n1200K52El:" #(#fn(logand)) even?)
+	    every #fn("7000n21H;ID0401<51;3:047001=62:" #(every) every) expand
+	    #fn("@000n1200>1DDDDDDDDDDD6;:" #(#fn(";000n;\x8c0\x8c1\x8c2\x8c3\x8c4\x8c5\x8c6\x8c7\x8c8\x8c9\x8c:020_41211>1_48222e1_483238:8201>4_484248:84>2_4852585>1_48626848385>3_487278:848385>4_48828838:>2_48929_48:2:8:89868788>5_48:<Aq62:" #(#fn("7000n20Z;I904200152S:" #(#fn(assq)) top?)
+  #fn("8000n10H3400:020d3400:0<B;3;047105122Q3F023A<7405151A<0=5162:0<A<0=51P:" #(((begin))
+  caar begin #fn(append) cdar) splice-begin) *expanded* #fn("9000n20H3400:20AF192>492<211523;093<051@30061:" #(#fn("9000n120A0F92>493<21925261:" #(#fn(":000n1200AF9293>503:071F51@30q61:" #(#fn("9000n120AF9293>4212223052945261:" #(#fn("9000n1\x8c0AI?02021F0>29262:2293F0>323093F>3D51925161:" #(#fn(map)
+  #fn("7000n1A<0F<62:" #()) #fn("9000n120AF920>4061:" #(#fn("8000n1D0B3[04A<70051QI@00F<0<92<52_@90071051_40=?0@\x04/493:" #(caar
+  cdar)))) #fn(":000n1\x8c00200AF92>4_40<:" #(#fn("9000n10H3400:0<B;3;042071051Q3<00<A<0=51P:22F92A0>493<0<F<5261:" #(define
+  caar #fn(":000n1A2021227305152A<52_4F<0P92<93=51P:" #(#fn(nconc)
+							#fn(map) #.list
+							get-defined-vars))))))))
   #fn(nconc) #fn(map) #.list)) get-defined-vars)) define)) begin) expand-body)
-  #fn(":000n20H3400:0<B;37040<=B3G07005190:71051152e2@400<9040=152P:" #(caar
-  cadar) expand-lambda-list) #fn("8000n10H3600e1:0<B3@0700519050=51P:0<9050=51P:" #(caar) l-vars)
-  #fn(";000n220>0T71051720519050T5164:" #(#fn(":000n420>2122238352F5261:" #(#fn(";000n12021e1924A052e1923902052F64:" #(#fn(nconc)
+  #fn("9000n20H3400:0<B;37040<=B3F070051A<71051152e2@400<F<0=152P:" #(caar
+  cadar) expand-lambda-list) #fn("7000n10H3600e1:0<B3?070051A<0=51P:0<A<0=51P:" #(caar) l-vars)
+  #fn(":000n220AF1>30T710517205192<0T5164:" #(#fn(":000n420A0F821>52122238352925261:" #(#fn(":000n12021e1A<F052e192<930529464:" #(#fn(nconc)
   λ)) #fn(nconc) #fn(map) #.list)) lastcdr cddr) expand-lambda)
-  #fn("<000n20=V;I6040TH3N070051J400:210T90:72051152e3:23>740517505170051905740515164:" #(cddr
-  define caddr #fn(":000n420>2122238352F5261:" #(#fn(";000n12021e1F924A052Pe192390205263:" #(#fn(nconc)
+  #fn(";000n20=V;I6040TH3M070051J400:210TA<72051152e3:23F921>374051750517005193<740515164:" #(cddr
+  define caddr #fn(":000n4201A0F82>52122238352925261:" #(#fn(":000n12021e1AF<92052Pe193<9405263:" #(#fn(nconc)
   define)) #fn(nconc) #fn(map) #.list)) cdadr caadr) expand-define)
-  #fn("7000n220>0T61:" #(#fn("<000n12091371A51222324>052F5252P:" #(begin cddr
-								   #fn(nconc)
-								   #fn(map)
-								   #fn(":000n10<7092:0T911525150911e3:" #(compile-thunk))))) expand-let-syntax)
-  #fn("6000n20:" #() local-expansion-env)
-  #fn("7000n20H3400:20>0<61:" #(#fn("9000n120>210F5261:" #(#fn("7000n120>21>61:" #(#fn(":000n1A;3604A=B3M093:AT920=f293970A519215262:A;IA04910RS;I704910Z360060:21>729205161:" #(caddr
-  #fn("8000n103B094:0930=f293162:92020C60930:92021C>094693093162:92021C>094693093162:92022C>094793093162:92023C>094893093162:A60:" #(quote
-  λ define let-syntax)) macrocall?)) #fn("7000n020>D5192061:" #(#fn("6000n120>?040:" #(#fn("9000n10H3400:0<H3700<@<094:0<93152A0=51P:" #())))))))
-							   #fn(assq)))) expand-in)))) expand)
-	    expand-define #fn("=000n1200T71051B3:071051@L00TR3;07250e1@=07324750515262:" #(#fn("<000n20R3:02001<e3:200<2122e10=e1231510<54e3:" #(set!
+  #fn("9000n220A0F1>40T61:" #(#fn("<000n120A<71F512223249293>2052935252P:" #(begin
+  cddr #fn(nconc) #fn(map) #fn("9000n10<70A<0TF525150Fe3:" #(compile-thunk))))) expand-let-syntax)
+  #fn("5000n20:" #() local-expansion-env)
+  #fn("<000n20H3400:20A0F1929394>70<61:" #(#fn("=000n120AF92930949596>8210935261:" #(#fn(">000n1200AF929394959697>921A93F>361:" #(#fn("=000n1A;3604A=B3J0F<AT92=f293<70A51945262:A;I?0495RS;I60495Z360060:21F9294959697980>872925161:" #(caddr
+  #fn("7000n103>0A<0F=f29262:9320C40F:9321C;094<F9262:9321C;094<F9262:9322C;095<F9262:9323C;096<F9262:9760:" #(quote
+  λ define let-syntax)) macrocall?)) #fn("7000n020AF>2D519261:" #(#fn("9000n1\x8c0020AF0>3_40<:" #(#fn("8000n10H3400:0<H3700<@90A<0<F5292<0=51P:" #())))))))
+  #fn(assq)))) expand-in)))) expand)
+	    expand-define #fn("<000n1200T71051B3:071051@L00TR3;07250e1@=07324750515262:" #(#fn(";000n20R3:02001<e3:200<2122e10=e1231510<54e3:" #(set!
   #fn(nconc) λ #fn(copy-list))) cddr void error "compile error: invalid syntax "
   print-to-string) expand-define)
-	    filter #fn("7000n220>D61:" #(#fn("9000n120>?040AFqe163:" #(#fn("9000n382D1B3S049101<513?0821<qPN=?2@30D41=?1@\f/4=:" #() filter-)))) filter)
-	    fits-i8 #fn("8000n10Y;3F04700r\xb052;3:04710r\xaf62:" #(>= <=) fits-i8)
-	    foldl #fn(":000n382J401:700082<15282=63:" #(foldl) foldl) foldr
-	    #fn(";000n382J401:082<700182=5362:" #(foldr) foldr) for-each #fn(";000|220>D61:" #(#fn(":000n120>?04902JJ0DFB3A04AF<514F=z01@\x1e/@;00AF902P524D:" #(#fn(":000n21<B3I002021152f24A0202215262:D:" #(#fn(map)
+	    extend-env #fn(":000n3202182>11722315151530P:" #(#fn(map)
+							     #fn("9000n2700210A52SS163:" #(vinfo
+  #fn(memq))) iota #fn(length)) extend-env)
+	    filter #fn("7000n22001>2D61:" #(#fn("8000n120A>1?040AFqe163:" #(#fn("8000n382D1B3Q04A1<513?0821<qPN=?2@30D41=?1@\x0e/4=:" #() filter-)))) filter)
+	    fits-i8 #fn("7000n10Y;3F04700r\xb052;3:04710r\xaf62:" #(>= <=) fits-i8)
+	    foldl #fn("9000n382J401:700082<15282=63:" #(foldl) foldl) foldr
+	    #fn(":000n382J401:082<700182=5362:" #(foldr) foldr) for-each #fn("<000|2\x8c1208210>3D61:" #(#fn("9000n1\x8c00200>1_4AJM0DF<B3C0492F<<514FF<=_@\x1b/@<00<92F<AP524D:" #(#fn("9000n21<B3J002021152f24A<0202215262:D:" #(#fn(map)
   #.car #.cdr) for-each-n)))) for-each)
-	    get-defined-vars #fn("8000n170A05161:" #(delete-duplicates) #0=#(#fn("9000n10H340q:0<20Q;36040=B3d00TR;37040Te1;IS040TB;3E0471051R;3:0471051e1;I404q:0<22C>02324A0=52\x7f2:q:" #(define
-  caadr begin #fn(nconc) #fn(map)) #0#) ()))
-	    hex5 #fn("9000n170210r@52r52263:" #(string-lpad #fn(number->string)
+	    get-defined-vars #fn("7000n170A<05161:" #(delete-duplicates) #(#0=(#fn("8000n10H340q:0<20Q;36040=B3d00TR;37040Te1;IS040TB;3E0471051R;3:0471051e1;I404q:0<22C?02324A<0=52\x7f2:q:" #(define
+  caadr begin #fn(nconc) #fn(map)) #(#0#)))))
+	    hex5 #fn("8000n170210r@52r52263:" #(string-lpad #fn(number->string)
 						#\0) hex5)
-	    identity #fn("6000n10:" #() identity) in-env?
-	    #fn("8000n21B;3F042001<52;I:047101=62:" #(#fn(memq) in-env?) in-env?)
-	    index-of #fn(":000n31J40O:01<C5082:7001=82KM63:" #(index-of) index-of)
-	    io-readall #fn("7000n120>215061:" #(#fn("8000n1200A52421>2205161:" #(#fn(io-copy)
-  #fn("7000n1020d;3:0421910513702260:0:" #("" #fn(io-eof?)
-					   #fn(eof-object)))
+	    identity #fn("5000n10:" #() identity) in-env?
+	    #fn("7000n21B;3F042001<52;I:047101=62:" #(#fn(assq) in-env?) in-env?)
+	    index-of #fn("9000n31J40O:01<C5082:7001=82KM63:" #(index-of) index-of)
+	    io-readall #fn("6000n1200>1215061:" #(#fn("7000n1200A52421A>12205161:" #(#fn(io-copy)
+  #fn("6000n1020d;380421A513702260:0:" #("" #fn(io-eof?)
+					 #fn(eof-object)))
   #fn(iostream->string))) #fn(buffer)) io-readall)
-	    io-readline #fn("8000n12002162:" #(#fn(io-readuntil) #\newline) io-readline)
-	    io-readlines #fn("8000n17071062:" #(read-all-of io-readline) io-readlines)
-	    iota #fn("8000n17071062:" #(map-int identity) iota) is-lambda?
-	    #fn("7000n1020Q;I704020Q:" #(λ) is-lambda?) keyword->symbol #fn("9000n1200513@02122230515161:0:" #(#fn(keyword?)
-  #fn(symbol) #fn(";000n1200E71220515163:" #(#fn(string-sub) 1- #fn(string-length)))
+	    io-readline #fn("7000n12002162:" #(#fn(io-readuntil) #\newline) io-readline)
+	    io-readlines #fn("7000n17071062:" #(read-all-of io-readline) io-readlines)
+	    iota #fn("7000n17071062:" #(map-int identity) iota) is-lambda?
+	    #fn("6000n1020Q;I704020Q:" #(λ) is-lambda?) keyword->symbol #fn("8000n1200513@02122230515161:0:" #(#fn(keyword?)
+  #fn(symbol) #fn(":000n1200E71220515163:" #(#fn(string-sub) 1- #fn(string-length)))
   #fn(string)) keyword->symbol)
-	    keyword-arg? #fn("7000n10B;3904200<61:" #(#fn(keyword?)) keyword-arg?)
-	    lambda-vars #fn("7000n120>D61:" #(#fn(":000n120>?040AAOO544212273A5162:" #(#fn(";000n40V;I5040R340D:0B;36040<R3S082;I504833<0702112263:A0=1828364:0B;36040<B3\x870730<r252;390474051R360O@=070250<2615442774051513<0A0=182D64:833<0702112863:A0=1D8364:0B3>070290<26164:01C:07021162:7029026164:" #(error
+	    keyword-arg? #fn("6000n10B;3904200<61:" #(#fn(keyword?)) keyword-arg?)
+	    lambda-vars #fn("6000n1200>1D61:" #(#fn("9000n1\x8c00200>1_40<AAOO544212273A5162:" #(#fn(":000n40V;I5040R340D:0B;36040<R3T082;I504833<0702112263:A<0=1828364:0B;36040<B3\x890730<r252;390474051R360O@=070250<2615442774051513=0A<0=182D64:833<0702112863:A<0=1D8364:0B3>070290<26164:01C:07021162:7029026164:" #(error
   "compile error: invalid argument list "
   ". optional arguments must come after required." length= caar "compile error: invalid optional argument "
   " in list " #fn(keyword?) ". keyword arguments must come last."
   "compile error: invalid formal argument ") check-formals)
-  #fn(map) #fn("7000n10B390700<61:0:" #(keyword->symbol)) to-proper))) lambda-vars)
-	    last-pair #fn("7000n10=H3400:700=61:" #(last-pair) last-pair)
-	    lastcdr #fn("7000n10H3400:70051=:" #(last-pair) lastcdr) length=
-	    #fn("9000n21EL340O:1El3500H:0H3601El:700=1K\x8062:" #(length=) length=)
-	    length> #fn("9000n21EL3400:1El3;00B;34040:0H3601EL:700=1K\x8062:" #(length>) length>)
-	    list->vector #fn("7000n1200\x7f2:" #(#.vector) list->vector)
-	    list-head #fn(":000n2701E52340q:0<710=1K\x8052P:" #(<= list-head) list-head)
-	    list-ref #fn("8000n2700152<:" #(list-tail) list-ref) list-tail
-	    #fn("9000n2701E523400:710=1K\x8062:" #(<= list-tail) list-tail)
-	    list? #fn("7000n10V;I@040B;3904700=61:" #(list?) list?) load
-	    #fn("9000n120>210225261:" #(#fn("7000n120>21>}:" #(#fn("9000n020>D51DDD63:" #(#fn("6000n120>?040:" #(#fn(":000n32091051IC0A219105107215163:2391051472161:" #(#fn(io-eof?)
+  #fn(map) #fn("6000n10B390700<61:0:" #(keyword->symbol)) to-proper))) lambda-vars)
+	    lambda:body #fn("6000n170061:" #(caddr) lambda:body) lambda:vars
+	    #fn("6000n1700T61:" #(lambda-vars) lambda:vars) last-pair #fn("6000n10=H3400:700=61:" #(last-pair) last-pair)
+	    lastcdr #fn("6000n10H3400:70051=:" #(last-pair) lastcdr) length=
+	    #fn("8000n21EL340O:1El3500H:0H3601El:700=1K\x8062:" #(length=) length=)
+	    length> #fn("8000n21EL3400:1El3;00B;34040:0H3601EL:700=1K\x8062:" #(length>) length>)
+	    list->vector #fn("6000n1200\x7f2:" #(#.vector) list->vector)
+	    list-head #fn("9000n2701E52340q:0<710=1K\x8052P:" #(<= list-head) list-head)
+	    list-ref #fn("7000n2700152<:" #(list-tail) list-ref) list-tail
+	    #fn("8000n2701E523400:710=1K\x8062:" #(<= list-tail) list-tail)
+	    list? #fn("6000n10V;I@040B;3904700=61:" #(list?) list?) load
+	    #fn("8000n1200>1210225261:" #(#fn("8000n1200>1210A>2}:" #(#fn("8000n020A>1D51DDD63:" #(#fn("8000n1\x8c0020A0>2_40<:" #(#fn("9000n320A51IB0F<21A5107215163:23A51472161:" #(#fn(io-eof?)
   #fn(read) load-process #fn(io-close)))))))
-							       #fn("9000n120A51421229100e361:" #(#fn(io-close)
-  #fn(raise) load-error)))) #fn(file) :read) load)
-	    load-process #fn("7000n170061:" #(eval) load-process) lookup-sym
-	    #fn("7000n41J5020:21>1<61:" #((global)
-					  #fn(":000n120>71A0E5361:" #(#fn(";000n103@09133400:9120P:70910911=913;I504AV380912@70912KMO64:" #(lookup-sym))
-  index-of))) lookup-sym)
-	    lower-define #fn("7000n120>D61:" #(#fn(";000n120?04AH;I80471A51340A:A<22C<07374A5161:75A<513J02627e1ATe10A51e178A5164:2973A62:" #(#fn("9000n12071051B3N072051B3=02371051P@7074051@60755061:" #(#fn("9000n120710517205162:" #(#fn("9000n20J401:2001e32122052P:" #(λ
-  #fn(map) #fn("6000n17060:" #(void)))) get-defined-vars lower-define)) cddr
+  #fn("8000n120A5142122F0e361:" #(#fn(io-close)
+				  #fn(raise) load-error))))
+					  #fn(file) :read) load)
+	    load-process #fn("6000n170061:" #(eval) load-process) lookup-sym
+	    #fn("8000n31J5020:218201>31<61:" #(global #fn("8000n120AF92>321F05261:" #(#fn("9000n10360A0P:70F92=AKM63:" #(lookup-sym))
+  #fn(assq)))) lookup-sym)
+	    lower-define #fn("6000n1200>1D61:" #(#fn(":000n120?04AH;I80471A51340A:A<22C<07374A5161:75A<513J02627e1ATe10A51e178A5164:2973A62:" #(#fn("8000n12071051B3N072051B3=02371051P@7074051@60755061:" #(#fn("8000n120710517205162:" #(#fn("8000n20J401:2001e32122052P:" #(λ
+  #fn(map) #fn("5000n17060:" #(void)))) get-defined-vars lower-define)) cddr
   cdddr begin caddr void) λ-body) quoted? define lower-define expand-define
   is-lambda? #fn(nconc) λ lastcdr #fn(map)))) lower-define)
-	    macrocall? #fn("7000n10<R;3904700<61:" #(symbol-syntax) macrocall?)
-	    macroexpand-1 #fn("8000n10H3400:20>7105161:" #(#fn("7000n103800A=\x7f2:A:" #())
-							   macrocall?) macroexpand-1)
-	    make-code-emitter #fn("9000n0q2050E21o4:" #(#fn(table) +inf.0) make-code-emitter)
-	    make-label #fn("6000n12060:" #(#fn(gensym)) make-label)
-	    make-perfect-hash-table #fn("7000n120>D61:" #(#fn("8000n120?0421>D5122A5161:" #(#fn("9000n270712205151162:" #(mod0
-  abs #fn(hash)) $hash-keyword) #fn("6000n120>?040:" #(#fn("9000n120>21r20i2O5261:" #(#fn("7000n120>D5193061:" #(#fn("6000n120>?040:" #(#fn("8000n10B3=020>7105161:910:" #(#fn(":000n120>r2950093052i261:" #(#fn("9000n19300G3=0950940KM61:9300Ap49300KM7091051p4920910=61:" #(cdar))))
+	    macrocall? #fn("6000n10<R;3904700<61:" #(symbol-syntax) macrocall?)
+	    macroexpand-1 #fn("7000n10H3400:200>17105161:" #(#fn("6000n103800A=\x7f2:A:" #())
+							     macrocall?) macroexpand-1)
+	    make-code-emitter #fn("8000n0q2050Eqo4:" #(#fn(table)) make-code-emitter)
+	    make-label #fn("5000n12060:" #(#fn(gensym)) make-label)
+	    make-perfect-hash-table #fn("6000n1200>1D61:" #(#fn("7000n1\x8c0020_4210A>2D5122A5161:" #(#fn("8000n270712205151162:" #(mod0
+  abs #fn(hash)) $hash-keyword) #fn("9000n1\x8c00200AF>3_40<:" #(#fn("9000n120A0F92>421r20i2O5261:" #(#fn("9000n1200AF92>4D519361:" #(#fn(";000n1\x8c0020AF92093>5_40<:" #(#fn(";000n10B3G020AF9209394>67105161:A:" #(#fn(";000n120AF9209394>6r295<09252i261:" #(#fn("8000n1A0G3;0F<92KM61:A093p4A0KM709451p495<94=61:" #(cdar))))
   caar)))))) #fn(vector-alloc))))) #fn(length)))) make-perfect-hash-table)
-	    make-system-image #fn(";000n120210222324542562:" #(#fn("8000n220>717262:" #(#fn("7000n2Dw04Dw1422>23>61:" #(*print-pretty*
-  *print-readably* #fn("7000n120>21>}0504:" #(#fn(":000n020>7122>73245051525142592061:" #(#fn("=000n1202122230222405253f2920524259207662:" #(#fn(write)
+	    make-system-image #fn(":000n120210222324542562:" #(#fn("7000n22001>2717262:" #(#fn("8000n2Dw04Dw1422AF>22301>261:" #(*print-pretty*
+  *print-readably* #fn("7000n120AF>2210>1}0504:" #(#fn("9000n020A>17122F>1732450515251425A61:" #(#fn("<000n1202122230222405253f2A52425A7662:" #(#fn(write)
   #fn(nconc) #fn(map) #.list #fn(top-level-value)
-  #fn(io-write) *linefeed*)) filter #fn("9000n10Z;3w0420051S;3l0421051[S;IC0422051222105151dS;3K0423092152S;3=04242105151S:" #(#fn(constant?)
+  #fn(io-write) *linefeed*)) filter #fn("8000n10Z;3u0420051S;3j0421051[S;IC0422051222105151dS;3I04230A52S;3=04242105151S:" #(#fn(constant?)
   #fn(top-level-value) #fn(string) #fn(memq)
   #fn(iostream?))) simple-sort #fn(environment)
-  #fn(io-close))) #fn("7000n1A50420061:" #(#fn(raise)))))
-  #fn("6000n0Aw04Fw1:" #(*print-pretty* *print-readably*)))) *print-pretty*
+  #fn(io-close))) #fn("6000n1A50420061:" #(#fn(raise)))))
+  #fn("5000n0Aw04Fw1:" #(*print-pretty* *print-readably*)))) *print-pretty*
   *print-readably*)) #fn(file) :write :create :truncate (*linefeed*
 							 *directory-separator*
 							 *argv* that
@@ -339,131 +354,132 @@
 							 *print-level*
 							 *print-length*
 							 *os-name*)) make-system-image)
-	    map! #fn("9000n21D1B3B04101<51_41=?1@\x1d/4:" #() map!) map-int
-	    #fn("8000n2701E52340q:21>0E51qPq62:" #(<= #fn(":000n20?14KFK\x8020>~40:" #(#fn("8000n1F910051qPN4F=z01:" #())))) map-int)
-	    mark-label #fn("9000n270021163:" #(emit label) mark-label) max
-	    #fn("<000|11J400:70210163:" #(foldl #fn("7000n201L3401:0:" #())) max)
-	    member #fn("8000n21H340O:1<0d3401:7001=62:" #(member) member) memv
-	    #fn("8000n21H340O:1<0c3401:7001=62:" #(memv) memv) min #fn("<000|11J400:70210163:" #(foldl
-  #fn("7000n201L3400:1:" #())) min)
-	    mod #fn("9000n207001521i2\x80:" #(div) mod) mod0
-	    #fn("8000n2001k1i2\x80:" #() mod0) nan? #fn("7000n1020d;I704021d:" #(+nan.0
+	    map! #fn("8000n21D1B3B04101<51_41=?1@\x1d/4:" #() map!) map-int
+	    #fn("7000n2701E52340q:2110>20E51qPq62:" #(<= #fn("9000n2\x8c110_4KAK\x80201F>2~40:" #(#fn("7000n1A<F051qPN4AA<=_:" #())))) map-int)
+	    mark-label #fn("8000n270021163:" #(emit label) mark-label) max
+	    #fn(";000|11J400:70210163:" #(foldl #fn("6000n201L3401:0:" #())) max)
+	    member #fn("7000n21H340O:1<0d3401:7001=62:" #(member) member) memv
+	    #fn("7000n21H340O:1<0c3401:7001=62:" #(memv) memv) min #fn(";000|11J400:70210163:" #(foldl
+  #fn("6000n201L3400:1:" #())) min)
+	    mod #fn("8000n207001521i2\x80:" #(div) mod) mod0
+	    #fn("7000n2001k1i2\x80:" #() mod0) nan? #fn("6000n1020d;I704021d:" #(+nan.0
   -nan.0) nan?)
-	    negative? #fn("7000n10EL:" #() negative?) nestlist
-	    #fn(";000n37082E52340q:1710015182K\x8053P:" #(<= nestlist) nestlist)
-	    newline #fn("9000\x8900001000\x8a0000I7070?0421072524D:" #(*output-stream*
+	    negative? #fn("6000n10EL:" #() negative?) nestlist
+	    #fn(":000n37082E52340q:1710015182K\x8053P:" #(<= nestlist) nestlist)
+	    newline #fn("8000\x8900001000\x8a0000I7070?0421072524D:" #(*output-stream*
   #fn(io-write) *linefeed*) newline)
-	    nnn #fn("8000n17021062:" #(count #fn("6000n10VS:" #())) nnn)
-	    nreconc #fn("8000n2701062:" #(reverse!-) nreconc) odd?
-	    #fn("7000n170051S:" #(even?) odd?) positive? #fn("8000n1700E62:" #(>) positive?)
-	    princ #fn("9000|020>7161:" #(#fn("7000n1Ow0421>22>61:" #(*print-readably*
-  #fn("7000n120>21>}0504:" #(#fn("8000n0702192062:" #(for-each #fn(write)))
-			     #fn("7000n1A50420061:" #(#fn(raise)))))
-  #fn("6000n0Aw0:" #(*print-readably*)))) *print-readably*) princ)
-	    print #fn(":000|07021062:" #(for-each #fn(write)) print)
-	    print-exception #fn("=000n10B;3D040<20Q;3:04710r3523I072230T24534757605151@\x0600B;3D040<27Q;3:04710r3523I072287605129534750T51@\xd400B;3D040<2:Q;3:04710r2523?0722;0T2<53@\xac00B;38040<2=Q3B0722>514720=f2@\x8d00B;38040<2?Q3G07@76051514722A0T52@i07B051;3:04710r2523I0750<514722C5142D0T51@>0722E514750514727F61:" #(type-error
+	    nreconc #fn("7000n2701062:" #(reverse!-) nreconc) odd?
+	    #fn("6000n170051S:" #(even?) odd?) positive? #fn("7000n1700E62:" #(>) positive?)
+	    princ #fn("8000|0200>17161:" #(#fn("7000n1Ow0421A>1220>161:" #(*print-readably*
+  #fn("7000n120A>1210>1}0504:" #(#fn("7000n07021A62:" #(for-each #fn(write)))
+				 #fn("6000n1A50420061:" #(#fn(raise)))))
+  #fn("5000n0Aw0:" #(*print-readably*)))) *print-readably*) princ)
+	    print #fn("9000|07021062:" #(for-each #fn(write)) print)
+	    print-exception #fn("<000n10B;3D040<20Q;3:04710r3523I072230T24534757605151@\x0600B;3D040<27Q;3:04710r3523I072287605129534750T51@\xd400B;3D040<2:Q;3:04710r2523?0722;0T2<53@\xac00B;38040<2=Q3B0722>514720=f2@\x8d00B;38040<2?Q3G07@76051514722A0T52@i07B051;3:04710r2523I0750<514722C5142D0T51@>0722E514750514727F61:" #(type-error
   length= princ "type error: expected " ", got " print caddr bounds-error "index "
   " out of bounds for " unbound-error "eval: variable " " has no value" error
-  "error: " load-error print-exception "in file " list? ": " #fn("8000n120051;I5040R37071@4072061:" #(#fn(string?)
+  "error: " load-error print-exception "in file " list? ": " #fn("7000n120051;I5040R37071@4072061:" #(#fn(string?)
   princ print)) "*** Unhandled exception: " *linefeed*) print-exception)
-	    print-stack-trace #fn("8000n120>DD62:" #(#fn(">000n220>?0421>?1422>7374Ar3523F075A76370r5@40r452@30A517778292:2;505252E63:" #(#fn("8000n320>2105182P61:" #(#fn("9000n120A5120F51C>02122230e361:24>25A5161:" #(#fn(function:code)
-  #fn(raise) thrown-value ffound #fn(":000n1E70210515122>~:" #(1- #fn(length)
-							       #fn("9000n170A0G513A0930A0G92191063:D:" #(closure?))))
+	    print-stack-trace #fn("7000n1200>1DD62:" #(#fn("=000n2\x8c0\x8c10200>1_41210>1_4221>17374Ar3523F075A76370r5@40r452@30A517778292:2;505252E63:" #(#fn("8000n32001A>32105182P61:" #(#fn("8000n120A5120F51C>02122230e361:2492F0>325A5161:" #(#fn(function:code)
+  #fn(raise) thrown-value ffound #fn(";000n1E702105151220AF92>4~:" #(1- #fn(length)
+  #fn("8000n170A0G513>0F<A0G929363:D:" #(closure?))))
   #fn(function:vals))) #fn(function:name)) find-in-f)
-  #fn("8000n22021>22}61:" #(#fn(";000n103H0207122237405152255261:26:" #(#fn(symbol)
+  #fn("9000n22021A01>322}61:" #(#fn(":000n103H0207122237405152255261:26:" #(#fn(symbol)
   string-join #fn(map) #fn(string) reverse! "/" λ))
-			    #fn("8000n07021>F524O:" #(for-each #fn("9000n19100Aq63:" #())))
-			    #fn("7000n10B;3B040<20Q;38040T21Q38072061:23061:" #(thrown-value
-  ffound caddr #fn(raise)))) fn-name) #fn("8000n37021>062:" #(for-each #fn("9000n1709110KGF5271051==P51472504902El3?0730KG0EG52@30O4902KMz02:" #(print
+				#fn("8000n07021AF>292524O:" #(for-each #fn("8000n1A<0Fq63:" #())))
+				#fn("6000n10B;3B040<20Q;38040T21Q38072061:23061:" #(thrown-value
+  ffound caddr #fn(raise)))) fn-name) #fn("9000n3\x8c27021A182>3062:" #(for-each
+  #fn("8000n170A<0KGF5271051==P5147250492<El3?0730KG0EG52@30O49292<KM_:" #(print
   vector->list newline disassemble)))) reverse! length> list-tail *interactive*
-  filter closure? #fn(map) #fn("7000n10Z;380420061:" #(#fn(top-level-value)))
+  filter closure? #fn(map) #fn("6000n10Z;380420061:" #(#fn(top-level-value)))
   #fn(environment)))) print-stack-trace)
-	    print-to-string #fn("7000n120>215061:" #(#fn("8000n120A052421061:" #(#fn(write)
+	    print-to-string #fn("6000n1200>1215061:" #(#fn("7000n120A052421061:" #(#fn(write)
   #fn(iostream->string))) #fn(buffer)) print-to-string)
-	    printable? #fn("7000n120051;I80421051S:" #(#fn(iostream?)
+	    printable? #fn("6000n120051;I80421051S:" #(#fn(iostream?)
 						       #fn(eof-object?)) printable?)
-	    quote-value #fn("7000n1700513400:210e2:" #(self-evaluating? quote) quote-value)
-	    quoted? #fn("7000n10<20Q:" #(quote) quoted?) random
-	    #fn("8000n1200513<0712250062:23500i2:" #(#fn(integer?) mod #fn(rand)
+	    quote-value #fn("6000n1700513400:210e2:" #(self-evaluating? quote) quote-value)
+	    quoted? #fn("6000n10<20Q:" #(quote) quoted?) random
+	    #fn("7000n1200513<0712250062:23500i2:" #(#fn(integer?) mod #fn(rand)
 						     #fn(rand-double)) random)
-	    read-all #fn("8000n17021062:" #(read-all-of #fn(read)) read-all)
-	    read-all-of #fn("9000n220>D51q015162:" #(#fn("6000n120>?040:" #(#fn("9000n2209115138071061:A10P9109115162:" #(#fn(io-eof?)
+	    read-all #fn("7000n17021062:" #(read-all-of #fn(read)) read-all)
+	    read-all-of #fn("8000n22010>2D51q015162:" #(#fn("9000n1\x8c0020A0F>3_40<:" #(#fn("8000n220A5138071061:F<10P92A5162:" #(#fn(io-eof?)
   reverse!))))) read-all-of)
-	    ref-int16-LE #fn(";000n2702101EMGE522101KMGr852M61:" #(int16 #fn(ash)) ref-int16-LE)
-	    ref-int32-LE #fn("=000n2702101EMGE522101KMGr8522101r2MGr@522101r3MGrH52g461:" #(int32
+	    ref-int16-LE #fn(":000n2702101EMGE522101KMGr852M61:" #(int16 #fn(ash)) ref-int16-LE)
+	    ref-int32-LE #fn("<000n2702101EMGE522101KMGr8522101r2MGr@522101r3MGrH52g461:" #(int32
   #fn(ash)) ref-int32-LE)
-	    repl #fn("8000n020DD62:" #(#fn("6000n220?0421>?1415047260:" #(#fn("8000n070215142273514242526}61:" #(princ
-  "> " #fn(io-flush) *output-stream* #fn("8000n1207151S;3<04227305161:" #(#fn(io-eof?)
-  *input-stream* #fn("7000n17005140w14D:" #(print that)) load-process))
-  #fn("6000n02060:" #(#fn(read))) #fn("7000n1207151422061:" #(#fn(io-discardbuffer)
+	    repl #fn("7000n020DD62:" #(#fn("8000n2\x8c0\x8c1020_412101>2_41<5047260:" #(#fn("7000n070215142273514242526}61:" #(princ
+  "> " #fn(io-flush) *output-stream* #fn("7000n1207151S;3<04227305161:" #(#fn(io-eof?)
+  *input-stream* #fn("6000n17005140w14D:" #(print that)) load-process))
+  #fn("5000n02060:" #(#fn(read))) #fn("6000n1207151422061:" #(#fn(io-discardbuffer)
 							      *input-stream* #fn(raise)))) prompt)
-  #fn("7000n020>21}3;072504F60:O:" #(#fn("7000n0A50;37047060:" #(newline))
-				     #fn("7000n1700514D:" #(top-level-exception-handler))
-				     newline) reploop) newline))) repl)
-	    revappend #fn("8000n2701062:" #(reverse-) revappend) reverse
-	    #fn("8000n170q062:" #(reverse-) reverse) reverse! #fn("8000n170q062:" #(reverse!-) reverse!)
-	    reverse!- #fn("9000n2D1B3B041=101?04N4?1@\x1d/40:" #() reverse!-)
-	    reverse- #fn("8000n21J400:701<0P1=62:" #(reverse-) reverse-)
-	    self-evaluating? #fn("8000n10H;36040RS;IK0420051;3A040R;3:04021051Q:" #(#fn(constant?)
+  #fn("6000n020A>121}3<072504F<60:O:" #(#fn("6000n0A<50;37047060:" #(newline))
+					#fn("6000n1700514D:" #(top-level-exception-handler))
+					newline) reploop) newline))) repl)
+	    revappend #fn("7000n2701062:" #(reverse-) revappend) reverse
+	    #fn("7000n170q062:" #(reverse-) reverse) reverse! #fn("7000n170q062:" #(reverse!-) reverse!)
+	    reverse!- #fn("8000n2D1B3B041=101?04N4?1@\x1d/40:" #() reverse!-)
+	    reverse- #fn("7000n21J400:701<0P1=62:" #(reverse-) reverse-)
+	    self-evaluating? #fn("7000n10H;36040RS;IK0420051;3A040R;3:04021051Q:" #(#fn(constant?)
   #fn(top-level-value)) self-evaluating?)
-	    separate #fn("7000n220>D61:" #(#fn(":000n120?040AFqe1qe164:" #(#fn(";000n4208283PD1B3Z0401<513?0821<qPN=?2@<0831<qPN=?341=?1@\x05/461:" #(#fn("8000n1700<=0==62:" #(values))) separate-)))) separate)
-	    set-syntax! #fn("9000n220710163:" #(#fn(put!)
+	    separate #fn("7000n22001>2D61:" #(#fn("9000n120?040AFqe1qe164:" #(#fn(":000n4208283PD1B3Z0401<513?0821<qPN=?2@<0831<qPN=?341=?1@\x05/461:" #(#fn("7000n1700<=0==62:" #(values))) separate-)))) separate)
+	    set-syntax! #fn("8000n220710163:" #(#fn(put!)
 						*syntax-environment*) set-syntax!)
-	    simple-sort #fn("7000n10V;I6040=V3400:20>0<61:" #(#fn("8000n17021>22>62:" #(call-with-values
-  #fn("8000n07021>910=62:" #(separate #fn("7000n10AL:" #())))
-  #fn(":000n22071051Ae17115163:" #(#fn(nconc) simple-sort))))) simple-sort)
-	    splice-form? #fn("8000n10B;3X040<20Q;IN040<21Q;ID040<22Q;3:04730r252;I704022Q:" #(unquote-splicing
+	    simple-sort #fn("6000n10V;I6040=V3400:200>10<61:" #(#fn("8000n170210A>2220>162:" #(call-with-values
+  #fn("7000n07021A>1F=62:" #(separate #fn("6000n10AL:" #())))
+  #fn("9000n22071051Ae17115163:" #(#fn(nconc) simple-sort))))) simple-sort)
+	    splice-form? #fn("7000n10B;3X040<20Q;IN040<21Q;ID040<22Q;3:04730r252;I704022Q:" #(unquote-splicing
   unquote-nsplicing unquote length>) splice-form?)
-	    string-join #fn("7000n20J5020:21>225061:" #("" #fn("8000n1200A<5247122>A=52423061:" #(#fn(io-write)
-  for-each #fn("8000n120A91152420A062:" #(#fn(io-write)))
+	    string-join #fn("7000n20J5020:2101>2225061:" #("" #fn("8000n1200A<52471220F>2A=52423061:" #(#fn(io-write)
+  for-each #fn("7000n120AF52420A062:" #(#fn(io-write)))
   #fn(iostream->string))) #fn(buffer)) string-join)
-	    string-lpad #fn(";000n3207182122051\x8052062:" #(#fn(string)
+	    string-lpad #fn(":000n3207182122051\x8052062:" #(#fn(string)
 							     string-rep #fn(string-length)) string-lpad)
-	    string-map #fn("9000n220>21502215162:" #(#fn("7000n220>E51421061:" #(#fn(";000n1D0FL3P0420A910219110525152472051?0@\x0e/:" #(#fn(io-putc)
+	    string-map #fn("8000n22001>221502215162:" #(#fn("9000n22010AF>4E51421061:" #(#fn(":000n1D0AL3N0420F9221930525152472051?0@\x10/:" #(#fn(io-putc)
   #fn(string-char) 1+)) #fn(iostream->string)))
-						     #fn(buffer)
-						     #fn(string-length)) string-map)
-	    string-rep #fn(";000n21r4L3`0701E5235021:1Kl38022061:1r2l390220062:2200063:731513@02207401K\x805262:742200521r2j262:" #(<=
+							#fn(buffer)
+							#fn(string-length)) string-map)
+	    string-rep #fn(":000n21r4L3`0701E5235021:1Kl38022061:1r2l390220062:2200063:731513@02207401K\x805262:742200521r2j262:" #(<=
   "" #fn(string) odd? string-rep) string-rep)
-	    string-rpad #fn("<000n32007182122051\x805262:" #(#fn(string)
+	    string-rpad #fn(";000n32007182122051\x805262:" #(#fn(string)
 							     string-rep #fn(string-length)) string-rpad)
-	    string-tail #fn("8000n2200162:" #(#fn(string-sub)) string-tail)
-	    string-trim #fn("8000n320>DD62:" #(#fn("8000n220>?0421>?1422>23A5161:" #(#fn(":000n48283L;3?042012108252523@0A017282518364:82:" #(#fn(string-find)
-  #fn(string-char) 1+) trim-start) #fn(";000n37082E52;3C0421122073825152523>0F0173825163:82:" #(>
+	    string-tail #fn("7000n2200162:" #(#fn(string-sub)) string-tail)
+	    string-trim #fn("8000n3200182>3DD62:" #(#fn(":000n2\x8c0\x8c10200>1_41211>1_422A0F192>523A5161:" #(#fn("9000n48283L;3?042012108252523A0A<017282518364:82:" #(#fn(string-find)
+  #fn(string-char) 1+) trim-start) #fn(":000n37082E52;3C0421122073825152523?0A<0173825163:82:" #(>
   #fn(string-find) #fn(string-char) 1-) trim-end)
-  #fn("<000n120910A910911E054F91091205363:" #(#fn(string-sub)))
+  #fn(";000n120AF<A92E05493<A9405363:" #(#fn(string-sub)))
   #fn(string-length)))) string-trim)
-	    symbol-syntax #fn("9000n120710O63:" #(#fn(get)
+	    symbol-syntax #fn("8000n120710O63:" #(#fn(get)
 						  *syntax-environment*) symbol-syntax)
-	    table-clone #fn("7000n120>215061:" #(#fn("9000n12021>qA5340:" #(#fn(table-foldl)
-  #fn("9000n320A0163:" #(#fn(put!))))) #fn(table)) table-clone)
-	    table-foreach #fn("9000n22021>q163:" #(#fn(table-foldl)
-						   #fn("8000n3A01524D:" #())) table-foreach)
-	    table-invert #fn("7000n120>215061:" #(#fn("9000n12021>qA5340:" #(#fn(table-foldl)
-  #fn("9000n320A1063:" #(#fn(put!))))) #fn(table)) table-invert)
-	    table-keys #fn("9000n12021q063:" #(#fn(table-foldl)
-					       #fn("7000n3082P:" #())) table-keys)
-	    table-pairs #fn("9000n12021q063:" #(#fn(table-foldl)
-						#fn("7000n301P82P:" #())) table-pairs)
-	    table-values #fn("9000n12021q063:" #(#fn(table-foldl)
-						 #fn("7000n3182P:" #())) table-values)
-	    to-proper #fn("8000n10J400:0H3600e1:0<700=51P:" #(to-proper) to-proper)
-	    top-level-exception-handler #fn("7000n120>7161:" #(#fn("7000n170w1422>23>61:" #(*stderr*
-  *output-stream* #fn("7000n120>21>}0504:" #(#fn("7000n07092051471225061:" #(print-exception
-  print-stack-trace #fn(stacktrace))) #fn("7000n1A50420061:" #(#fn(raise)))))
-  #fn("6000n0Aw0:" #(*output-stream*)))) *output-stream*) top-level-exception-handler)
-	    trace #fn("8000n120>2105151422:" #(#fn("7000n120>215061:" #(#fn("@000n170A51Ie0219107223024252627910e20e3e228e12927Ae20e3e4e35162:D:" #(traced?
+	    table-clone #fn("6000n1200>1215061:" #(#fn("8000n120210>1qA5340:" #(#fn(table-foldl)
+  #fn("8000n320A0163:" #(#fn(put!))))) #fn(table)) table-clone)
+	    table-foreach #fn("8000n220210>1q163:" #(#fn(table-foldl)
+						     #fn("7000n3A01524D:" #())) table-foreach)
+	    table-invert #fn("6000n1200>1215061:" #(#fn("8000n120210>1qA5340:" #(#fn(table-foldl)
+  #fn("8000n320A1063:" #(#fn(put!))))) #fn(table)) table-invert)
+	    table-keys #fn("8000n12021q063:" #(#fn(table-foldl)
+					       #fn("6000n3082P:" #())) table-keys)
+	    table-pairs #fn("8000n12021q063:" #(#fn(table-foldl)
+						#fn("6000n301P82P:" #())) table-pairs)
+	    table-values #fn("8000n12021q063:" #(#fn(table-foldl)
+						 #fn("6000n3182P:" #())) table-values)
+	    to-proper #fn("7000n10J400:0H3600e1:0<700=51P:" #(to-proper) to-proper)
+	    top-level-exception-handler #fn("6000n1200>17161:" #(#fn("7000n170w1422A>1230>161:" #(*stderr*
+  *output-stream* #fn("7000n120A>1210>1}0504:" #(#fn("6000n070A51471225061:" #(print-exception
+  print-stack-trace #fn(stacktrace))) #fn("6000n1A50420061:" #(#fn(raise)))))
+  #fn("5000n0Aw0:" #(*output-stream*)))) *output-stream*) top-level-exception-handler)
+	    trace #fn("7000n1200>12105151422:" #(#fn("7000n1200A>2215061:" #(#fn("?000n170A51Ia021F7223024252627Fe20e3e228e12927Ae20e3e4e35162:D:" #(traced?
   #fn(set-top-level-value!) eval λ begin write cons quote newline apply))
   #fn(gensym))) #fn(top-level-value) ok) trace)
-	    traced? #fn("8000n170051;3>042105121A51d:" #(closure? #fn(function:code)) #(#fn(":000|020210P51472504230\x7f2:" #(#fn(write)
-  x newline #.apply)) ()))
-	    untrace #fn("8000n120>2105161:" #(#fn("9000n1700513@021A22051r2G62:D:" #(traced?
+	    traced? #fn("7000n170051;3?042105121A<51d:" #(closure? #fn(function:code)) #((#fn("9000|020210P51472504230\x7f2:" #(#fn(write)
+  x newline #.apply)))))
+	    untrace #fn("7000n1200>12105161:" #(#fn("8000n1700513@021A22051r2G62:D:" #(traced?
   #fn(set-top-level-value!) #fn(function:vals)))
-					      #fn(top-level-value)) untrace)
-	    values #fn("9000|00B;36040=V3500<:A0P:" #() #1#) vector->list
-	    #fn("8000n120>21051q62:" #(#fn(":000n2K020>~41:" #(#fn("8000n1910A0\x80GFPz01:" #())))
-				       #fn(length)) vector->list)
-	    vector-map #fn("8000n220>2115161:" #(#fn("8000n120>2105161:" #(#fn(":000n1EAK\x8020>~40:" #(#fn(":000n1A09209210G51p:" #())))
+						#fn(top-level-value)) untrace)
+	    values #fn("8000|00B;36040=V3500<:A0P:" #() #(#1#)) vector->list
+	    #fn("7000n1200>121051q62:" #(#fn(":000n2\x8c1K0201A0>3~41<:" #(#fn("8000n1AF920\x80GA<P_:" #())))
+					 #fn(length)) vector->list)
+	    vector-map #fn("7000n22001>22115161:" #(#fn("8000n1200AF>32105161:" #(#fn(":000n1EAK\x80200F92>3~40:" #(#fn("9000n1A0F920G51p:" #())))
   #fn(vector-alloc))) #fn(length)) vector-map)
-	    void #fn("6000n0D:" #() void) zero?
-	    #fn("7000n10El:" #() zero?))
+	    vinfo #fn("7000n30182e3:" #() vinfo) vinfo:heap? #.cadr vinfo:index
+	    #2# vinfo:sym #.car void
+	    #fn("5000n0D:" #() void) zero? #fn("6000n10El:" #() zero?))
--- a/flisp.c
+++ b/flisp.c
@@ -451,8 +451,8 @@
 		FL(lim) = FL(curheap)+FL(heapsize)-sizeof(cons_t);
 
 	if(FL(throwing_frame) > FL(curr_frame)){
-		top = FL(throwing_frame) - 4;
-		f = FL(stack)[FL(throwing_frame)-4];
+		top = FL(throwing_frame) - 3;
+		f = FL(stack)[FL(throwing_frame)-3];
 	}else{
 		top = FL(sp);
 		f = FL(curr_frame);
@@ -462,8 +462,8 @@
 			FL(stack)[i] = relocate(FL(stack)[i]);
 		if(f == 0)
 			break;
-		top = f - 4;
-		f = FL(stack)[f-4];
+		top = f - 3;
+		f = FL(stack)[f-3];
 	}
 	for(i = 0; i < FL(ngchandles); i++)
 		*FL(gchandles)[i] = relocate(*FL(gchandles)[i]);
@@ -754,9 +754,8 @@
 	value_t args[64], v = FL(Nil);
 	uint32_t i, a = 0, nrestargs;
 	value_t s1 = FL(stack)[FL(sp)-1];
-	value_t s2 = FL(stack)[FL(sp)-2];
+	value_t s3 = FL(stack)[FL(sp)-3];
 	value_t s4 = FL(stack)[FL(sp)-4];
-	value_t s5 = FL(stack)[FL(sp)-5];
 	if(__unlikely(nargs < nreq))
 		lerrorf(FL(ArgError), "too few arguments");
 	if(__unlikely(extr > nelem(args)))
@@ -807,11 +806,10 @@
 		memmove(&FL(stack)[bp+ntot], &FL(stack)[bp+i], nrestargs*sizeof(value_t));
 	memmove(&FL(stack)[bp+nreq], args, extr*sizeof(value_t));
 	FL(sp) = bp + nargs;
-	assert(FL(sp) < FL(nstack)-5);
-	PUSH(s5);
+	assert(FL(sp) < FL(nstack)-4);
 	PUSH(s4);
+	PUSH(s3);
 	PUSH(nargs);
-	PUSH(s2);
 	PUSH(s1);
 	FL(curr_frame) = FL(sp);
 	return nargs;
@@ -853,8 +851,7 @@
 {
 	uint32_t top_frame = FL(curr_frame);
 	// frame variables
-	uint32_t n, captured;
-	uint32_t bp;
+	uint32_t n, bp;
 	const uint8_t *ip;
 	fixnum_t s, hi;
 	int tail, x;
@@ -873,7 +870,6 @@
 	USED(n);
 	USED(v);
 apply_cl_top:
-	captured = 0;
 	func = FL(stack)[FL(sp)-nargs-1];
 	ip = cvalue_data(fn_bcode(func));
 	assert(!ismanaged((uintptr_t)ip));
@@ -888,7 +884,6 @@
 	PUSH(nargs);
 	ipd = FL(sp);
 	FL(sp)++; // ip
-	PUSH(0); // captured?
 	FL(curr_frame) = FL(sp);
 
 #if defined(COMPUTED_GOTO)
@@ -915,12 +910,12 @@
 		GOTO_OP_OFFSET(OP_CLOSURE),
 		GOTO_OP_OFFSET(OP_SETA),
 		GOTO_OP_OFFSET(OP_JMP),
-		GOTO_OP_OFFSET(OP_LOADC00),
+		GOTO_OP_OFFSET(OP_LOADC0),
 		GOTO_OP_OFFSET(OP_PAIRP),
 		GOTO_OP_OFFSET(OP_BRNE),
 		GOTO_OP_OFFSET(OP_LOADT),
 		GOTO_OP_OFFSET(OP_LOAD0),
-		GOTO_OP_OFFSET(OP_LOADC01),
+		GOTO_OP_OFFSET(OP_LOADC1),
 		GOTO_OP_OFFSET(OP_AREF),
 		GOTO_OP_OFFSET(OP_ATOMP),
 		GOTO_OP_OFFSET(OP_BRT),
@@ -990,6 +985,8 @@
 		GOTO_OP_OFFSET(OP_OPTARGS),
 		GOTO_OP_OFFSET(OP_BRBOUND),
 		GOTO_OP_OFFSET(OP_KEYARGS),
+		GOTO_OP_OFFSET(OP_BOX),
+		GOTO_OP_OFFSET(OP_BOXL),
 	};
 	NEXT_OP;
 #else
@@ -1000,11 +997,11 @@
 		switch(op){
 #endif
 		OP(OP_LOADA0)
-			PUSH(captured ? vector_elt(FL(stack)[bp], 0) : FL(stack)[bp]);
+			PUSH(FL(stack)[bp]);
 			NEXT_OP;
 
 		OP(OP_LOADA1)
-			PUSH(captured ? vector_elt(FL(stack)[bp], 1) : FL(stack)[bp+1]);
+			PUSH(FL(stack)[bp+1]);
 			NEXT_OP;
 
 		OP(OP_LOADV)
@@ -1044,7 +1041,7 @@
 			if(tag(func) == TAG_FUNCTION){
 				if(func > (N_BUILTINS<<3)){
 					if(tail){
-						FL(curr_frame) = FL(stack)[FL(curr_frame)-4];
+						FL(curr_frame) = FL(stack)[FL(curr_frame)-3];
 						for(s = -1; s < (fixnum_t)n; s++)
 							FL(stack)[bp+s] = FL(stack)[FL(sp)-n+s];
 						FL(sp) = bp+n;
@@ -1113,46 +1110,51 @@
 		OP(OP_LOADA)
 			assert(nargs > 0);
 			i = *ip++;
-			if(captured){
-				e = FL(stack)[bp];
-				assert(isvector(e));
-				assert(i < vector_size(e));
-				v = vector_elt(e, i);
-			}else{
-				v = FL(stack)[bp+i];
-			}
+			v = FL(stack)[bp+i];
 			PUSH(v);
 			NEXT_OP;
 
 		OP(OP_LOADC)
-			s = *ip++;
 			i = *ip++;
 			v = FL(stack)[bp+nargs];
-			while(s--)
-				v = vector_elt(v, vector_size(v)-1);
 			assert(isvector(v));
 			assert(i < vector_size(v));
 			PUSH(vector_elt(v, i));
 			NEXT_OP;
 
+		OP(OP_BOX)
+			i = *ip++;
+			v = mk_cons();
+			car_(v) = FL(stack)[bp+i];
+			cdr_(v) = FL(Nil);
+			FL(stack)[bp+i] = v;
+			NEXT_OP;
+
+		OP(OP_BOXL)
+			i = GET_INT32(ip); ip += 4;
+			v = mk_cons();
+			car_(v) = FL(stack)[bp+i];
+			cdr_(v) = FL(Nil);
+			FL(stack)[bp+i] = v;
+			NEXT_OP;
+
 		OP(OP_RET)
 			v = POP();
 			FL(sp) = FL(curr_frame);
-			FL(curr_frame) = FL(stack)[FL(sp)-4];
+			FL(curr_frame) = FL(stack)[FL(sp)-3];
 			if(FL(curr_frame) == top_frame)
 				return v;
-			FL(sp) -= 5+nargs;
-			captured = FL(stack)[FL(curr_frame)-1];
-			ipd = FL(curr_frame)-2;
+			FL(sp) -= 4+nargs;
+			ipd = FL(curr_frame)-1;
 			ip = (uint8_t*)FL(stack)[ipd];
-			nargs = FL(stack)[FL(curr_frame)-3];
-			bp = FL(curr_frame) - 5 - nargs;
+			nargs = FL(stack)[FL(curr_frame)-2];
+			bp = FL(curr_frame) - 4 - nargs;
 			FL(stack)[FL(sp)-1] = v;
 			NEXT_OP;
 
 		OP(OP_DUP)
+			FL(stack)[FL(sp)] = FL(stack)[FL(sp)-1];
 			FL(sp)++;
-			FL(stack)[FL(sp)-1] = FL(stack)[FL(sp)-2];
 			NEXT_OP;
 
 		OP(OP_CAR)
@@ -1174,25 +1176,18 @@
 			NEXT_OP;
 
 		OP(OP_CLOSURE)
-			// build a closure (lambda args body . env)
-			if(nargs > 0 && !captured){
-				// save temporary environment to the heap
-				n = nargs;
-				pv = alloc_words(n + 2);
-				PUSH(tagptr(pv, TAG_VECTOR));
-				pv[0] = fixnum(n+1);
-				pv++;
-				do{
-					pv[n] = FL(stack)[bp+n];
-				}while(n--);
-				// environment representation changed; install
-				// the new representation so everybody can see it
-				captured = 1;
-				FL(stack)[FL(curr_frame)-1] = 1;
-				FL(stack)[bp] = FL(stack)[FL(sp)-1];
-			}else{
-				PUSH(FL(stack)[bp]); // env has already been captured; share
-			}
+			n = *ip++;
+			assert(n > 0);
+			pv = alloc_words(n + 1);
+			v = tagptr(pv, TAG_VECTOR);
+			i = 0;
+			pv[i++] = fixnum(n);
+			do{
+				pv[i] = FL(stack)[FL(sp)-n + i-1];
+				i++;
+			}while(i <= n);
+			POPN(n);
+			PUSH(v);
 			if(__unlikely((value_t*)FL(curheap) > (value_t*)FL(lim)-2))
 				gc(0);
 			pv = (value_t*)FL(curheap);
@@ -1211,14 +1206,7 @@
 			assert(nargs > 0);
 			v = FL(stack)[FL(sp)-1];
 			i = *ip++;
-			if(captured){
-				e = FL(stack)[bp];
-				assert(isvector(e));
-				assert(i < vector_size(e));
-				vector_elt(e, i) = v;
-			}else{
-				FL(stack)[bp+i] = v;
-			}
+			FL(stack)[bp+i] = v;
 			NEXT_OP;
 
 		OP(OP_JMP)
@@ -1225,7 +1213,7 @@
 			ip += GET_INT16(ip);
 			NEXT_OP;
 
-		OP(OP_LOADC00)
+		OP(OP_LOADC0)
 			PUSH(vector_elt(FL(stack)[bp+nargs], 0));
 			NEXT_OP;
 
@@ -1246,7 +1234,7 @@
 			PUSH(fixnum(0));
 			NEXT_OP;
 
-		OP(OP_LOADC01)
+		OP(OP_LOADC1)
 			PUSH(vector_elt(FL(stack)[bp+nargs], 1));
 			NEXT_OP;
 
@@ -1697,7 +1685,7 @@
 			assert(nargs > 0);
 			i = GET_INT32(ip);
 			ip += 4;
-			v = captured ? vector_elt(FL(stack)[bp], i) : FL(stack)[bp+i];
+			v = FL(stack)[bp+i];
 			PUSH(v);
 			NEXT_OP;
 
@@ -1706,10 +1694,7 @@
 			v = FL(stack)[FL(sp)-1];
 			i = GET_INT32(ip);
 			ip += 4;
-			if(captured)
-				vector_elt(FL(stack)[bp], i) = v;
-			else
-				FL(stack)[bp+i] = v;
+			FL(stack)[bp+i] = v;
 			NEXT_OP;
 
 		OP(OP_SETC)
@@ -1724,13 +1709,9 @@
 			NEXT_OP;
 
 		OP(OP_LOADCL)
-			s = GET_INT32(ip);
-			ip += 4;
 			i = GET_INT32(ip);
 			ip += 4;
 			v = FL(stack)[bp+nargs];
-			while(s--)
-				v = vector_elt(v, vector_size(v)-1);
 			PUSH(vector_elt(v, i));
 			NEXT_OP;
 
@@ -1761,9 +1742,8 @@
 					FL(stack)[bp+i+1] = FL(stack)[bp+nargs+0];
 					FL(stack)[bp+i+2] = FL(stack)[bp+nargs+1];
 					FL(stack)[bp+i+3] = i+1;
-					//FL(stack)[bp+i+4] = 0;
-					FL(stack)[bp+i+5] = 0;
-					FL(sp) =  bp+i+6;
+					FL(stack)[bp+i+4] = 0;
+					FL(sp) =  bp+i+5;
 					FL(curr_frame) = FL(sp);
 				}
 			}else if(__unlikely(s < 0)){
@@ -1770,14 +1750,14 @@
 				FL(stack)[ipd] = (uintptr_t)ip;
 				lerrorf(FL(ArgError), "too few arguments");
 			}else{
-				PUSH(0);
-				FL(stack)[FL(sp)-3] = i+1;
+				FL(sp)++;
+				FL(stack)[FL(sp)-2] = i+1;
+				FL(stack)[FL(sp)-3] = FL(stack)[FL(sp)-4];
 				FL(stack)[FL(sp)-4] = FL(stack)[FL(sp)-5];
-				FL(stack)[FL(sp)-5] = FL(stack)[FL(sp)-6];
-				FL(stack)[FL(sp)-6] = FL(Nil);
+				FL(stack)[FL(sp)-5] = FL(Nil);
 				FL(curr_frame) = FL(sp);
 			}
-			ipd = FL(sp)-2;
+			ipd = FL(sp)-1;
 			nargs = i+1;
 			NEXT_OP;
 
@@ -1808,12 +1788,11 @@
 				n -= nargs;
 				FL(sp) += n;
 				FL(stack)[FL(sp)-1] = FL(stack)[FL(sp)-n-1];
-				FL(stack)[FL(sp)-2] = FL(stack)[FL(sp)-n-2];
-				FL(stack)[FL(sp)-3] = nargs+n;
+				FL(stack)[FL(sp)-2] = nargs+n;
+				FL(stack)[FL(sp)-3] = FL(stack)[FL(sp)-n-3];
 				FL(stack)[FL(sp)-4] = FL(stack)[FL(sp)-n-4];
-				FL(stack)[FL(sp)-5] = FL(stack)[FL(sp)-n-5];
 				FL(curr_frame) = FL(sp);
-				ipd = FL(sp)-2;
+				ipd = FL(sp)-1;
 				for(i = 0; i < n; i++)
 					FL(stack)[bp+nargs+i] = UNBOUND;
 				nargs += n;
@@ -1823,7 +1802,7 @@
 		OP(OP_BRBOUND)
 			i = GET_INT32(ip);
 			ip += 4;
-			v = captured ? vector_elt(FL(stack)[bp], i) : FL(stack)[bp+i];
+			v = FL(stack)[bp+i];
 			PUSH(v != UNBOUND ? FL(t) : FL(f));
 			NEXT_OP;
 
@@ -1884,9 +1863,9 @@
 
 	fl_gc_handle(&lst);
 	while(top > 0){
-		const uint8_t *ip1 = (void*)FL(stack)[top-2];
-		uint32_t sz = FL(stack)[top-3]+1;
-		uint32_t bp = top-5-sz;
+		const uint8_t *ip1 = (void*)FL(stack)[top-1];
+		uint32_t sz = FL(stack)[top-2]+1;
+		uint32_t bp = top-4-sz;
 		value_t func = FL(stack)[bp];
 		const uint8_t *ip0 = cvalue_data(fn_bcode(func));
 		intptr_t ip = ip1 - ip0 - 1; /* -1: ip1 is *after* the one that was being executed */
@@ -1893,19 +1872,14 @@
 		value_t v = alloc_vector(sz+1, 0);
 		vector_elt(v, 0) = fixnum(ip);
 		vector_elt(v, 1) = func;
-		if(FL(stack)[top-1] /*captured*/){
-			memmove(&vector_elt(v, 2),
-				   &vector_elt(FL(stack)[bp+1], 0), (sz-1)*sizeof(value_t));
-		}else{
-			for(uint32_t i = 1; i < sz; i++){
-				value_t si = FL(stack)[bp+i];
-				// if there's an error evaluating argument defaults some slots
-				// might be left set to UNBOUND (issue #22)
-				vector_elt(v, i+1) = si == UNBOUND ? FL(unspecified) : si;
-			}
+		for(uint32_t i = 1; i < sz; i++){
+			value_t si = FL(stack)[bp+i];
+			// if there's an error evaluating argument defaults some slots
+			// might be left set to UNBOUND (issue #22)
+			vector_elt(v, i+1) = si == UNBOUND ? FL(unspecified) : si;
 		}
 		lst = fl_cons(v, lst);
-		top = FL(stack)[top-4];
+		top = FL(stack)[top-3];
 	}
 	fl_free_gc_handles(1);
 	return lst;
--- a/gen.lsp
+++ b/gen.lsp
@@ -17,12 +17,12 @@
     OP_CLOSURE        closure   #f      0
     OP_SETA           seta      #f      0
     OP_JMP            jmp       #f      0
-    OP_LOADC00        loadc00   #f      0
+    OP_LOADC0         loadc0    #f      0
     OP_PAIRP          pair?     1       (λ (x) (pair? x))
     OP_BRNE           brne      #f      0
     OP_LOADT          loadt     #f      0
     OP_LOAD0          load0     #f      0
-    OP_LOADC01        loadc01   #f      0
+    OP_LOADC1         loadc1    #f      0
     OP_AREF           aref      2       (λ (x y) (aref x y))
     OP_ATOMP          atom?     1       (λ (x) (atom? x))
     OP_BRT            brt       #f      0
@@ -92,6 +92,8 @@
     OP_OPTARGS        optargs   #f      0
     OP_BRBOUND        brbound   #f      0
     OP_KEYARGS        keyargs   #f      0
+    OP_BOX            box       #f      0
+    OP_BOXL           box.l     #f      0
     OP_BOOL_CONST_F   dummy_f   #f      0
     OP_BOOL_CONST_T   dummy_t   #f      0
     OP_THE_EMPTY_LIST dummy_nil #f      0
--- a/maxstack.inc
+++ b/maxstack.inc
@@ -15,8 +15,8 @@
 		case OP_LOADA0: case OP_LOADA1:
 		case OP_DUP: case OP_LOADT: case OP_LOADF: case OP_LOADNIL:
 		case OP_LOAD0:
-		case OP_LOAD1: case OP_LOADC00:
-		case OP_LOADC01:
+		case OP_LOAD1: case OP_LOADC0:
+		case OP_LOADC1:
 			sp++;
 			break;
 
@@ -34,11 +34,11 @@
 			sp--;
 			break;
 
-		case OP_ARGC: case OP_SETG: case OP_SETA:
+		case OP_ARGC: case OP_SETG: case OP_SETA: case OP_BOX:
 			ip++;
 			break;
 
-		case OP_TCALL: case OP_CALL:
+		case OP_TCALL: case OP_CALL: case OP_CLOSURE:
 			n = *ip++;  // nargs
 			sp -= n;
 			break;
@@ -51,9 +51,8 @@
 			break;
 
 		case OP_LOADC:
-			sp++; // fallthrough
-		case OP_SETC:
-			ip += 2;
+			sp++;
+			ip++;
 			break;
 
 		case OP_VARGC:
@@ -137,14 +136,11 @@
 
 		case OP_LOADCL:
 			sp++; // fallthrough
-		case OP_SETCL:
 			SWAP_INT32(ip);
 			ip += 4;
-			SWAP_INT32(ip);
-			ip += 4;
 			break;
 		}
 	}
 	assert(ip == end);
-	return maxsp+5;
+	return maxsp+4;
 }
--- a/mkboot1.lsp
+++ b/mkboot1.lsp
@@ -1,5 +1,7 @@
 ; -*- scheme -*-
 
+(load "builtins.lsp")
+(load "instructions.lsp")
 (load "system.lsp")
 (load "compiler.lsp")
 (make-system-image "flisp.boot")
--- a/opcodes.h
+++ b/opcodes.h
@@ -16,12 +16,12 @@
 	OP_CLOSURE,
 	OP_SETA,
 	OP_JMP,
-	OP_LOADC00,
+	OP_LOADC0,
 	OP_PAIRP,
 	OP_BRNE,
 	OP_LOADT,
 	OP_LOAD0,
-	OP_LOADC01,
+	OP_LOADC1,
 	OP_AREF,
 	OP_ATOMP,
 	OP_BRT,
@@ -91,6 +91,8 @@
 	OP_OPTARGS,
 	OP_BRBOUND,
 	OP_KEYARGS,
+	OP_BOX,
+	OP_BOXL,
 	OP_BOOL_CONST_F,
 	OP_BOOL_CONST_T,
 	OP_THE_EMPTY_LIST,