From 4477112731119ebc28d5e4a9dce858d8d008af36 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 14 Feb 2019 06:46:45 -0800 Subject: symdiff: new function. * eval.c (eval_init): Register symdiff intrinsic. * lib.c (symdiff): New function. * lib.h (us_car_p, us_cdr_p): New inline functions. (symdiff): Declared. * txr.1: Documented, also fixing issues not related to symdiff doc. --- lib.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'lib.c') diff --git a/lib.c b/lib.c index f5a3d920..b56a4a5b 100644 --- a/lib.c +++ b/lib.c @@ -9994,6 +9994,49 @@ val set_diff(val list1, val list2, val testfun, val keyfun) return make_like(out, list_orig); } +val symdiff(val seq1, val seq2, val testfun, val keyfun) +{ + val self = lit("symdiff"); + list_collect_decl (out, ptail); + seq_iter_t si1, si2; + val el1, el2; + + testfun = default_arg(testfun, equal_f); + keyfun = default_arg(keyfun, identity_f); + + seq_iter_init(self, &si1, seq1); + seq_iter_init(self, &si2, seq2); + + while (seq_get(&si1, &el1)) + ptail = list_collect(ptail, el1); + + while (seq_get(&si2, &el2)) { + val el2_key = funcall1(keyfun, el2); + val *iter; + int found = 0; + + for (iter = &out; *iter; ) { + val elo = us_car(*iter); + val elo_key = funcall1(keyfun, elo); + if (funcall2(testfun, elo_key, el2_key)) { + val del = us_cdr(*iter); + if (deref(ptail) == del) + ptail = mkcloc(*iter); + *iter = del; + found = 1; + break; + } else { + iter = us_cdr_p(*iter); + } + } + + if (!found) + ptail = list_collect(ptail, el2); + } + + return make_like(out, seq1); +} + val isec(val seq1, val seq2, val testfun, val keyfun) { val self = lit("isec"); -- cgit v1.2.3