ref: 1712b18a90b80757dbc96850744aa4c0c14fcfd1
parent: 39517070479e7453b62fb8aeb2cb52e869b33fbb
author: spew <spew@cbza.org>
date: Tue Apr 22 18:32:56 EDT 2025
implement subseq, replace list head and tail calls Fixes: https://todo.sr.ht/~ft/sl/29
--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -51,17 +51,17 @@
ltin)) cons? ((:doc-group . builtin)) doc-group ((:doc-group . doc)) aref ((:doc-group . builtin)) *properties* ((:doc-group . prop)) vec ((:doc-group . builtin)) >= ((:doc-group . compare)) sym? ((:doc-group . builtin)) zero? ((:doc-group . compare)) length= ((:doc-group . list)) positive? ((:doc-group . compare)) doc-for ((:doc-group . doc)) aset! ((:doc-group . builtin)) T ((:doc-see)) car ((:doc-group . list)
(:doc-group . builtin)) *builtins* ((:doc-group . builtin)) str ((:doc-group . string)) cons ((:doc-group . list)
(:doc-group . builtin)) - ((:doc-group . builtin)) remprop ((:doc-group . prop)) <= ((:doc-group . compare)) rand ((:doc-group . rand)) negative? ((:doc-group . compare)) Instructions ((:doc-group . builtin)) file ((:doc-group . io)) rand-double ((:doc-group . rand)) cdr ((:doc-group . list)
-ist)
- (:doc-group . builtin)) *builtins* ((:doc-group . builtin)) str ((:doc-group . string)) cons ((:doc-group . list)
- (:doc-group . builtin)) - ((:doc-group . builtin)) remprop ((:doc-group . prop)) <= ((:doc-group . compare)) rand ((:doc-group . rand)) negative? ((:doc-group . compare)) Instructions ((:doc-group . builtin)) file ((:doc-group . io)) rand-double ((:doc-group . rand)) cdr ((:doc-group . list)
- (:doc-group . builtin)) atom? ((:doc-group . builtin)) vec? ((:doc-group . builtin)) / ((:doc-group . builtin)) equal? ((:doc-group . compare)
+ist)
+ (:doc-group . builtin)) *builtins* ((:doc-group . builtin)) str ((:doc-group . string)) cons ((:doc-group . list)
+ (:doc-group . builtin)) - ((:doc-group . builtin)) remprop ((:doc-group . prop)) <= ((:doc-group . compare)) rand ((:doc-group . rand)) negative? ((:doc-group . compare)) Instructions ((:doc-group . builtin)) file ((:doc-group . io)) rand-double ((:doc-group . rand)) cdr ((:doc-group . list)
+ (:doc-group . builtin)) atom? ((:doc-group . builtin)) vec? ((:doc-group . builtin)) / ((:doc-group . builtin)) equal? ((:doc-group . compare)
-group . compare)
-ltin)) help ((:doc-group . doc)) rand-u32 ((:doc-group . rand)) = ((:doc-group . compare)
- (:doc-group . builtin)) rand-u64 ((:doc-group . rand)) not ((:doc-group . builtin)) separate-doc-from-body ((:doc-group . doc)) set-cdr! ((:doc-group . list)
- (:doc-group . builtin)) fn? ((:doc-group . builtin)) help-print-header ((:doc-group . doc)) lz-pack ((:doc-group . compress)) arg-counts ((:doc-group . builtin)) eq? ((:doc-group . compare)
- (:doc-group . builtin)) getprop ((:doc-group . prop) (:doc-see . putprop)) vm-stats ((:doc-group . vm)) * ((:doc-group . builtin)) putprop ((:doc-group . prop)
- (:doc-see . getprop)) io->str ((:doc-group . io))))
- *syntax-environment* #table(bcode:nconst #fn("n1200r2e3:" #(aref)) doc-for #fn("z10B86;35040<;J404086;35040=70211225251<863I0232487e22489e22488e2e4:232487e22489e2e3:" #(separate-doc-from-body
+roup . builtin)) help ((:doc-group . doc)) rand-u32 ((:doc-group . rand)) = ((:doc-group . compare)
+ (:doc-group . builtin)) rand-u64 ((:doc-group . rand)) not ((:doc-group . builtin)) separate-doc-from-body ((:doc-group . doc)) set-cdr! ((:doc-group . list)
+ (:doc-group . builtin)) fn? ((:doc-group . builtin)) help-print-header ((:doc-group . doc)) lz-pack ((:doc-group . compress)) arg-counts ((:doc-group . builtin)) eq? ((:doc-group . compare)
+ (:doc-group . builtin)) getprop ((:doc-group . prop) (:doc-see . putprop)) vm-stats ((:doc-group . vm)) * ((:doc-group . builtin)) putprop ((:doc-group . prop)
+ (:doc-see . getprop)) io->str ((:doc-group . io))))
+ *syntax-environment* #table(bcode:nconst #fn("n1200r2e3:" #(aref)) doc-for #fn("z10B86;35040<;J404086;35040=70211225251<863I0232487e22489e22488e2e4:232487e22489e2e3:" #(separate-doc-from-body
58551513c07675855151278685<e2e12886217975855151PA<0=51e4e3:272:85<e2e1282:7585512:e2A<0=51e4e3:2885<2185=PA<0=51e4:" #(else
begin or => 1arg-lambda? caddr caadr let if cddr #:g19) cond-clauses->if))) do #fn("z21<2071052207205220230522425268827872829e12:1=51522829e12:82512825e18:52e153e4e3e2e12825e18952e3:" #(#fn(map)
car cadr #fn("n170051B38071061:0<:" #(cddr caddr)) letrec #:g415 λ if #fn(nconc) begin #fn(copy-list))) assert-fail #fn("z12021220qe32324e113E0252624e2271<e2e3@30De3e3e2:" #(assert
@@ -70,10 +70,10 @@
e2:" #(assert
trycatch begin λ e eq? car quote)) bcode:code #fn("n1200Ee3:" #(aref)) let #fn("z1q0R3B00?641<?041=?1@30q42021e12223052e124151532225052863C0268687e2e186e3@408788P:" #(#fn(nconc)
λ #fn(map) #fn("n10B3500<:0:") #fn(copy-list) #fn("n10B3500T:7060:" #(void)) letrec)) with-bindings #fn("z12071052207205220230522425e12076888653e12720288687535129242:e12715152242:e127202;8688535152e3e164:" #(#fn(map)
-rec)) with-bindings #fn("z12071052207205220230522425e12076888653e12720288687535129242:e12715152242:e127202;8688535152e3e164:" #(#fn(map)
- car cadr #fn("n12060:" #(#fn(gensym))) #fn(nconc) let list #fn(copy-list)
- #fn("n22001e3:" #(set!)) unwind-protect begin #fn("n22001e3:" #(set!)))) %defstruct% #fn("O10005000*///z6W1000J7021?14W2000;J60D?24W3000;J60D?34W4000;J60D?44W5000;J60D?54II22230>1??5142224?@514258651262786528@8651268?8652121C60D@C0128C60q@90792:1528E3B082;J904792;51@;082;35048;;36040e185DQ;3:042<02=52;J504858G;3L048F3708G@A08>3;0792>51@30q8E3:02?0e2@7002@e283DQ83;3\\0483H;3M0483DQ;3:042<2A052;J504838CP;J5048384DQ;3:042B02C52;J50484I222D8E108B8F>5?M5142E2Fe18H3{02G8H2He28E3E02I2J2He22K8Ie2e3@V02L2M2N2HEe32K0e2e32O2P2He27Q8A51e3e3e3@30qe18K3C02G8K<8M8K=51e3@30qe18E3U02R2K0e22K2Se28J3808K<@808M8C51e4@30qe12T7U2V8D8B8L8E8H8I8F0>88A525165:" #(#(:constructor
- 2 :predicate 4 NIL NIL :type 0 :named 1 :conc-name 3 NIL NIL) vec #0#
+) letrec)) with-bindings #fn("z12071052207205220230522425e12076888653e17720288687535129242:e17715152242:e177202;8688535152e3e164:" #(#fn(map)
+ car cadr #fn("n12060:" #(#fn(gensym))) #fn(nconc) let list copy-list #fn("n22001e3:" #(set!))
+ unwind-protect begin #fn("n22001e3:" #(set!)))) %defstruct% #fn("O10005000*///z6W1000J7021?14W2000;J60D?24W3000;J60D?34W4000;J60D?44W5000;J60D?54II22230>1??5142224?@514258651262786528@8651268?8652121C60D@C0128C60q@90792:1528E3B082;J904792;51@;082;35048;;36040e185DQ;3:042<02=52;J504858G;3L048F3708G@A08>3;0792>51@30q8E3:02?0e2@7002@e283DQ83;3\\0483H;3M0483DQ;3:042<2A052;J504838CP;J5048384DQ;3:042B02C52;J50484I222D8E108B8F>5?M5142E2Fe18H3{02G8H2He28E3E02I2J2He22K8Ie2e3@V02L2M2N2HEe32K0e2e32O2P2He27Q8A51e3e3e3@30qe18K3C02G8K<8M8K=51e3@30qe18E3U02R2K0e22K2Se28J3808K<@808M8C51e4@30qe17T7U2V8D8B8L8E8H8I8F0>88A525165:" #(#(:constructor
+ 2 :predicate 4 NIL NIL :type 0 :named 1 :conc-name 3 NIL NIL) vec #0#
92>51@30q8E3:02?0e2@7002@e283DQ83;3\\0483H;3M0483DQ;3:042<2A052;J504838CP;J5048384DQ;3:042B02C52;J50484I222D8E108B8F>5?M5142E2Fe18H3{02G8H2He28E3E02I2J2He22K8Ie2e3@V02L2M2N2HEe32K0e2e32O2P2He27Q8A51e3e3e3@30qe18K3C02G8K<8M8K=51e3@30qe18E3U02R2K0e22K2Se28J3808K<@808M8C51e4@30qe12T7U2V8D8B8L8E8H8I8F0>88A525165:" #(#(:constructor
2 :predicate 4 NIL NIL :type 0 :named 1 :conc-name 3 NIL NIL) vec #0#
#fn("n10H370q:@30q4207172051f22324850A>38652486:" #((:read-only) assoc-list cddr #fn(for-each)
@@ -91,24 +91,23 @@
ef
#fn(sym) def s v v-supplied? unless type-error quote if not aref assv :read-only error str "slot "
" in struct " " is :read-only" aset!)))) make-label #fn("n120e1:" #(gensym)) bcode:cenv #fn("n1200r3e3:" #(aref)) mark-label #fn("n22002122e21e4:" #(emit
-#fn("n1700E62:" #(bq-process)) > #fn("z12021e1721510e163:" #(#fn(nconc)
+#fn("n1700E62:" #(bq-process)) > #fn("z12021e1721510e163:" #(#fn(nconc)
241;3<0422231520P13;02410e3@3007588265275882752IIIIIb;b<288;29_514288<2:_514282;?=514282<87>1?>514282=??51402>CM02?2@8<>18?2A7B26528=5252@$089;J5048:3\xe3082888:2C154475882D527E2F8@527E2G8@52893H07H7I2J898A535147K50@30q48B3W07K5047H2L5147K5042?2M8;>18B5247K50@30q^1^1^1413c07K5047H2N5147K5042?2O8;>18?2A7B26528>525247K50@30q47P50@g07H2Q13<02R12S52@402T05341JE00R3@00ZJ;07H2U51@30q47K5047P60:" #(#(:print-header
0) help-print-header #fn(sym) ":doc-" doc getprop *doc* *formals-list* #0#
-5147K50@30q48B3W07K5047H2L5147K5042?2M8;>18B5247K50@30q^1^1^1413c07K5047H2N5147K5042?2O8;>18?2A7B26528>525247K50@30q47P50@g07H2Q13<02R12S52@402T05341JE00R3@00ZJ;07H2U51@30q47K5047P60:" #(#(:print-header
- 0) help-print-header #fn(sym) ":doc-" doc getprop *doc* *formals-list* #0#
- #fn("n313?02021820>2162:72504738251474061:" #(#fn(for-each)
- #fn("n17050471A51472F0P61:" #(newline princ print))
- newline princ print) print-sig)
- #fn("n12002152853;0220E8563:0:" #(#fn(str-find) "\n" #fn(str-sub)) first-line)
+5147K50@30q48B3W07K5047H2L5147K5042?2M8;>18B5247K50@30q^1^1^1413c07K5047H2N5147K5042?2O8;>18?2A7B26528>525247K50@30q47P50@g07H2Q13<02R12S52@402T05341JE00R3@00ZJ;07H2U51@30q47K5047P60:" #(#(:print-header
+ 0) help-print-header #fn(sym) ":doc-" doc getprop *doc* *formals-list* #0#
+ #fn("n313?02021820>2162:72504738251474061:" #(#fn(for-each)
+ #fn("n17050471A51472F0P61:" #(newline princ print))
+ newline princ print) print-sig)
#fn("n3A051370082P:82:") <) table-keys-filter-sort) groups #fn(for-each)
#fn("n1707105122A<7302452515347560:" #(princ caddr ": " getprop *doc* newline))
#fn(get) *properties* :kind *doc-extra* filter #fn("n10<20Q:" #(:doc-fmt))
#fn("n10<20Q:" #(:doc-see)) princ foldl #fn("n20=161:") newline "See also:" #fn("n1A<0=700=21522263:" #(getprop
-
+formals-list* " ")) void
H0738824862589Pe15252@30q42627e188e128875163:" #(separate-doc-from-body
-0E8553@300853<02208552@402324752627AF5351285229862:7;882<528764:" #(#fn(str-find)
- "\n\n" #fn(str-sub) "" #fn(str-split) print-to-str #fn(list*) defstruct "\n" #fn(str) "\n\n "
- str-join "\n ") fmt) sym-set-doc #fn(append) :doc-fmt #fn(nconc) %defstruct% #fn(copy-list))) bcode:ctable #fn("n1200Ke3:" #(aref)) with-output-to #fn("z12021e1220e2e1e12315163:" #(#fn(nconc)
+ #0# #fn("n12002152853=0220E8553@300853<02208552@402324752627AF5351285229862:7;882<528764:" #(#fn(str-find)
+ "\n\n" #fn(str-sub) "" #fn(str-split) print-to-str #fn(list*) defstruct "\n" #fn(str) "\n\n "
+ str-join "\n ") fmt) sym-set-doc #fn(append) :doc-fmt #fn(nconc) %defstruct% copy-list)) bcode:ctable #fn("n1200Ke3:" #(aref)) with-output-to #fn("z12021e1220e2e1e17315163:" #(#fn(nconc)
-bindings *io-out* #fn(copy-list))) catch #fn("n22012122e123242522e2262722e22829e2e3262:22e20e3e42;22e22<22e2e4e3e3:" #(trycatch
λ #:g438 if and cons? eq? car quote thrown-value cadr caddr raise)) let* #fn("z10H3E02021e1qe12215153e1:2021e173051e1e1220=B3H02024e10=e12215153e1@301515375051e2:" #(#fn(nconc)
λ #fn(copy-list) caar let* cadar)) letrec #fn("z1202021e12273052e122240522515154e1227605262:" #(#fn(nconc)
@@ -141,7 +140,8 @@
;857<865387;3D042=8751;39047>8761:" #(*os-name*
"unknown" "plan9" "home" "macos" princ "\e]0;StreetLISP v0.999\a" "HOME" #fn(os-getenv) "lib/slrc"
".slrc" #fn(str) *directory-separator* #fn(path-exists?) load) __rcscript)
-0>121{:" #(#fn("n070A61:" #(load))
+0>121{:" #(#fn("n070A61:" #(load))
+ #fn("n1700514212205161:" #(top-level-exception-handler
vel-exception-handler
#fn(exit)
#fn(str)))) __script)
@@ -179,8 +179,8 @@
"n10<T:" #() cadar) caddar #fn("n10<=T:" #() caddar) cadddr
#fn("n10==T:" #() cadddr) caddr #4=#fn("n10=T:" #() caddr) call-with-values
#fn("n205086B3@0A86<C90186=}2:18661:" #() #(#3=(*values*))) capture-var! #fn("n20r3G70186E5387;JG042186510r322861e152p4:" #(index-of
-0r322861e152p4:" #(index-of
- #fn(length) #fn(nconc)) capture-var!)
+0r322861e152p4:" #(index-of
+ #fn(length) #fn(nconc)) capture-var!)
fn("n10=T=:" #() cdaddr) cdadr
#fn("n10T=:" #() cdadr) cdar #fn("n10<=:" #() cdar) cddaar
#fn("n10<<==:" #() cddaar) cddadr #fn("n10T==:" #() cddadr) cddar
@@ -234,6 +234,8 @@
540r40r4GKMp486360q@9072023524720858;5340r40r4Gr/Mp486360q@907202452475018283=84858657486340q:720268;63:" #(compile-in
#fn(gensym) emit dup pop compile-short-circuit label) compile-short-circuit)
compile-sym #fn("n470821E538821C`02282513M073248251513@07502624825163:750278263:88<El23W0750287988=51534833A088=T3:07502:62:q:7502;7<08252534833A088=T3:07502:62:q:" #(lookup-sym
+251513@07502624825163:750278263:88<El23W0750287988=51534833A088=T3:07502:62:q:7502;7<08252534833A088=T3:07502:62:q:" #(lookup-sym
+ global #fn(const?) printable? #fn(top-level-value) emit loadv loadg loada vinfo:index car loadc
251513@07502624825163:750278263:88<El23W0750287988=51534833A088=T3:07502:62:q:7502;7<08252534833A088=T3:07502:62:q:" #(lookup-sym
global #fn(const?) printable? #fn(top-level-value) emit loadv loadg loada vinfo:index car loadc
capture-var!) compile-sym)
@@ -248,8 +250,8 @@
("n1700AqF929366:" #(complex-bindings-))) complex-bindings-)
const-to-idx-vec #fn("n1200r2G51212285>10KG52485:" #(#fn(vec-alloc)
#fn(for-each)
-for-each)
- #fn("n2A10p:")) const-to-idx-vec)
+" #(#0#
+ #fn("n382;3?0482El2;3504I:41360q@40I:41<qP087N4A<871=82;390470825163:" #(1-) copy-) 1-) copy-list)
#fn("n31J5082:A<01=01<5139082KM@408263:" #() count-)) count)
delete-duplicates #fn("n1700rD523O02150Ib686228586>2_486<^10q62:0H3400:0<0=73858652390748661:85748651P:" #(length>
#fn(table) #fn("n20H38070161:21A0<523:0F<0=162:22A0<D534F<0=0<1P62:" #(reverse! #fn(has?)
@@ -263,17 +265,17 @@
oadc.l)) loada (0) loada0 (1) loada1 loadc loadc0 loadc1 brn not brnn eq? brne nreconc) emit)
emit-optional-arg-inits #fn("n582B3\xa60205071022845347382513<07102452@30q4710258953476077178838452q53q7982515447102:845347102;5247102<895347=0182=8384KM65:q:" #(#fn(gensym)
emit bounda cddar dup brnn compile-in extend-env list-head cadar seta pop label
-q:" #(#fn(gensym)
- emit bounda cddar dup brnn compile-in extend-env list-head cadar seta pop label
+65:q:" #(#fn(gensym)
+ emit bounda cddar dup brnn compile-in extend-env subseq cadar seta pop label
r2ki2M2452255025502650qqEI8>87L23\xbc14868>G?<48<27CP02889868>KMG298;515348>r2M?>@\x8b12:8;2;7<883k08<8C2=C702>@X08C2?C702@@L08C2AC702B@@08C2CC702D@408<^1@408<525248>KM?>48>87L2;3804868>G?=42E8<2F523`0288:298;518=5342:8;883707G@407HE515248>KM?>@\xeb08<2ICH02:8;2J8=515248>KM?>@\xce08=X3\xc708<2E8?2K523H02:8;2J8=515248>KM?>@\x9f02E8?2L523\x8102:8;2J8=515248>KM?>42:8;2J868>G515248>KM?>48<2MCK02:8;2J868>G515248>KM?>@30q@E02:8;2N8=515248>KM?>^1@30q@\x9f.42O2P8;8889>38:5242Q8;61:" #(reverse!
list->vec #fn(length) >= 65536 #fn(table) #fn(buffer) label #fn(put!)
#fn(sizeof) #fn(io-write) #fn(get) Instructions jmp jmp.l brne brne.l brnn brnn.l brn brn.l #fn(memq)
(jmp brne brnn brn) s32 s16 bounda #fn(s32) (loadv.l loadg.l setg.l loada.l seta.l argc.l vargc.l
call.l tcall.l loadc.l box.l) (optargs keyargs)
-) label #fn(put!)
+uffer) label #fn(put!)
.l loadg.l setg.l loada.l seta.l argc.l vargc.l
call.l tcall.l loadc.l box.l) (optargs keyargs)
-72@407324921520~5162:" #(#fn(io-seek)
+ch) #fn("n220A052421AF37072@407324921520~5162:" #(#fn(io-seek)
#fn(io-write) s32 s16
#fn(get)))
#fn(io->str)) encode-byte-code)
@@ -322,12 +324,12 @@
#fn(io->str)) io-readall)
io-readline #fn("n12002162:" #(#fn(io-readuntil) #\newline) io-readline) io-readlines
#fn("n17071062:" #(read-all-of io-readline) io-readlines) iota #fn("n17071062:" #(map-int
-K021220512386K24865153^161:0:" #(#fn(keyword?)
- #fn(sym)
- #fn(str)
- #fn(str-sub)
- #fn(str-length)) keyword->sym)
- keyword-arg? #fn("n10B;3904200<61:" #(#fn(keyword?)) keyword-arg?) lambda-vars
+K021220512386K24865153^161:0:" #(#fn(keyword?)
+ #fn(sym)
+ #fn(str)
+ #fn(str-sub)
+ #fn(str-length)) keyword->sym)
+ keyword-arg? #fn("n10B;3904200<61:" #(#fn(keyword?)) keyword-arg?) lambda-vars
"n40S;J5040R340D:0B3Z00<R3T082;J504833<0702112263:A<0=1828364:0B3\xa500<B3\x9f073051R3Y0740<r252;JF04740<r352;390475051R360q@=070260<2715442873051513=0A<0=182D64:833<0702112963:A<0=1D8364:0B3>0702:0<27164:01C:07021162:702:027164:" #(compile-error
"invalid argument list " ": optional arguments must come after required" caar length= caddar "invalid optional argument "
" in list " #fn(keyword?) ": keyword arguments must come last."
@@ -477,8 +479,13 @@
10B;3X040<20Q;JN040<21Q;JD040<22Q;3:04730r252;J704022Q:" #(unquote-splicing
unquote-nsplicing unquote length>) splice-form?)
str-join #fn("n20J5020:215022860<5242324861>20=524258661:" #("" #fn(buffer)
+ #fn(for-each)
+ #fn("n120AF52420A062:" #(#fn(io-write)))
+ #fn(io->str)) str-join)
+ str-lpad #fn("n3207182122051~52062:" #(#fn(str) str-rep #fn(str-length)) str-lpad)
+ str-map #fn("n2205021151EI8887L23O0422860231885251524748851?8@\f/^14258661:" #(#fn(buffer)
#fn(for-each)
- str-lpad #fn("n3207182122051~52062:" #(#fn(str) str-rep #fn(str-length)) str-lpad)
+ail #fn("n2200162:" #(#fn(str-sub)) str-tail) str-trim
str-map #fn("n2205021151EI8887L23O0422860231885251524748851?8@\f/^14258661:" #(#fn(buffer)
#fn(str-length) #fn(io-putrune) #fn(str-rune) 1+ #fn(io->str)) str-map)
str-rep #fn("n21r4L23b0701E5235021:1Kl238022061:1r2l2390220062:2200063:731513@02207401K~5262:742200521r2j262:" #(<=
@@ -502,7 +509,7 @@
A<0=51P:" #(length> list-head) formals-clean)
#fn(str?) #fn(map) str-join #fn(str-split) "\n" any #fn("n1E20051L2;3B04210E5222Q;34040:" #(#fn(str-length)
#fn(str-rune) #\space)) #fn(length) str-trim " " "" #fn("n170A2105152390220A62:0:" #(<= #fn(length)
-(str-sub)))
+(str-sub)))
))
#fn(append) void) sym-set-doc)
table-clone #fn("n12050212285>1q053485:" #(#fn(table)
--- a/src/compiler.sl
+++ b/src/compiler.sl
@@ -217,8 +217,8 @@
(cond ((= nref 1)
(compile-app g env NIL (cons 'aset! args)))
((> nref 1)
- (compile-app g env NIL (cons 'aref (list-head args nref)))
- (let ((nargs (compile-arglist g env (list-tail args nref))))
+ (compile-app g env NIL (cons 'aref (subseq args 0 nref)))
+ (let ((nargs (compile-arglist g env (subseq args nref))))
(bcode:stack g (- nargs))
(emit g 'aset!)))
(else (argc-error 'aset! 3)))))
@@ -576,7 +576,7 @@
(when (cddar opta)
(emit g 'dup))
(emit g 'brnn nxt)
- (compile-in g (extend-env env (list-head vars i) NIL) NIL (cadar opta))
+ (compile-in g (extend-env env (subseq vars 0 i) NIL) NIL (cadar opta))
(emit g 'seta i)
(emit g 'pop)
(mark-label g nxt)
--- a/src/sl.c
+++ b/src/sl.c
@@ -1063,12 +1063,6 @@
bthrow(type_error(nil, "fn", v));
}
-BUILTIN("copy-list", copy_list)
-{
- argcount(nargs, 1);
- return copy_list(args[0]);
-}
-
BUILTIN("append", append)
{
sl_v first = sl_nil, lst, lastcons = sl_nil;
--- a/src/system.sl
+++ b/src/system.sl
@@ -165,7 +165,7 @@
(let ((f (car fs)))
(cons (if (and (cons? f)
(length> f 2))
- (list-head f 2)
+ (subseq f 0 2)
f)
(formals-clean (cdr fs)))))
(let* {[doc-only (str? doc-seq)]
@@ -490,11 +490,6 @@
lst
(list-tail (cdr lst) (- n 1))))
-(def (list-head lst n)
- (and (> n 0)
- (cons (car lst)
- (list-head (cdr lst) (- n 1)))))
-
(def (list-ref lst n)
(car (list-tail lst n)))
@@ -513,11 +508,43 @@
(else (= (length seq) n))))
(def (length> seq n)
- (cond ((< n 0) seq)
+ (cond ((< n 0) T)
((= n 0) (and (cons? seq) seq))
((cons? seq) (length> (cdr seq) (- n 1)))
- (else (= (length seq) n))))
+ (else (> (length seq) n))))
+(def (copy-list seq (n NIL))
+ (def (copy- tail seq n)
+ (and n (= n 0) (return))
+ (unless seq (return))
+ (let {[next (cons (car seq) NIL)]}
+ (set-cdr! tail next)
+ (copy- next (cdr seq) (and n (1- n)))))
+ (and (if n (> n 0) T)
+ seq
+ (let {[head (cons (car seq) NIL)]}
+ (copy- head (cdr seq) (and n (1- n)))
+ head)))
+
+(def (subseq seq start (end NIL))
+ (unless (length> seq (1- start)) (bounds-error "start" start))
+ (unless (<= start end) (bounds-error "start <= end" (list start end)))
+ (and end (not (length> seq (1- end))) (bounds-error "end" end))
+ (def (subseq-l seq n)
+ (if (= n 0)
+ (copy-list seq (and end (- end start)))
+ (subseq-l (cdr seq) (1- n))))
+ (def (subseq-av alloc)
+ (let* {[end (or end (length seq))]
+ [av (alloc (- end start))]}
+ (for start (1- end)
+ (λ (i) (aset! av (- i start) (aref seq i))))
+ av))
+ (cond ((list? seq) (subseq-l seq start))
+ ((vec? seq) (subseq-av vec-alloc))
+ ((arr? seq) (let {[atype (cadr (type-of seq))]}
+ (subseq-av (λ (n) (arr-alloc atype n 0)))))))
+
(def (last-pair l)
(if (atom? (cdr l))
l
@@ -638,8 +665,7 @@
(if (or (not lst) (p (key (car lst))))
(car lst)
(find-if- (cdr lst))))
- (set! lst (list-tail lst start))
- (when end (set! lst (list-head lst (- end start))))
+ (set! lst (subseq lst start end))
(when from-end (set! lst (reverse! lst)))
(find-if- lst))
@@ -859,6 +885,9 @@
(def (type-error . args)
(raise (cons 'type-error args)))
+
+(def (bounds-error . args)
+ (raise (cons 'bounds-error args)))
(defmacro (throw tag value)
`(raise (list 'thrown-value ,tag ,value)))
--- a/test/unittest.sl
+++ b/test/unittest.sl
@@ -427,6 +427,35 @@
(assert (equal? (map (λ (x y) (+ x y)) '(1 2) '(3)) '(4)))
(assert (equal? (map (λ (x y z) (+ x y z)) '(1 2) '(3) '(4 5)) '(8)))
+;; list copying
+(assert (equal? (copy-list (iota 50)) (iota 50)))
+(assert (equal? (copy-list (iota 50) 25) (iota 25)))
+(let* {[l (iota 10)]
+ [c (copy-list l)]}
+ (aset! l 3 5)
+ (aset! c 4 23)
+ (assert (= (aref l 3) 5))
+ (assert (= (aref c 3) 3))
+ (assert (= (aref l 4) 4))
+ (assert (= (aref c 4) 23)))
+
+(assert (equal? (subseq (iota 20) 10) '(10 11 12 13 14 15 16 17 18 19)))
+(assert (equal? (subseq (iota 20) 10 15) '(10 11 12 13 14)))
+(assert (equal? (subseq (apply vec (iota 20)) 10) (vec 10 11 12 13 14 15 16 17 18 19)))
+(assert (equal? (subseq (apply vec (iota 20)) 10 15) (vec 10 11 12 13 14)))
+(assert (equal? (subseq (apply arr (cons 'u32 (iota 20))) 10) (arr 'u32 10 11 12 13 14 15 16 17 18 19)))
+(assert (equal? (subseq (apply arr (cons 'u32 (iota 20))) 10 15) (arr 'u32 10 11 12 13 14)))
+(assert-fail (subseq (iota 10) 11))
+(assert-fail (subseq (iota 10) 5 11))
+(assert-fail (subseq (iota 10) 6 5))
+(assert-fail (subseq (apply vec (iota 10)) 11))
+(assert-fail (subseq (apply vec (iota 10)) 5 11))
+(assert-fail (subseq (apply vec (iota 10)) 6 5))
+(assert (not (subseq (iota 10) 10)))
+(assert (not (subseq NIL 0)))
+(assert (equal? (subseq (apply vec (iota 10)) 10) (vec)))
+(assert (equal? (subseq (vec) 0) (vec)))
+
;; map with different return types
(assert (equal? (map 'vec + '(1 2 3) '(4 5 6) '(7 8 9)) (vec 12 15 18)))
(assert (equal? (map '(arr s32) + '(1 2 3) '(4 5 6) '(7 8 9)) (arr 's32 12 15 18)))