diff options
-rw-r--r-- | lib.c | 258 | ||||
-rw-r--r-- | lib.h | 16 |
2 files changed, 136 insertions, 138 deletions
@@ -1519,179 +1519,177 @@ val rmember_if(val pred, val list, val key) return found; } -val remq(val obj, val list_orig, val keyfun) +static val rem_impl(val (*eqfun)(val, val), + val obj, val seq_in, val keyfun_in) { - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); + val keyfun = default_bool_arg(keyfun_in); - keyfun = default_bool_arg(keyfun); + switch (type(seq_in)) { + case NIL: + return nil; + case CONS: + case LCONS: + case COBJ: + { + list_collect_decl (out, ptail); + val list = seq_in; + val lastmatch = cons(nil, list); - gc_hint(list); + gc_hint(list); - for (; list; list = cdr(list)) { - val elem = car(list); - val key = keyfun ? funcall1(keyfun, elem) : elem; + for (; list; list = cdr(list)) { + val elem = car(list); + val key = keyfun ? funcall1(keyfun, elem) : elem; - if (key == obj) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; + if (eqfun(key, obj)) { + ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); + lastmatch = list; + } + } + ptail = list_collect_nconc(ptail, cdr(lastmatch)); + return out; } - } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); -} - -val remql(val obj, val list_orig, val keyfun) -{ - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); - - keyfun = default_bool_arg(keyfun); + case LIT: + case STR: + case LSTR: + { + val out = mkustring(zero); + val str = seq_in; + cnum len = c_num(length_str(str)), i; - gc_hint(list); + for (i = 0; i < len; i++) { + val elem = chr_str(str, num_fast(i)); + val key = keyfun ? funcall1(keyfun, elem) : elem; - for (; list; list = cdr(list)) { - val elem = car(list); - val key = keyfun ? funcall1(keyfun, elem) : elem; + if (!eqfun(key, obj)) + string_extend(out, elem); + } - if (eql(key, obj)) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; + return out; } - } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); -} - -val remqual(val obj, val list_orig, val keyfun) -{ - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); - - keyfun = default_bool_arg(keyfun); + case VEC: + { + val out = vector(zero, nil); + val vec = seq_in; + cnum len = c_num(length_vec(vec)), i; - gc_hint(list); + for (i = 0; i < len; i++) { + val elem = vecref(vec, num_fast(i)); + val key = keyfun ? funcall1(keyfun, elem) : elem; - for (; list; list = cdr(list)) { - val elem = car(list); - val key = keyfun ? funcall1(keyfun, elem) : elem; + if (!eqfun(key, obj)) + vec_push(out, elem); + } - if (equal(key, obj)) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; + return out; } + default: + uw_throwf(error_s, lit("remq: ~s isn't a sequence"), in, nao); } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); } -val remove_if(val pred, val list_orig, val key) +val remove_if(val pred, val seq_in, val keyfun_in) { - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); + val keyfun = default_bool_arg(keyfun_in); - key = default_arg(key, identity_f); + switch (type(seq_in)) { + case NIL: + return nil; + case CONS: + case LCONS: + case COBJ: + { + list_collect_decl (out, ptail); + val list = seq_in; + val lastmatch = cons(nil, list); - gc_hint(list); + gc_hint(list); - for (; list; list = cdr(list)) { - val subj = funcall1(key, car(list)); - val satisfies = funcall1(pred, subj); + for (; list; list = cdr(list)) { + val elem = car(list); + val key = keyfun ? funcall1(keyfun, elem) : elem; - if (satisfies) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; + if (funcall1(pred, key)) { + ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); + lastmatch = list; + } + } + ptail = list_collect_nconc(ptail, cdr(lastmatch)); + return out; } - } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); -} - -val keepq(val obj, val list_orig, val key) -{ - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); + case LIT: + case STR: + case LSTR: + { + val out = mkustring(zero); + val str = seq_in; + cnum len = c_num(length_str(str)), i; - key = default_arg(key, identity_f); + for (i = 0; i < len; i++) { + val elem = chr_str(str, num_fast(i)); + val key = keyfun ? funcall1(keyfun, elem) : elem; - gc_hint(list); + if (!funcall1(pred, key)) + string_extend(out, elem); + } - for (; list; list = cdr(list)) { - if (funcall1(key, car(list)) != obj) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; + return out; } - } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); -} - -val keepql(val obj, val list_orig, val key) -{ - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); + case VEC: + { + val out = vector(zero, nil); + val vec = seq_in; + cnum len = c_num(length_vec(vec)), i; - key = default_arg(key, identity_f); + for (i = 0; i < len; i++) { + val elem = vecref(vec, num_fast(i)); + val key = keyfun ? funcall1(keyfun, elem) : elem; - gc_hint(list); + if (!funcall1(pred, key)) + vec_push(out, elem); + } - for (; list; list = cdr(list)) { - if (!eql(funcall1(key, car(list)), obj)) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; + return out; } + default: + uw_throwf(error_s, lit("remq: ~s isn't a sequence"), in, nao); } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); } -val keepqual(val obj, val list_orig, val key) -{ - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); - - key = default_arg(key, identity_f); - gc_hint(list); +val remq(val obj, val seq, val keyfun) +{ + return rem_impl(eq, obj, seq, keyfun); +} - for (; list; list = cdr(list)) { - if (!equal(funcall1(key, car(list)), obj)) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; - } - } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); +val remql(val obj, val seq, val keyfun) +{ + return rem_impl(eql, obj, seq, keyfun); } -val keep_if(val pred, val list_orig, val key) +val remqual(val obj, val seq, val keyfun) { - list_collect_decl (out, ptail); - val list = tolist(list_orig); - val lastmatch = cons(nil, list); + return rem_impl(equal, obj, seq, keyfun); +} - key = default_arg(key, identity_f); +val keepq(val obj, val seq, val keyfun) +{ + return rem_impl(neq, obj, seq, keyfun); +} - gc_hint(list); +val keepql(val obj, val seq, val keyfun) +{ + return rem_impl(neql, obj, seq, keyfun); +} - for (; list; list = cdr(list)) { - val subj = funcall1(key, car(list)); - val satisfies = funcall1(pred, subj); +val keepqual(val obj, val seq, val keyfun) +{ + return rem_impl(nequal, obj, seq, keyfun); +} - if (!satisfies) { - ptail = list_collect_nconc(ptail, ldiff(cdr(lastmatch), list)); - lastmatch = list; - } - } - ptail = list_collect_nconc(ptail, cdr(lastmatch)); - return make_like(out, list_orig); +val keep_if(val pred, val seq, val keyfun) +{ + return remove_if(notf(pred), seq, keyfun); } static val rem_lazy_rec(val obj, val list, val env, val func); @@ -557,14 +557,14 @@ val member(val item, val list, val testfun, val keyfun); val rmember(val item, val list, val testfun, val keyfun); val member_if(val pred, val list, val key); val rmember_if(val pred, val list, val key); -val remq(val obj, val list, val keyfun); -val remql(val obj, val list, val keyfun); -val remqual(val obj, val list, val keyfun); -val remove_if(val pred, val list, val key); -val keepq(val obj, val list_orig, val key); -val keepql(val obj, val list_orig, val key); -val keepqual(val obj, val list_orig, val key); -val keep_if(val pred, val list, val key); +val remq(val obj, val seq, val keyfun); +val remql(val obj, val seq, val keyfun); +val remqual(val obj, val seq, val keyfun); +val remove_if(val pred, val seq, val keyfun); +val keepq(val obj, val seq, val keyfun); +val keepql(val obj, val seq, val keyfun); +val keepqual(val obj, val seq, val keyfun); +val keep_if(val pred, val seq, val keyfun); val remq_lazy(val obj, val list); val remql_lazy(val obj, val list); val remqual_lazy(val obj, val list); |