diff options
author | Paul A. Patience <paul@apatience.com> | 2022-01-22 03:19:07 -0500 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-01-22 22:28:39 -0800 |
commit | 004e1208708fa7ed0538c391c42411e36ddac431 (patch) | |
tree | 499c8d691cd83f708590058ffdc0ba67514e8ecd | |
parent | 912954cca7ed1d778a2ee7f416e0461845836c7c (diff) | |
download | txr-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.c | 28 | ||||
-rw-r--r-- | lib.c | 10 | ||||
-rw-r--r-- | lib.h | 2 | ||||
-rw-r--r-- | stdlib/doc-syms.tl | 4 | ||||
-rw-r--r-- | txr.1 | 159 |
5 files changed, 171 insertions, 32 deletions
@@ -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)); @@ -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); @@ -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") @@ -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 ]]) |