diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-11-23 06:42:52 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-11-23 06:42:52 -0800 |
commit | cdb62673a886801298c543346c2186f0e054ca6e (patch) | |
tree | 3dcdec25ff587329df02b76623c78a13dce9c7e6 /lib.c | |
parent | 3f4b4dc10fa7e2d099b2ba0dfef78c108a671ec9 (diff) | |
download | txr-cdb62673a886801298c543346c2186f0e054ca6e.tar.gz txr-cdb62673a886801298c543346c2186f0e054ca6e.tar.bz2 txr-cdb62673a886801298c543346c2186f0e054ca6e.zip |
New function: grade.
Inspired by APL.
* eval.c (eval_init): Register grade intrinsic.
* lib.c (grade): New function.
* lib.h (grade): Declared.
* txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 43 |
1 files changed, 43 insertions, 0 deletions
@@ -8398,6 +8398,49 @@ val uniq(val seq) return unique(seq, identity_f, hashv_args); } +val grade(val seq, val lessfun, val keyfun_in) +{ + val self = lit("grade"); + seq_info_t si = seq_info(seq); + + if (si.kind != SEQ_NIL) { + val keyfun = if3(missingp(keyfun_in), + car_f, + chain(car_f, keyfun_in, nao)); + cnum i, len = c_fixnum(length(seq), self); + val iter, v = vector(num_fast(len), nil); + + switch (si.kind) { + case SEQ_LISTLIKE: + for (iter = si.obj, i = 0; i < len; i++, iter = cdr(iter)) { + set(mkloc(v->v.vec[i], v), cons(car(iter), num_fast(i))); + } + break; + case SEQ_VECLIKE: + for (i = 0; i < len; i++) { + val ix = num_fast(i); + set(mkloc(v->v.vec[i], v), cons(ref(seq, ix), ix)); + } + break; + default: + uw_throwf(error_s, lit("~a: unsupported object ~s"), self, seq, nao); + } + + { + list_collect_decl (out, ptail); + + sort(v, lessfun, keyfun); + + for (i = 0; i < len; i++) + ptail = list_collect(ptail, cdr(v->v.vec[i])); + + return out; + } + } + + return nil; +} + val find(val item, val seq, val testfun, val keyfun) { val self = lit("find"); |