2021-08-24 18:44:01 +00:00
|
|
|
use builtin
|
|
|
|
use str
|
2020-03-13 14:03:36 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn -p {|@argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var c = (count $argv)
|
2021-08-24 18:44:01 +00:00
|
|
|
if (== $c 0) {
|
|
|
|
put [ (all) ]
|
|
|
|
} elif (== $c 1) {
|
|
|
|
put $argv[0]
|
|
|
|
} else {
|
2021-12-11 21:09:02 +00:00
|
|
|
fail '0 or 1 argument needed given '$c' arguments: ['(each {|e| put '"'$e'"' } $argv | str:join ', ')']'
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn -r {|step begin end|
|
2021-08-24 18:44:01 +00:00
|
|
|
if (> $step 0) {
|
|
|
|
builtin:range &step=$step $begin (+ $end 1)
|
|
|
|
} else {
|
2021-08-27 20:09:05 +00:00
|
|
|
var d = (+ $begin $end)
|
2021-12-11 21:09:02 +00:00
|
|
|
builtin:range &step=(* $step -1) $end (+ $begin 1) | each {|e| - $d $e }
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn to-list {|@argv|
|
2021-08-24 18:44:01 +00:00
|
|
|
try {
|
|
|
|
-p $@argv
|
|
|
|
} except e {
|
|
|
|
put $argv
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn range {|&step=1 b @r|
|
2021-08-24 18:44:01 +00:00
|
|
|
if (== $step 0) {
|
|
|
|
fail 'bad value: step must be positive, but is 0'
|
|
|
|
}
|
2021-08-27 20:09:05 +00:00
|
|
|
var c = (count $r)
|
2021-08-24 18:44:01 +00:00
|
|
|
if (> $c 1) {
|
|
|
|
fail 'usage: list:range &step=1 begin? end'
|
|
|
|
}
|
2021-08-27 20:09:05 +00:00
|
|
|
var e = 0
|
2021-08-24 18:44:01 +00:00
|
|
|
if (== $c 0) {
|
|
|
|
if (> $step 0) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set b e = $e $b
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-10-13 18:49:48 +00:00
|
|
|
set e = $r[0]
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
-r $step $b $e
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn indexes {|&from=$false &step=1 @argv|
|
2020-03-13 14:03:36 +00:00
|
|
|
if (== $step 0) {
|
2021-08-24 18:44:01 +00:00
|
|
|
fail 'bad value: step must be positive, but is 0'
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-08-27 20:09:05 +00:00
|
|
|
var l = (-p $@argv)
|
|
|
|
var c = (count $l)
|
2020-03-13 14:03:36 +00:00
|
|
|
if (not $from) {
|
2021-08-24 18:44:01 +00:00
|
|
|
range &step=$step (- $c 1)
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-08-24 18:44:01 +00:00
|
|
|
if (< $from 0) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set from = (+ $c $from)
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
if (> $step 0) {
|
|
|
|
if (< $from 0) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set from = 0
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
range &step=$step $from (- $c 1)
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-08-24 18:44:01 +00:00
|
|
|
if (>= $from $c) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set from = (- $c 1)
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
range &step=$step $from 0
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn -for {|&from=$false &step=1 @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var l = (-p $@argv)
|
2021-12-11 21:09:02 +00:00
|
|
|
indexes &from=$from &step=$step $l | each {|i| put [ $i $l[$i] ] }
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn loop {|&from=$false &step=1 &end=$false cb @argv|
|
2020-03-13 14:03:36 +00:00
|
|
|
if (not $end) {
|
2021-12-11 21:09:02 +00:00
|
|
|
-for &from=$from &step=$step $@argv | each {|e| $cb $@e }
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-12-11 21:09:02 +00:00
|
|
|
-for &from=$from &step=$step $@argv | each {|e|
|
2021-08-27 20:09:05 +00:00
|
|
|
var i v = $@e
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($end $i $v) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
$cb $i $v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn ploop {|&from=$false &step=1 cb @argv|
|
|
|
|
-for &from=$from &step=$step $@argv | peach {|e| $cb $@e }
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn reverse {|@argv| loop &step=-1 {|_ e| put $e } $@argv }
|
|
|
|
fn reach {|cb @argv| reverse $@argv | each {|e| cb $e } }
|
2020-03-13 14:03:36 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn empty {|@argv| == (count (-p $@argv)) 0 }
|
|
|
|
fn not-empty {|@argv| not (empty $@argv) }
|
2020-03-13 14:03:36 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn filter {|cb @argv|
|
|
|
|
each {|v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $v) {
|
|
|
|
put $v
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} (-p $@argv)
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn filter-not {|cb @argv| filter {|v| not ($cb $v) } $@argv }
|
|
|
|
fn first {|&from=$false &reverse=$false cb @argv|
|
|
|
|
var f = {|v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $v) {
|
|
|
|
put $v
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-08-27 20:09:05 +00:00
|
|
|
var l = (-p $@argv)
|
2021-08-24 18:44:01 +00:00
|
|
|
if (not $from) {
|
|
|
|
if $reverse {
|
|
|
|
reach $f $l
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-08-24 18:44:01 +00:00
|
|
|
each $f $l
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
|
|
|
} else {
|
2021-08-27 20:09:05 +00:00
|
|
|
var c = (count $l)
|
2021-08-24 18:44:01 +00:00
|
|
|
if (< $from 0) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set from = (+ $c $from)
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
if $reverse {
|
2021-08-27 20:09:05 +00:00
|
|
|
var e = (+ $from 1)
|
2021-08-24 18:44:01 +00:00
|
|
|
if (> $e $c) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set e = $c
|
2021-08-24 18:44:01 +00:00
|
|
|
} elif (< $e 0) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set e = 0
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
reach $f $l[..$e]
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-08-27 20:09:05 +00:00
|
|
|
var b = $from
|
2021-08-24 18:44:01 +00:00
|
|
|
if (> $b $c) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set b = $c
|
2021-08-24 18:44:01 +00:00
|
|
|
} elif (< $b 0) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set b = 0
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
|
|
|
each $f $l[$b..]
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn filter-index {|cb @argv|
|
|
|
|
loop {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $v) {
|
|
|
|
put $i
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn filter-index-not {|cb @argv| filter-index {|v| not ($cb $v) } $@argv }
|
|
|
|
fn first-index {|&from=$false &reverse=$false cb @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var idx = -1
|
|
|
|
var step = 1
|
2021-08-24 18:44:01 +00:00
|
|
|
if $reverse {
|
2021-10-13 18:49:48 +00:00
|
|
|
set step = -1
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
loop &from=$from &step=$step {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $v) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set idx = $i
|
2020-03-13 14:03:36 +00:00
|
|
|
break
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
put $idx
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn search {|cb @argv|
|
|
|
|
loop {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $i $v) {
|
|
|
|
put $v
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn search-not {|cb @argv| search {|i v| not ($cb $i $v) } $@argv }
|
|
|
|
fn search-first {|&from=$false &reverse=$false cb @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var step = 1
|
2021-08-24 18:44:01 +00:00
|
|
|
if $reverse {
|
2021-10-13 18:49:48 +00:00
|
|
|
set step = -1
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
loop &from=$from &step=$step {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $i $v) {
|
|
|
|
put $v
|
|
|
|
break
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn search-index {|cb @argv|
|
|
|
|
loop {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $i $v) {
|
|
|
|
put $i
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn search-index-not {|cb @argv| search-index {|i v| not ($cb $i $v) } $@argv }
|
|
|
|
fn search-first-index {|&from=$false &reverse=$false cb @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var idx = -1
|
|
|
|
var step = 1
|
2021-08-24 18:44:01 +00:00
|
|
|
if $reverse {
|
2021-10-13 18:49:48 +00:00
|
|
|
set step = -1
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
loop &from=$from &step=$step {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $i $v) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set idx = $i
|
2020-03-13 14:03:36 +00:00
|
|
|
break
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
put $idx
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn contains {|cb @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var e = $false
|
2021-12-11 21:09:02 +00:00
|
|
|
each {|v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $v) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set e = $true
|
2020-03-13 14:03:36 +00:00
|
|
|
break
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} (-p $@argv)
|
2020-03-13 14:03:36 +00:00
|
|
|
put $e
|
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn contains-not {|cb @argv| contains {|v| not ($cb $v) } $@argv }
|
2021-08-24 18:44:01 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn exists {|cb @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var e = $false
|
2021-12-11 21:09:02 +00:00
|
|
|
loop {|i v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if ($cb $i $v) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set e = $true
|
2020-03-13 14:03:36 +00:00
|
|
|
break
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
} $@argv
|
2020-03-13 14:03:36 +00:00
|
|
|
put $e
|
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn exists-not {|cb @argv| exists {|i v| $cb $i $v } $@argv }
|
2021-08-24 18:44:01 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn includes {|v @argv| contains {|e| is $v $e } $@argv }
|
|
|
|
fn includes-not {|v @argv| contains-not {|e| is $v $e } $@argv }
|
2020-03-13 14:03:36 +00:00
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn reduce {|v cb @argv|
|
|
|
|
each {|e| set v = ($cb $v $e) } (to-list $@argv)
|
2021-08-24 18:44:01 +00:00
|
|
|
put $v
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn remove-duplicate {|@argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var done = [&]
|
2021-12-11 21:09:02 +00:00
|
|
|
each {|v|
|
2020-03-13 14:03:36 +00:00
|
|
|
put [&v=$v &e=(has-key $done $v)]
|
2021-10-13 18:49:48 +00:00
|
|
|
set done[$v] = $nil
|
2021-12-11 21:09:02 +00:00
|
|
|
} (-p $@argv) | each {|v|
|
2020-03-13 14:03:36 +00:00
|
|
|
assoc $v k (not $v[e])
|
2021-12-11 21:09:02 +00:00
|
|
|
} | each {|v|
|
2020-03-13 14:03:36 +00:00
|
|
|
if $v[k] {
|
|
|
|
put $v[v]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn premove-duplicate {|@argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var done = [&]
|
2021-12-11 21:09:02 +00:00
|
|
|
peach {|v|
|
2021-10-13 18:49:48 +00:00
|
|
|
set done[$v] = $nil
|
2021-08-24 18:44:01 +00:00
|
|
|
} (-p $@argv)
|
2020-03-13 14:03:36 +00:00
|
|
|
keys $done
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn swap {|i j @argv|
|
2021-08-27 20:09:05 +00:00
|
|
|
var l = (-p $@argv)
|
|
|
|
var c = (count $l)
|
2021-10-13 18:49:48 +00:00
|
|
|
set i j = (-i $i $c) (-i $j $c)
|
2021-08-24 18:44:01 +00:00
|
|
|
if (or (== $i $c) (== $j $c)) {
|
2020-03-13 14:03:36 +00:00
|
|
|
fail 'Index out of range'
|
|
|
|
}
|
2021-08-24 18:44:01 +00:00
|
|
|
if (== $i $j) {
|
2020-07-22 09:24:43 +00:00
|
|
|
all $l
|
2020-03-13 14:03:36 +00:00
|
|
|
} else {
|
2021-08-24 18:44:01 +00:00
|
|
|
if (> $i $j) {
|
2021-10-13 18:49:48 +00:00
|
|
|
set i j = $j $i
|
2021-08-24 18:44:01 +00:00
|
|
|
}
|
2020-03-13 14:03:36 +00:00
|
|
|
take $i $l
|
|
|
|
put $l[j]
|
2021-08-24 18:44:01 +00:00
|
|
|
all $l[(+ $i 1)..$j]
|
2020-03-13 14:03:36 +00:00
|
|
|
put $l[$i]
|
|
|
|
drop (+ $j 1) $l
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:09:02 +00:00
|
|
|
fn less {|cb|
|
|
|
|
var l = {|a b| < ($cb $a $b) 0 }
|
2020-07-22 09:24:43 +00:00
|
|
|
put $l
|
|
|
|
}
|
2021-12-11 21:09:02 +00:00
|
|
|
fn sort {|cb @argv| order &less-than=(less $cb) (-p $@argv) }
|