summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul A. Patience <paul@apatience.com>2022-01-22 03:19:07 -0500
committerKaz Kylheku <kaz@kylheku.com>2022-01-22 22:28:39 -0800
commit004e1208708fa7ed0538c391c42411e36ddac431 (patch)
tree499c8d691cd83f708590058ffdc0ba67514e8ecd
parent912954cca7ed1d778a2ee7f416e0461845836c7c (diff)
downloadtxr-004e1208708fa7ed0538c391c42411e36ddac431.tar.gz
txr-004e1208708fa7ed0538c391c42411e36ddac431.tar.bz2
txr-004e1208708fa7ed0538c391c42411e36ddac431.zip
lib: new functions nand, nor, nandf and norf.
* eval.c (me_nand, me_nor, nor_fun, nand_fun): New functions. (eval_init): Register new intrinsics. * lib.c (nandv, norv): New functions. * lib.h (nandv, norv): Declared. * txr.1: Documented, along with trivial fixes to the descriptions of and, or, andf, orf and notf. * stdlib/doc-syms.tl: Updated.
-rw-r--r--eval.c28
-rw-r--r--lib.c10
-rw-r--r--lib.h2
-rw-r--r--stdlib/doc-syms.tl4
-rw-r--r--txr.1159
5 files changed, 171 insertions, 32 deletions
diff --git a/eval.c b/eval.c
index a1c6b8b4..15936205 100644
--- a/eval.c
+++ b/eval.c
@@ -3279,6 +3279,18 @@ static val rt_pprof(val prof_list)
return retval;
}
+static val me_nand(val form, val menv)
+{
+ (void) menv;
+ return list(not_s, cons(and_s, cdr(form)), nao);
+}
+
+static val me_nor(val form, val menv)
+{
+ (void) menv;
+ return list(not_s, cons(or_s, cdr(form)), nao);
+}
+
static val me_when(val form, val menv)
{
(void) menv;
@@ -6356,6 +6368,11 @@ static val or_fun(struct args *vals)
return nil;
}
+static val nor_fun(struct args *vals)
+{
+ return tnil(!or_fun(vals));
+}
+
static val and_fun(struct args *vals)
{
val item = t;
@@ -6370,6 +6387,11 @@ static val and_fun(struct args *vals)
return item;
}
+static val nand_fun(struct args *vals)
+{
+ return tnil(!and_fun(vals));
+}
+
static val progn_fun(struct args *vals)
{
return if3(vals->list, car(lastcons(vals->list)), vals->arg[vals->fill - 1]);
@@ -6816,6 +6838,8 @@ void eval_init(void)
reg_mac(sys_qquote_s, me_qquote_f);
reg_mac(intern(lit("equot"), user_package), func_n2(me_equot));
reg_mac(intern(lit("pprof"), user_package), func_n2(me_pprof));
+ reg_mac(intern(lit("nand"), user_package), func_n2(me_nand));
+ reg_mac(intern(lit("nor"), user_package), func_n2(me_nor));
reg_mac(when_s, func_n2(me_when));
reg_mac(intern(lit("unless"), user_package), func_n2(me_unless));
reg_mac(while_s, me_while_until_f);
@@ -7089,13 +7113,17 @@ void eval_init(void)
reg_fun(intern(lit("andf"), user_package), func_n0v(andv));
reg_fun(intern(lit("orf"), user_package), func_n0v(orv));
reg_fun(intern(lit("notf"), user_package), func_n1(notf));
+ reg_fun(intern(lit("nandf"), user_package), func_n0v(nandv));
+ reg_fun(intern(lit("norf"), user_package), func_n0v(norv));
reg_fun(intern(lit("iff"), user_package), func_n3o(iff, 1));
reg_fun(intern(lit("iffi"), user_package), func_n3o(iffi, 2));
reg_fun(intern(lit("dup"), user_package), func_n1(dupl));
reg_fun(intern(lit("flipargs"), user_package), func_n1(swap_12_21));
reg_fun(if_s, func_n3o(if_fun, 2));
reg_fun(or_s, func_n0v(or_fun));
+ reg_fun(intern(lit("nor"), user_package), func_n0v(nor_fun));
reg_fun(and_s, func_n0v(and_fun));
+ reg_fun(intern(lit("nand"), user_package), func_n0v(nand_fun));
reg_fun(progn_s, func_n0v(progn_fun));
reg_fun(prog1_s, func_n0v(prog1_fun));
reg_fun(prog2_s, func_n0v(prog2_fun));
diff --git a/lib.c b/lib.c
index 91768c3a..b926f051 100644
--- a/lib.c
+++ b/lib.c
@@ -8862,6 +8862,16 @@ val notf(val fun)
return func_f0v(fun, do_not);
}
+val nandv(struct args *funlist)
+{
+ return notf(andv(funlist));
+}
+
+val norv(struct args *funlist)
+{
+ return notf(orv(funlist));
+}
+
static val do_iff(val env, struct args *args_in)
{
cons_bind (condfun, choices, env);
diff --git a/lib.h b/lib.h
index 0961cefd..83437b61 100644
--- a/lib.h
+++ b/lib.h
@@ -1090,6 +1090,8 @@ val andv(struct args *funlist);
val orf(val first_fun, ...);
val orv(struct args *funlist);
val notf(val fun);
+val nandv(struct args *funlist);
+val norv(struct args *funlist);
val iff(val condfun, val thenfun, val elsefun);
val iffi(val condfun, val thenfun, val elsefun);
val dupl(val fun);
diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl
index 676323a4..dc8424a5 100644
--- a/stdlib/doc-syms.tl
+++ b/stdlib/doc-syms.tl
@@ -1303,6 +1303,8 @@
("n-choose-k" "N-02ACFDE6")
("n-perm-k" "N-02ACFDE6")
("name" "N-01557906")
+ ("nand" "N-01EB4CCB")
+ ("nandf" "N-00C18907")
("ncon" "N-022F6E60")
("ncon*" "N-022F6E60")
("nconc" "N-0014162F")
@@ -1325,6 +1327,8 @@
("nlink-t" "N-01153D9E")
("noflsh" "N-0072FF5E")
("none" "D-006B")
+ ("nor" "N-03662D87")
+ ("norf" "N-00C18907")
("not" "D-0069")
("notf" "N-0026CE18")
("nr" "N-03A7AE6D")
diff --git a/txr.1 b/txr.1
index edbdd5f0..d6c7f39d 100644
--- a/txr.1
+++ b/txr.1
@@ -16443,7 +16443,7 @@ operator and an
function. A list form with the
symbol
.code and
-in the fist position is interpreted as an invocation of the
+in the first position is interpreted as an invocation of the
operator. The function can be accessed using the DWIM bracket notation and in
other ways.
@@ -16465,22 +16465,25 @@ The
.metn form s,
if any, are
evaluated from left to right. The return value is overwritten with
-the result of each form. Evaluation stops when all forms are exhausted,
-or when
+the result of each
+.metn form .
+Evaluation stops when all
+.metn form s
+are exhausted, or when
.code nil
is stored in the return value.
When evaluation stops, the operator yields the return value.
The
.code and
-function provides no evaluation control; it receives all of its
+function provides no evaluation control: it receives all of its
arguments fully evaluated. If it is given no arguments, it returns
.codn t .
If it is given one or more arguments, and any of them are
.codn nil ,
it returns
.codn nil .
-Otherwise it returns the value of the last argument.
+Otherwise, it returns the value of the last argument.
.TP* Examples:
.verb
@@ -16489,6 +16492,35 @@ Otherwise it returns the value of the last argument.
(and 1 2 3) -> 3 ;; shorthand for (if (and 1 2) 3).
.brev
+.coNP Macro/function @ nand
+.synb
+.mets (nand << form *)
+.mets '['nand << arg *']'
+.syne
+.desc
+There exist both a
+.code nand
+macro and a
+.code nand
+function.
+A list form with the symbol
+.code nand
+in the first position is interpreted as an invocation of the macro.
+The function can be accessed using the DWIM bracket notation and in
+other ways.
+
+The
+.code nand
+macro and function are the logical negation of the
+.code and
+operator and function.
+They are related according to the following equivalences:
+
+.verb
+ (nand f0 f1 f2 ...) <--> (not (and f0 f1 f2 ...))
+ [nand f0 f1 f2 ...] <--> (not [and f0 f1 f2 ...])
+.brev
+
.coNP Operator/function @ or
.synb
.mets (or << form *)
@@ -16502,16 +16534,19 @@ operator and an
function. A list form with the
symbol
.code or
-in the fist position is interpreted as an invocation of the
+in the first position is interpreted as an invocation of the
operator. The function can be accessed using the DWIM bracket notation and in
other ways.
-The or operator provides three functionalities in one. It computes the
+The
+.code or
+operator provides three functionalities in one. It computes the
logical "or" function over several forms. It controls evaluation (a.k.a.
"short-circuiting"). The behavior of
.code or
-also provides an idiom for the selection of the first non-nil value from a
-sequence of forms.
+also provides an idiom for the selection of the first
+.cod2 non- nil
+value from a sequence of forms.
The
.code or
@@ -16524,13 +16559,14 @@ if any,
are evaluated from left to right. The return value is overwritten
with the result of each
.metn form .
-Evaluation stops when all forms are
-exhausted, or when a true value is stored into the return value.
+Evaluation stops when all
+.metn form s
+are exhausted, or when a true value is stored into the return value.
When evaluation stops, the operator yields the return value.
The
.code or
-function provides no evaluation control; it receives all of its
+function provides no evaluation control: it receives all of its
arguments fully evaluated. If it is given no arguments, it returns
.codn nil .
If all of its arguments are
@@ -16549,6 +16585,35 @@ returns the value of the first argument which isn't
(or (> 10 20) (stringp "foo")) -> t
.brev
+.coNP Macro/function @ nor
+.synb
+.mets (nor << form *)
+.mets '['nor << arg *']'
+.syne
+.desc
+There exist both a
+.code nor
+macro and a
+.code nor
+function.
+A list form with the symbol
+.code nor
+in the first position is interpreted as an invocation of the macro.
+The function can be accessed using the DWIM bracket notation and in
+other ways.
+
+The
+.code nor
+macro and function are the logical negation of the
+.code or
+operator and function.
+They are related according to the following equivalences:
+
+.verb
+ (nor f0 f1 f2 ...) <--> (not (or f0 f1 f2 ...))
+ [nor f0 f1 f2 ...] <--> (not [or f0 f1 f2 ...])
+.brev
+
.coNP Macros @ when and @ unless
.synb
.mets (when < expression << form *)
@@ -56866,37 +56931,45 @@ resulting combined function is then callable with that many arguments.
The
.code andf
function returns a function which combines the input functions with
-a short-circuiting logical conjunction. The resulting function passes its
-arguments to the functions successively, in left-to-right order. As soon as any
-of the functions returns
+a short-circuiting logical conjunction.
+The resulting function passes its arguments to the input functions
+successively,
+in left-to-right order.
+As soon as any of the functions returns
.codn nil ,
-then nil is returned immediately, and the
-remaining functions are not called. Otherwise, if none of the functions return
+then
+.code nil
+is returned and the remaining functions are not called.
+If none of the functions return
.codn nil ,
-then the value returned by the last function is returned. If the list of
-functions is empty, then
+then the value returned by the last function is returned.
+If the list of functions is empty, then
.code t
-is returned. That is,
+is returned.
+That is,
.code (andf)
-returns a function
-which accepts any arguments, and returns
+returns a function which accepts any arguments and returns
.codn t .
The
.code orf
-function combines the input functions with a short-circuiting logical
-disjunction. The function produced by
-.code orf
-passes its arguments down to the
-functions successively, in left-to-right order. As soon as any function
-returns a
+function returns a function which combines the input functions with
+a short-circuiting logical disjunction.
+The resulting function passes its arguments to the input functions
+successively,
+in left-to-right order.
+As soon as any of the functions returns a
.cod2 non- nil
-value, that value is returned and the remaining functions are
-not called. If all functions return
+value, that value is returned and the remaining functions are not called.
+If all of the functions return
.codn nil ,
then
.code nil
-is returned. The expression
+is returned.
+If the list of functions is empty, then
+.code nil
+is returned.
+That is,
.code (orf)
returns a function which accepts any arguments and returns
.codn nil .
@@ -56915,9 +56988,31 @@ of
The returned function takes a variable number of arguments. When
invoked, it passes all of these arguments to
.meta function
-and then inverts the result as if by application of the
+and then inverts the result as if by application of
.codn not .
+.coNP Functions @ nandf and @ norf
+.synb
+.mets (nandf << func *)
+.mets (norf << func *)
+.syne
+.desc
+The
+.code nandf
+and
+.code norf
+functions are the logical negation of the
+.code andf
+and
+.code orf
+functions.
+They are related according to the following equivalences:
+
+.verb
+ [nandf f0 f1 f2 ...] <--> (notf [andf f0 f1 f2 ...])
+ [norf f0 f1 f2 ...] <--> (notf [orf f0 f1 f2 ...])
+.brev
+
.coNP Functions @ iff and @ iffi
.synb
.mets (iff < condfun >> [ thenfun <> [ elsefun ]])