diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-03-23 02:09:05 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-03-23 02:09:05 -0700 |
commit | f456fef7fb28cfa3ed5872b778219e5dc02c442b (patch) | |
tree | 7a06683073ba89522f162cc3fa49f143141d2b4e | |
parent | 93e2bea59699815979259cc2b2d8adffcc852ec9 (diff) | |
download | txr-f456fef7fb28cfa3ed5872b778219e5dc02c442b.tar.gz txr-f456fef7fb28cfa3ed5872b778219e5dc02c442b.tar.bz2 txr-f456fef7fb28cfa3ed5872b778219e5dc02c442b.zip |
* eval.c (not_s): New symbol var.
(me_unless, me_while, m_until): New static functions.
(eval_init): Register macros unless, while and until.
* txr.1: Document unless, while and until.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | eval.c | 29 | ||||
-rw-r--r-- | txr.1 | 40 |
3 files changed, 72 insertions, 5 deletions
@@ -1,3 +1,11 @@ +2014-03-23 Kaz Kylheku <kaz@kylheku.com> + + * eval.c (not_s): New symbol var. + (me_unless, me_while, m_until): New static functions. + (eval_init): Register macros unless, while and until. + + * txr.1: Document unless, while and until. + 2014-03-22 Kaz Kylheku <kaz@kylheku.com> Version 87 @@ -73,7 +73,7 @@ val dyn_env; val eval_error_s; val dwim_s, progn_s, prog1_s, let_s, let_star_s, lambda_s, call_s; val cond_s, if_s, defvar_s, defun_s, defmacro_s, tree_case_s, tree_bind_s; -val inc_s, dec_s, push_s, pop_s, flip_s, gethash_s, car_s, cdr_s; +val inc_s, dec_s, push_s, pop_s, flip_s, gethash_s, car_s, cdr_s, not_s; val del_s, vecref_s; val for_s, for_star_s, each_s, each_star_s, collect_each_s, collect_each_star_s; val append_each_s, append_each_star_s; @@ -2027,6 +2027,27 @@ static val me_when(val form, val menv) return cons(cond_s, cons(rest(form), nil)); } +static val me_unless(val form, val menv) +{ + (void) menv; + return list(if_s, second(form), nil, cons(progn_s, rest(rest(form))), nao); +} + +static val me_while(val form, val menv) +{ + (void) menv; + return apply_frob_args(list(for_s, nil, cons(second(form), nil), nil, + rest(rest(form)), nao)); +} + +static val me_until(val form, val menv) +{ + val inv = cons(not_s, cons(second(form), nil)); + (void) menv; + return apply_frob_args(list(for_s, nil, cons(inv, nil), nil, + rest(rest(form)), nao)); +} + val expand_forms(val form, val menv) { if (atom(form)) { @@ -3104,6 +3125,7 @@ void eval_init(void) gethash_s = intern(lit("gethash"), user_package); car_s = intern(lit("car"), user_package); cdr_s = intern(lit("cdr"), user_package); + not_s = intern(lit("not"), user_package); vecref_s = intern(lit("vecref"), user_package); list_s = intern(lit("list"), user_package); append_s = intern(lit("append"), user_package); @@ -3186,6 +3208,9 @@ void eval_init(void) reg_mac(sys_qquote_s, me_qquote); reg_mac(intern(lit("pprof"), user_package), me_pprof); reg_mac(intern(lit("when"), user_package), me_when); + reg_mac(intern(lit("unless"), user_package), me_unless); + reg_mac(intern(lit("while"), user_package), me_while); + reg_mac(intern(lit("until"), user_package), me_until); reg_fun(cons_s, func_n2(cons)); reg_fun(intern(lit("make-lazy-cons"), user_package), func_n1(make_lazy_cons)); @@ -3207,7 +3232,7 @@ void eval_init(void) reg_fun(intern(lit("atom"), user_package), func_n1(atom)); reg_fun(intern(lit("null"), user_package), func_n1(null)); - reg_fun(intern(lit("not"), user_package), func_n1(null)); + reg_fun(not_s, func_n1(null)); reg_fun(intern(lit("consp"), user_package), func_n1(consp)); reg_fun(intern(lit("listp"), user_package), func_n1(listp)); reg_fun(intern(lit("proper-listp"), user_package), func_n1(proper_listp)); @@ -5580,21 +5580,55 @@ If the first form of a group yields nil, then processing continues with the next group, if any. If all form groups yield nil, then the cond form yields nil. This holds in the case that the syntax is empty: (cond) yields nil. -.SS Macro when +.SS Macros when and unless .TP Syntax: - (when <expression> {<form>}*) + (when <expression> <form>*) + (unless <expression> <form>*) .TP Description: The when macro operator evaluates <expression>. If <expression> yields -true, and there are additiona forms, then each <form> is evaluated. +true, and there are additional forms, then each <form> is evaluated. The value of the last form is becomes the result value of the when form. If there are no forms, then the result is nil. +The unless operator is similar to when, except that it reverses the +logic of the test. The forms, if any, are evaluated if, and only if +<expression> is false. + +.SS Macros while and until + +.TP +Syntax: + + (while <expression> <form>*) + (until <expression> <form>*) + +.TP +Description: + +The while macro operator provides a looping construct. It evaluates +<expression>. If <expression> yields nil, then the evaluation of the while form +terminates, producing the value nil. Otherwise, if there are additional forms, +then each <form> is evaluated. Next, evaluation returns to <expression>, +repeating all of the previous steps. + +The until macro operator is similar to while, except that the until form +terminates when <expression> evaluates true, rather than false. + +These operators arrange for the evaluation of all their enclosed forms +in an anonymous block. Any of the <form>-s, or <expression>, may use +the return operator to terminate the loop, and optionally to specify +a result value for the form. + +The only way these forms can yield a value other than nil is if +the return operator is used to terminate the implicit anonymous block, +and is given an argument, which becomes the result value. + .SS Operator/function if .TP |