summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-11 17:33:00 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-11 17:33:00 -0800
commit3c32f8de768338c0f64b1218a2f60f85d59c36ce (patch)
tree6465f8b1092d6ab46d4eae1ae9fa910f85b1643c
parent15dda4428072bb741d6bf42fa4906b217fc2aeb1 (diff)
downloadtxr-3c32f8de768338c0f64b1218a2f60f85d59c36ce.tar.gz
txr-3c32f8de768338c0f64b1218a2f60f85d59c36ce.tar.bz2
txr-3c32f8de768338c0f64b1218a2f60f85d59c36ce.zip
* eval.c (eval_init): Register new functions posqual, posql,
posq, pos, and pos_if as intrinsics. * lib.c (posqual, posql, posq, pos, pos_if): New functions. * lib.h (posqual, posql, posq, pos, pos_if): Declared. * txr.1: Documented
-rw-r--r--ChangeLog11
-rw-r--r--eval.c5
-rw-r--r--lib.c66
-rw-r--r--lib.h5
-rw-r--r--txr.162
5 files changed, 149 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index cdc54316..ce8a80ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2014-02-11 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (eval_init): Register new functions posqual, posql,
+ posq, pos, and pos_if as intrinsics.
+
+ * lib.c (posqual, posql, posq, pos, pos_if): New functions.
+
+ * lib.h (posqual, posql, posq, pos, pos_if): Declared.
+
+ * txr.1: Documented
+
+2014-02-11 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (eval_init): Turn a require argument into an optional
one for the functions some, all and none.
diff --git a/eval.c b/eval.c
index 82aa8ea0..92c4afe1 100644
--- a/eval.c
+++ b/eval.c
@@ -2412,6 +2412,11 @@ void eval_init(void)
reg_fun(intern(lit("countql"), user_package), func_n2(countql));
reg_fun(intern(lit("countq"), user_package), func_n2(countq));
reg_fun(intern(lit("count-if"), user_package), func_n3o(count_if, 2));
+ reg_fun(intern(lit("posqual"), user_package), func_n2(posqual));
+ reg_fun(intern(lit("posql"), user_package), func_n2(posql));
+ reg_fun(intern(lit("posq"), user_package), func_n2(posq));
+ reg_fun(intern(lit("pos"), user_package), func_n4o(pos, 2));
+ reg_fun(intern(lit("pos-if"), user_package), func_n3o(pos_if, 2));
reg_fun(intern(lit("some"), user_package), func_n3o(some_satisfy, 1));
reg_fun(intern(lit("all"), user_package), func_n3o(all_satisfy, 1));
reg_fun(intern(lit("none"), user_package), func_n3o(none_satisfy, 1));
diff --git a/lib.c b/lib.c
index 1b0199c2..8787cb8f 100644
--- a/lib.c
+++ b/lib.c
@@ -4793,6 +4793,72 @@ val find_if(val pred, val list, val key)
return nil;
}
+val posqual(val obj, val list)
+{
+ val pos = zero;
+
+ for (; list; list = cdr(list), pos = plus(pos, one))
+ if (equal(car(list), obj))
+ return pos;
+
+ return nil;
+}
+
+val posql(val obj, val list)
+{
+ val pos = zero;
+
+ for (; list; list = cdr(list), pos = plus(pos, one))
+ if (eql(car(list), obj))
+ return pos;
+
+ return nil;
+}
+
+val posq(val obj, val list)
+{
+ val pos = zero;
+
+ for (; list; list = cdr(list), pos = plus(pos, one))
+ if (eq(car(list), obj))
+ return pos;
+
+ return nil;
+}
+
+val pos(val item, val list, val testfun, val keyfun)
+{
+ val pos = zero;
+ testfun = default_arg(testfun, equal_f);
+ keyfun = default_arg(keyfun, identity_f);
+
+ for (; list; list = cdr(list), pos = plus(pos, one)) {
+ val elem = car(list);
+ val key = funcall1(keyfun, elem);
+
+ if (funcall2(testfun, item, key))
+ return pos;
+ }
+
+ return nil;
+}
+
+
+val pos_if(val pred, val list, val key)
+{
+ val pos = zero;
+ key = default_arg(key, identity_f);
+
+ for (; list; list = cdr(list), pos = plus(pos, one)) {
+ val item = car(list);
+ val subj = funcall1(key, item);
+
+ if (funcall1(pred, subj))
+ return pos;
+ }
+
+ return nil;
+}
val set_diff(val list1, val list2, val testfun, val keyfun)
{
diff --git a/lib.h b/lib.h
index 869d3c31..77ca800d 100644
--- a/lib.h
+++ b/lib.h
@@ -679,6 +679,11 @@ val sort(val seq, val lessfun, val keyfun);
val multi_sort(val lists, val funcs, val key_funcs);
val find(val list, val key, val testfun, val keyfun);
val find_if(val pred, val list, val key);
+val posqual(val obj, val list);
+val posql(val obj, val list);
+val posq(val obj, val list);
+val pos(val list, val key, val testfun, val keyfun);
+val pos_if(val pred, val list, val key);
val set_diff(val list1, val list2, val testfun, val keyfun);
val length(val seq);
val sub(val seq, val from, val to);
diff --git a/txr.1 b/txr.1
index 93aca12d..976b4c34 100644
--- a/txr.1
+++ b/txr.1
@@ -7025,6 +7025,68 @@ transformed to an argument to <predicate-function>. If this argument is omitted
then the predicate function is applied to the elements directly, a behavior
which is identical to <key-function> being (fun identity).
+.SS Functions posqual, posql and posq
+
+.TP
+Syntax:
+
+ (posq <object> <list>)
+ (posql <object> <list>)
+ (posqual <object> <list>)
+
+.TP
+Description
+
+The posq, posql and posqual functions return the zero-based position of the
+first item in <list> which is, respectively, eq, eql or equal to <object>.
+
+.SS Functions posqual, posql and posq
+
+.TP
+Syntax:
+
+ (posq <object> <list>)
+ (posql <object> <list>)
+ (posqual <object> <list>)
+
+.TP
+Description
+
+The posq, posql and posqual functions return the zero-based position of the
+first item in <list> which is, respectively, eq, eql or equal to <object>.
+
+.SS Functions pos and pos-if
+
+.TP
+Syntax:
+
+ (pos <key> <list> [<testfun> [<keyfun>]])
+ (pos-if <predfun> <list> [<keyfun>])
+
+.TP
+Description:
+
+The pos and pos-if functions search through a list for an item which
+matches a key, or satisfies a predicate function, respectively.
+They return the zero based position of the matching item.
+
+The keyfun argument specifies a function which is applied to the elements
+of the list to produce the comparison key. If this argument is omitted,
+then the untransformed elements of the list themselves are searched.
+
+The pos function's testfun argument specifies the test function which
+is used to compare the comparison keys from the list to the search key.
+If this argument is omitted, then the equal function is used.
+The position of the first element from the list whose comparison key (as
+retrieved by the key function) matches the search (under the test function) is
+returned. If no such element is found, nil is returned.
+
+The pos-if function's predfun argument specifies a predicate function
+which is applied to the successive comparison keys pulled from the list
+by applying the key function to successive elements. The position of
+the first element for which the predicate function yields true is returned. If
+no such element is found, nil is returned.
+
.SS Function tree-find
.TP