shithub: femtolisp

Download patch

ref: 7392b1c634dd3137b04ada6f6aa2824f34997ec0
parent: cace583970f7f5c50f40cd796bc7b60fbb5d5409
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Mon Dec 2 21:59:53 EST 2024

compiler: "if": fold dup+brf+pop when not caring about the final result with "and"

--- a/compiler.lsp
+++ b/compiler.lsp
@@ -250,7 +250,8 @@
 ;; control flow
 
 (define (compile-if g env tail? x)
-  (let ((elsel (make-label g))
+  (let ((thenl (make-label g))
+        (elsel (make-label g))
         (endl  (make-label g))
         (test  (cadr x))
         (then  (caddr x))
@@ -262,8 +263,9 @@
           ((eq? test #f)
            (compile-in g env tail? else))
           (else
-           (compile-in g env #f test)
+           (compile-in g env #f test elsel)
            (emit g 'brf elsel)
+           (mark-label g thenl)
            (compile-in g env tail? then)
            (if tail?
                (emit g 'ret)
@@ -314,24 +316,24 @@
        (pair? (cadr func))
        (length= (cadr func) 1)))
 
-(define (compile-short-circuit g env tail? forms default branch)
-  (cond ((atom? forms)        (compile-in g env tail? default))
-        ((atom? (cdr forms))  (compile-in g env tail? (car forms)))
+(define (compile-short-circuit g env tail? forms default branch outl)
+  (cond ((atom? forms)        (compile-in g env tail? default outl))
+        ((atom? (cdr forms))  (compile-in g env tail? (car forms) outl))
         (else
-         (let ((end  (make-label g)))
-           (compile-in g env #f (car forms))
+         (let ((end (or outl (make-label g))))
+           (compile-in g env #f (car forms) outl)
            (bcode:stack g 1)
-           (emit g 'dup)
+           (unless outl (emit g 'dup))
            (emit g branch end)
            (bcode:stack g -1)
-           (emit g 'pop)
-           (compile-short-circuit g env tail? (cdr forms) default branch)
-           (mark-label g end)))))
+           (unless outl (emit g 'pop))
+           (compile-short-circuit g env tail? (cdr forms) default branch outl)
+           (unless outl (mark-label g end))))))
 
-(define (compile-and g env tail? forms)
-  (compile-short-circuit g env tail? forms #t 'brf))
+(define (compile-and g env tail? forms outl)
+  (compile-short-circuit g env tail? forms #t 'brf outl))
 (define (compile-or g env tail? forms)
-  (compile-short-circuit g env tail? forms #f 'brt))
+  (compile-short-circuit g env tail? forms #f 'brt #f))
 
 ;; calls
 
@@ -461,7 +463,7 @@
 
 (define (fits-i8 x) (and (fixnum? x) (>= x -128) (<= x 127)))
 
-(define (compile-in g env tail? x)
+(define (compile-in g env tail? x (outl #f))
   (cond ((symbol? x) (compile-sym g env x #t))
         ((atom? x)
          (cond ((eq? x 0)   (emit g 'load0))
@@ -491,7 +493,7 @@
                                                 (compile-sym g env var #f))
                                               cenv)
                                     (emit g 'closure (length cenv)))))))
-           (and      (compile-and g env tail? (cdr x)))
+           (and      (compile-and g env tail? (cdr x) outl))
            (or       (compile-or  g env tail? (cdr x)))
            (while    (compile-while g env (cadr x) (cons 'begin (cddr x))))
            (return   (compile-in g env #t (cadr x))
--- a/flisp.boot
+++ b/flisp.boot
@@ -87,9 +87,9 @@
 	    bq-bracket #fn(";000n20H3=070710152e2:0<22CR01El380700=P:707324710=1K~52e3e2:0<25CS01El390260Te2:707027710T1K~52e3e2:0<28CO01El3500T:707029710T1K~52e3e2:70710152e2:" #(list
   bq-process unquote cons 'unquote unquote-splicing copy-list 'unquote-splicing
   unquote-nsplicing 'unquote-nsplicing) bq-bracket)
-	    bq-bracket1 #fn(":000n20B;38040<20Q3K01El3500T:7122730=1K~52e3:730162:" #(unquote
+	    bq-bracket1 #fn(":000n20B3R00<20CK01El3500T:7122730=1K~52e3:730162:" #(unquote
   cons 'unquote bq-process) bq-bracket1)
-	    bq-process #fn("<000n20R380200e2:0]3T0717205115286<73C907486=P:757486e3:0H3400:0<26CB07327710T1KM52e3:0<28CW01El;3:04790r2523500T:7:2;710=1K~52e3:7<7=052It07>0512?2@1>105286J807387P:87=JA07:87<7186152e3:2A7B87P7186152e162:D\x8a6862C186>2_486<^10q62:" #(quote
+	    bq-process #fn("<000n20R380200e2:0]3T0717205115286<73C907486=P:757486e3:0H3400:0<26CB07327710T1KM52e3:0<28CU01El3?0790r2523500T:7:2;710=1K~52e3:7<7=052It07>0512?2@1>105286J807387P:87=JA07:87<7186152e3:2A7B87P7186152e162:D\x8a6862C186>2_486<^10q62:" #(quote
   bq-process vector->list list vector apply quasiquote 'quasiquote unquote
   length= cons 'unquote any splice-form? lastcdr #fn(map)
   #fn("7000n1700A62:" #(bq-bracket1)) #fn(nconc) list* #fn("=000n20J;02071151P:0B3n00<22CW020731AEl3700=@C07425e2760=AK~52e252P:F<0=770<A521P62:2071760A521P51P:" #(nconc
@@ -104,7 +104,7 @@
 	    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("7000n205086B;3804A86<Q390186=}2:18661:" #() #(#1=(*values*)))
+	    #fn("7000n205086B3@0A86<C90186=}2:18661:" #() #(#1=(*values*)))
 	    capture-var! #fn("<000n27005171186E5387;IG042286510r323861e152p4:" #(bcode:cenv
   index-of #fn(length) #fn(nconc)) capture-var!)
 	    cdaaar #fn("5000n10<<<=:" #() cdaaar) cdaadr
@@ -120,8 +120,9 @@
   rune) char?)
 	    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("E000n483<88R;3O047088152S;3B0488Z;3:04218851[3;0218851@40887283=23523i07401O89544750K524760183=537508:U5247708237028@40298:63:89[;39047:8951892;Q;3V047089152S;3I04212;517;d;3;047<83r2523E07401O83T5447702;62:89B;3E047=89<51;39047>83513=07?01828364:8:IE07401O89544750K52@30D4760183=537508;U5248:I<0750r/52@30D48:3C07@018283898:8;67:770823702A@402B8;63:" #(in-env?
+	    compile-and #fn("<000n570018283D218467:" #(compile-short-circuit
+						       brf) compile-and)
+	    compile-app #fn("E000n483<88R3U07088152IK088Z3E0218851[3;0218851@40887283=23523i07401O89544750K524760183=537508:U5247708237028@40298:63:89[;39047:8951892;Cf07089152I\\0212;517;d3P07<83r2523E07401O83T5447702;62:89B3P07=89<513F07>83513=07?01828364:8:IE07401O89544750K52@30D4760183=537508;U5248:I<0750r/52@30D48:3C07@018283898:8;67:770823702A@402B8;63:" #(in-env?
   #fn(top-level-value) length> 255 compile-in bcode:stack compile-arglist emit
   tcall.l call.l builtin->instruction cadr length= is-lambda? inlineable?
   compile-let compile-builtin-call tcall call) compile-app)
@@ -130,7 +131,7 @@
   bcode:stack)) #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("<000n7207185O538;;3=047283=8;52S3=073858;52@30D4858<24CK086El3:07502662:750858663:8<27C[086El3:07502862:86r2l3:07502962:750858663:8<2:Cj086El3:07385K62:86Kl3:07502;62:86r2l3:07502<62:750858663:8<2=CK086El3:07502>62:750858663:8<2?CK086El3:07385K62:750858663:8<2@CM086El3<07502A2B63:750858663:8<2CCW086r2L3;07385r262:750823702D@402C8663:7508562:" #(#fn(get)
+	    compile-builtin-call #fn("<000n7207185O538;3I07283=8;52I=073858;52@30D4858<24CK086El3:07502662:750858663:8<27C[086El3:07502862:86r2l3:07502962:750858663:8<2:Cj086El3:07385K62:86Kl3:07502;62:86r2l3:07502<62:750858663:8<2=CK086El3:07502>62:750858663:8<2?CK086El3:07385K62:750858663:8<2@CM086El3<07502A2B63:750858663:8<2CCW086r2L3;07385r262:750823702D@402C8663:7508562:" #(#fn(get)
   arg-counts length= argc-error list emit loadnil + load0 add2 - neg sub2 *
   load1 / vector loadv #() apply tapply) compile-builtin-call)
 	    compile-f #fn("8000n2702101>22262:" #(call-with-values #fn("7000n070AF62:" #(compile-f-))
@@ -141,9 +142,9 @@
   emit-optional-arg-inits > 255 largc lvargc vargc argc extend-env
   complex-bindings lambda:body box-vars compile-in ret values #fn(function)
   encode-byte-code bcode:code const-to-idx-vec bcode:cenv) compile-f-)
-	    compile-if #fn("@000n4700517005183T718351728351B3;0738351@6074508:DC=07501828;64:8:OC=07501828<64:7501O8:54476027885347501828;544823<07602852@;076029895347:0885247501828<5447:08962:" #(make-label
-  caddr cdddr cadddr void compile-in emit brf ret jmp mark-label) compile-if)
-	    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:83<882@CS07A83T513>07:018283T64:7102=83T63:882BC=07C01828364:882DC>07E018283=64:882FC;07G018363:882HCD07I2J183>22K01>262:882LC>07M018283=64:882NC>07O018283=64:882PCE07Q0183T2D7R8351P64:882SCE07:01D83T5447102T62:882UCT083TR360O@807V2W5147X0183T7Y835164:882ZCp07:01O2Hq83Te35447[7Y835151360O@807V2\\5147:01O7Y83515447102Z62:7?01828364:" #(compile-sym
+	    compile-if #fn("A000n470051700517005183T718351728351B3;0738351@6074508;DC=07501828<64:8;OC=07501828=64:7501O8;895547602789534780885247501828<544823<07602952@;07602:8:534780895247501828=5447808:62:" #(make-label
+  caddr cdddr cadddr void compile-in emit brf mark-label ret jmp) compile-if)
+	    compile-in #fn(">000\x8740005000\x884000I60O?4483R3<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:83<892@CS07A83T513>07:018283T64:7102=83T63:892BC=07C01828364:892DC>07E018283=64:892FC;07G018363:892HCD07I2J183>22K01>262:892LC@07M018283=8465:892NC>07O018283=64:892PCE07Q0183T2D7R8351P64:892SCE07:01D83T5447102T62:892UCT083TR360O@807V2W5147X0183T7Y835164:892ZCp07:01O2Hq83Te35447[7Y835151360O@807V2\\5147:01O7Y83515447102Z62:7?01828364:" #(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 quote
   self-evaluating? if compile-if begin compile-begin prog1 compile-prog1 λ
@@ -154,18 +155,18 @@
   and compile-and or compile-or while compile-while cddr return ret set! error
   "set!: second argument must be a symbol" compile-set! caddr trycatch
   1arg-lambda? "trycatch: second form must be a 1-argument lambda") compile-in)
-	    compile-let #fn("A000n483<83=7005188T71018953728;737488518;528:537508=524268=1<521=P7708>827488515447808<U524798<E52;360482S3<07:02;8<63:D:" #(bcode:sp
+	    compile-let #fn("A000n483<83=7005188T71018953728;737488518;528:537508=524268=1<521=P7708>827488515447808<U524798<E523A082I<07:02;8<63:D:" #(bcode:sp
   compile-arglist vars-to-env complex-bindings caddr box-vars #fn(nconc)
   compile-in bcode:stack > emit shift) compile-let)
-	    compile-or #fn(";000n470018283O2166:" #(compile-short-circuit brt) compile-or)
+	    compile-or #fn("<000n470018283O21O67:" #(compile-short-circuit brt) compile-or)
 	    compile-prog1 #fn(":000n37001O82T544718251B3W0720K5247301O71825154474025524720r/62:D:" #(compile-in
   cddr bcode:stack compile-begin emit pop) compile-prog1)
 	    compile-set! #fn("?000n470821E538821CF07201O83544730248263:88<El88=T893<07588=51@9076082528:3g07308937027@40288;534790K5247201O83544790r/5247302:62:7201O8354489IA07;2<2=825251@30D47302>8;63:" #(lookup-sym
   global compile-in emit setg vinfo:index capture-var! loada loadc bcode:stack
   set-car! error #fn(string) "internal error: misallocated var " seta) compile-set!)
-	    compile-short-circuit #fn("<000n683H3=07001828464:83=H3>070018283<64:710517001O83<544720K52473024524730858:534720r/5247302552476018283=84855647708:62:" #(compile-in
+	    compile-short-circuit #fn("?000n783H3?0700182848665:83=H3@070018283<8665:86;I804710517001O83<86554720K52486360O@9073024524730858;534720r/52486360O@907302552476018283=84858657486340O:7708;62:" #(compile-in
   make-label bcode:stack emit dup pop compile-short-circuit mark-label) compile-short-circuit)
-	    compile-sym #fn(";000n470821E538821Cb0228251;3=0473248251513@07502624825163:750278263:88<El3Y0750287988=5153483;370488=T3:07502:62:D:7502;7<0825253483;370488=T3:07502:62:D:" #(lookup-sym
+	    compile-sym #fn(";000n470821E538821C`02282513M073248251513@07502624825163:750278263:88<El3W0750287988=51534833A088=T3:07502:62:D:7502;7<08252534833A088=T3:07502:62:D:" #(lookup-sym
   global #fn(constant?) printable? #fn(top-level-value) emit loadv loadg loada
   vinfo:index car loadc capture-var!) compile-sym)
 	    compile-thunk #fn(":000n170q21q72051e362:" #(compile-f λ
@@ -174,7 +175,7 @@
   compile-in void bcode:stack mark-label emit brf pop jmp) compile-while)
 	    complex-bindings #fn("=000n2205020507101OO8687564722386>174875162:" #(#fn(table)
   complex-bindings- filter #fn("7000n120A062:" #(#fn(has?))) table-keys) complex-bindings)
-	    complex-bindings- #fn("=000n61J40O:0R3M083;39042001523;021840D63:D:0H;I80472051340O:0<23Co0200T1523Q021850TD534833>021840TD53@30D@30D474750511O83848566:760<513U074770517817905152O82S;I50483848566:740<17:051838485562;2<1838485>40=52P:" #(#fn(memq)
+	    complex-bindings- #fn("=000n61J40O:0R3K0833D02001523;021840D63:D:0H;I80472051340O:0<23Co0200T1523Q021850TD534833>021840TD53@30D@30D474750511O83848566:760<513U074770517817905152O82S;I50483848566:740<17:051838485562;2<1838485>40=52P:" #(#fn(memq)
   #fn(put!) quoted? set! complex-bindings- caddr is-lambda? lambda:body diff
   lambda:vars inlineable? #fn(map) #fn(";000n1700AOF929366:" #(complex-bindings-))) complex-bindings-)
 	    const-to-idx-vec #fn("9000n1207105151722385>17405152485:" #(#fn(vector-alloc)
@@ -188,9 +189,8 @@
 								   diff) diff)
 	    disassemble #fn("T000\x871000.///\x881000I60O?14z282JD07001E53471504D:@30D482<2205123051DD2487>1?:425187>2?;4r4268851\x8a<D8<<8=L3\x85242728888<>2O79537:8<<r4523907150@30D4E87K~2;|48<8<<KM_48>2<8?2=523[08;8>8<<r45348:897>888<<52G5148<8<<r4M_@\x1112<8?2?523V08;8>8<<K5348:89888<<GG5148<8<<KM_@\xe212<8?2@523W08;8>8<<K5347A2B888<<G515148<8<<KM_@\xb212<8?2C523\\08;8>8<<r45347A2B7>888<<52515148<8<<r4M_@}12<8?2D523\xb808;8>8<<r88>2EC70r4@30EM5347A2B7>888<<52512F5248<8<<r4M_47A2B7>888<<52515148<8<<r4M_48>2ECY07A2F5147A2B7>888<<52512F5248<8<<r4M_@30D@\xec08?2Gc3^08;8>8<<r45347A2B7>888<<52512F5248<8<<r4M_@\xb802<8?2H523e08;8>8<<r25347A2I7J8<<r,7K888<<52g3515248<8<<r2M_@z02<8?2L523e08;8>8<<r45347A2I7J8<<r,7>888<<52g3515248<8<<r4M_@<08;8>8<<E53^1^1@\xd6-:" #(disassemble
   newline #fn(function:code) #fn(function:vals)
-  #fn("9000n10\\;36040[S3C07021514720OAKM63:73061:" #(princ "\n" disassemble
-						      print) print-val)
-  #fn(";000n370A;3P04FEl;3H0471A7215152;3904A182ML37023@4024751r5~512602765:" #(princ
+  #fn("9000n10\\3H00[IC07021514720OAKM63:73061:" #(princ "\n" disassemble print) print-val)
+  #fn(";000n370A3S0FEl3M071A72151523@0A182ML37023@4024751r5~512602765:" #(princ
   >= 1- " >" "  " hex5 ":  " " ") print-inst)
   #fn(length) #fn(table-foldl) #fn("7000n382;I?041AF<GQ;34040:" #())
   Instructions > #fn("6000n1702161:" #(princ "\t"))
@@ -201,7 +201,7 @@
   keyargs " " brbound (jmp brf brt brne brnn brn) "@" hex5 ref-int16-LE (jmp.l
   brf.l brt.l brne.l brnn.l brn.l)) disassemble)
 	    div #fn("7000n201k0EL;3C041EL;3404K;I504r/;I404EM:" #() div) emit
-	    #fn("P000z20EG82J^0120Q;3A0487B;390487<21Q3:08722_@900E187Pp@\xb4123124523A075082<52e1?2@30D4261275288;3<047882<29523:088T?1@30D^142612:5288;3<047882<29523:088T?1@30D^1412;C\\0822<d3=02=?14q?2@F0822>d3=02??14q?2@30O@30D412@C\\0822<d3=02A?14q?2@F0822>d3=02B?14q?2@30O@30D487B38087<@30q12CQ;3\x9f04882DQ;390487T2EQ3E00E82<2F7G8751PPp@x0882DCB00E82<2H87=PPp@a0882ICB00E82<2J87=PPp@J0882ECB00E82<2K87=PPp@30O;Ia0412HQ;3804882EQ3B00E82<2F87=PPp@?00E7L182P8752p^140:" #(car
+	    #fn("P000z20EG82JX0120CH087B3B087<21C:08722_@900E187Pp@\xa8123124523A075082<52e1?2@30D42612752883F07882<29523:088T?1@30D^142612:52883F07882<29523:088T?1@30D^1412;C\\0822<d3=02=?14q?2@F0822>d3=02??14q?2@30O@30D412@C\\0822<d3=02A?14q?2@F0822>d3=02B?14q?2@30O@30D487B38087<@30q12CQ;3\x9b04882DCM087T2ECE00E82<2F7G8751PPp@x0882DCB00E82<2H87=PPp@a0882ICB00E82<2J87=PPp@J0882ECB00E82<2K87=PPp@30O;I]0412HCI0882ECB00E82<2F87=PPp@?00E7L182P8752p^140:" #(car
   cdr cadr #fn(memq) (loadv loadg setg) bcode:indexfor #fn(assq)
   ((loadv loadv.l) (loadg loadg.l) (setg setg.l) (loada loada.l) (seta seta.l)
 		   (box box.l)) > 255 ((loadc loadc.l)) loada (0) loada0 (1)
@@ -223,13 +223,13 @@
   expand) eval)
 	    even? #fn("7000n1200K52El:" #(#fn(logand)) even?) every
 	    #fn("7000n21H;ID0401<51;3:047001=62:" #(every) every) expand #fn("F000n1DDDDDDDDDDD\x8a5\x8a6\x8a7\x8a8\x8a9\x8a:\x8a;\x8a<\x8a=\x8a>\x8a?8520_4862186>1_48722e1_4882385868?87>4_489248?89>2_48:258:>1_48;268:8988>3_48<278?8:8988>4_48=28888?>2_48>29_48?2:8?8>8;8<8=>5_48?<0q62:" #(#fn("7000n20Z;I904200152S:" #(#fn(assq)) top?)
-  #fn("8000n10H3400:020d3400:0<B;3;047105122Q3F023A<7405151A<0=5162:0<A<0=51P:" #(((begin))
+  #fn("8000n10H3400:020d3400:0<B3P07105122CF023A<7405151A<0=5162:0<A<0=51P:" #(((begin))
   caar begin #fn(append) cdar) splice-begin) *expanded* #fn("A000n20H3400:A<201523:0F<051@300A<21152873;0728651@30q2324758852152\x8a987IA024269289>28662:D\x8a:8:278:928993>4_48:<^186518:D8;B3c0493<788;51QIC08;92<8;<89<52_@;08;798;51_48;=?;@\xfb/48::" #(begin
   define get-defined-vars #fn(nconc) #fn(map) list #fn("7000n1A<0F<62:" #())
-  #fn(";000n10H3400:0<B;3;042071051Q3<00<A<0=51P:F<0<92<52922223747585515292<52_493<85PA<0=51P:" #(define
+  #fn(";000n10H3400:0<B3F02071051C<00<A<0=51P:F<0<92<52922223747585515292<52_493<85PA<0=51P:" #(define
   caar #fn(nconc) #fn(map) list get-defined-vars)) caar cdar) expand-body)
-  #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("9000n20H3400:0<B3M00<=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("?000n20T7005171051A<0T5122237489521522225e1F<868:52e192<888:528764:" #(lastcdr
   cddr #fn(nconc) #fn(map) list λ) expand-lambda)
   #fn("?000n20=V;I6040TH3M070051J400:210TA<72051152e3:730517405170051F<730515125267789521522521e18792<868:52Pe193<888:5263:" #(cddr
@@ -238,7 +238,7 @@
 						 #fn(map)
 						 #fn("9000n10<70A<0TF525150Fe3:" #(compile-thunk))) expand-let-syntax)
   #fn("5000n20:" #() local-expansion-env)
-  #fn("<000n20H3400:0<208615221A10>387;370487=B3I0A<87T0=f2F<72875115262:87;I?0486RS;I60486Z3708860:73051893>0A<890=f2162:8624C400:8625C:092<0162:8625C:092<0162:8626C:093<0162:8627C:094<0162:8860:" #(#fn(assq)
+  #fn("<000n20H3400:0<208615221A10>3873P087=B3I0A<87T0=f2F<72875115262:87;I?0486RS;I60486Z3708860:73051893>0A<890=f2162:8624C400:8625C:092<0162:8625C:092<0162:8626C:093<0162:8627C:094<0162:8860:" #(#fn(assq)
   #fn(":000n0D\x8a48420AF84>3_484<^19261:" #(#fn("8000n10H3400:0<H3700<@90A<0<F5292<0=51P:" #())))
   caddr macrocall? quote λ define let-syntax) expand-in)) expand)
 	    expand-define #fn("?000n10T70051B3:070051@L00TR3;07150e1@=07223740515285R3<0258586<e3:2585<2627e185=e128865185<54e3:" #(cddr
@@ -249,7 +249,7 @@
 	    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)
-	    get-defined-vars #fn("7000n170A<05161:" #(delete-duplicates) #(#0=(#fn("8000n10H340q:0<20Q;36040=B3d00TR;37040Te1;IS040TB;3E0471051R;3:0471051e1;I404q:0<22C?07324A<0=52}2:q:" #(define
+	    get-defined-vars #fn("7000n170A<05161:" #(delete-duplicates) #(#0=(#fn("8000n10H340q:0<20Cj00=B3d00TR;37040Te1;IS040TB;3E0471051R;3:0471051e1;I404q:0<22C?07324A<0=52}2:q:" #(define
   caadr begin nconc #fn(map)) #(#0#)))))
 	    hex5 #fn("8000n170210r@52r52263:" #(string-lpad #fn(number->string)
 						#\0) hex5)
@@ -258,7 +258,7 @@
 	    index-of #fn("9000n31J40O:01<C5082:7001=82KM63:" #(index-of) index-of)
 	    inlineable? #fn("9000n10<85B;3u047085<51;3i047185T51;3]04727385T52;3O047485T2552S;3@047685T270=5162:" #(is-lambda?
   list? every symbol? length> 255 length= #fn(length)) inlineable?)
-	    io-readall #fn("8000n12050218505242285518623d;3804240513702560:86:" #(#fn(buffer)
+	    io-readall #fn("8000n12050218505242285518623d3?0240513702560:86:" #(#fn(buffer)
   #fn(io-copy) #fn(iostream->string) "" #fn(io-eof?)
   #fn(eof-object)) io-readall)
 	    io-readline #fn("7000n12002162:" #(#fn(io-readuntil) #\newline) io-readline)
@@ -267,7 +267,7 @@
 	    #fn("6000n1020Q;I704020Q:" #(λ) is-lambda?) keyword->symbol #fn("<000n1200513O021220512386E742586515153^161:0:" #(#fn(keyword?)
   #fn(symbol) #fn(string) #fn(string-sub) 1- #fn(string-length)) keyword->symbol)
 	    keyword-arg? #fn("6000n10B;3904200<61:" #(#fn(keyword?)) keyword-arg?)
-	    lambda-vars #fn(":000n1D\x8a5852085>1_485<00OO54421227305162:" #(#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
+	    lambda-vars #fn(":000n1D\x8a5852085>1_485<00OO54421227305162:" #(#fn(":000n40V;I5040R340D:0B3Z00<R3T082;I504833<0702112263:A<0=1828364:0B3\x8d00<B3\x870730<r2523?074051R360O@=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."
@@ -336,7 +336,7 @@
 							       #fn("7000n02071A62:" #(#fn(for-each)
   write)) #fn("6000n1A50420061:" #(#fn(raise)))) princ)
 	    print #fn("9000z02071062:" #(#fn(for-each) write) print)
-	    print-exception #fn("=000n10B;3D040<20Q;3:04710r3523T072230T2425760515127554787605151@ 00B;3D040<29Q;3:04710r3523I0722:760512;534780T51@\xee00B;3D040<2<Q;3:04710r2523?0722=0T2>53@\xc600B;38040<2?Q3B0722@514720=f2@\xa700B;38040<2AQ3G07B76051514722C0T52@\x8307D051;3:04710r2523c0780<51472275140T2E8551;I60485R37072@40788551^1@>0722F514780514727G61:" #(type-error
+	    print-exception #fn("=000n10B3e00<20C^0710r3523T072230T2425760515127554787605151@\x0e00B3Z00<29CS0710r3523I0722:760512;534780T51@\xe100B3P00<2<CI0710r2523?0722=0T2>53@\xbe00B3I00<2?CB0722@514720=f2@\xa200B3N00<2ACG07B76051514722C0T52@\x8107D0513m0710r2523c0780<51472275140T2E8551;I60485R37072@40788551^1@>0722F514780514727G61:" #(type-error
   length= princ "type error: expected " ", got " #fn(typeof) caddr ": " print
   bounds-error "index " " out of bounds for " unbound-error "eval: variable "
   " has no value" error "error: " load-error print-exception "in file " list?
@@ -345,7 +345,7 @@
   #fn(function:code) #fn(raise) thrown-value ffound #fn(function:vals) 1- #fn(length)
   #fn("8000n170A0G513>0F<A0G929363:D:" #(closure?))) find-in-f)
   #fn(";000n220A01>321{863I02273247576865152275261:28:" #(#fn("8000n02021AF>292524O:" #(#fn(for-each)
-  #fn("8000n1A<0Fq63:" #()))) #fn("6000n10B;3B040<20Q;38040T21Q38072061:23061:" #(thrown-value
+  #fn("8000n1A<0Fq63:" #()))) #fn("6000n10B3F00<20C?00T21C8072061:23061:" #(thrown-value
   ffound caddr #fn(raise))) #fn(symbol) string-join #fn(map) string reverse! "/"
 							  λ) fn-name) reverse!
   length> list-tail *interactive* filter closure? #fn(map)
@@ -403,8 +403,8 @@
 	    string-rpad #fn(";000n32007182122051~5262:" #(#fn(string)
 							  string-rep #fn(string-length)) string-rpad)
 	    string-tail #fn("7000n2200162:" #(#fn(string-sub)) string-tail)
-	    string-trim #fn(">000n3DD\x8a7\x8a8872087>1_4882188>1_42205123087<01E895488<082895363:" #(#fn("9000n48283L;3?042012108252523A0A<017282518364:82:" #(#fn(string-find)
-  #fn(string-char) 1+) trim-start) #fn(":000n37082E52;3C0421122073825152523?0A<0173825163:82:" #(>
+	    string-trim #fn(">000n3DD\x8a7\x8a8872087>1_4882188>1_42205123087<01E895488<082895363:" #(#fn("9000n48283L3P02012108252523A0A<017282518364:82:" #(#fn(string-find)
+  #fn(string-char) 1+) trim-start) #fn(":000n37082E523R021122073825152523?0A<0173825163:82:" #(>
   #fn(string-find) #fn(string-char) 1-) trim-end)
   #fn(string-length) #fn(string-sub)) string-trim)
 	    symbol-syntax #fn("8000n120710O63:" #(#fn(get)
@@ -437,7 +437,7 @@
 	    untrace #fn("9000n1200517185513A0220238551r2G62:D:" #(#fn(top-level-value)
 								  traced? #fn(set-top-level-value!)
 								  #fn(function:vals)) untrace)
-	    values #fn("8000z00B;36040=V3500<:A0P:" #() #(#1#)) vars-to-env
+	    values #fn("8000z00B3:00=J500<:A0P:" #() #(#1#)) vars-to-env
 	    #fn(":000n32021182>2072230515163:" #(#fn(map)
 						 #fn("9000n2700210A52SS1FM63:" #(vinfo
   #fn(memq))) iota #fn(length)) vars-to-env)
--- a/test/unittest.lsp
+++ b/test/unittest.lsp
@@ -161,6 +161,18 @@
 ; this crashed once
 (for 1 10 (λ (i) 0))
 
+; and, or
+(assert (equal? #t (and)))
+(assert (equal? #f (or)))
+(assert (equal? 1 (and '() 'x 1)))
+(assert (equal? 1 (or #f #f #f #f #f 1 #f #f #f #f)))
+(assert (equal? 2 (if (and '() 'x 1) 2 0)))
+(assert (equal? 2 (if (or #f #f #f #f #f 1 #f #f #f #f) 2 0)))
+(assert (equal? #f (and '() 1 'x #f)))
+(assert (equal? #f (or #f #f #f #f #f #f #f #f #f #f)))
+(assert (equal? 0 (if (and '() 1 'x #f) 2 0)))
+(assert (equal? 0 (if (or #f #f #f #f #f #f #f #f #f #f) 2 0)))
+
 ; failing applications
 (assert-fail ((λ (x) x) 1 2))
 (assert-fail ((λ (x) x)))