diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-04-16 06:28:11 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-04-16 06:28:11 -0700 |
commit | 906f11fb2104c4f6f9770c0c4d747cf44c13bfe6 (patch) | |
tree | 9a2ec92d6e9968dd68e4058dac3d7341dab35ad6 | |
parent | 56beef8defcb5944be1ee523400b382119dbe8fc (diff) | |
download | txr-906f11fb2104c4f6f9770c0c4d747cf44c13bfe6.tar.gz txr-906f11fb2104c4f6f9770c0c4d747cf44c13bfe6.tar.bz2 txr-906f11fb2104c4f6f9770c0c4d747cf44c13bfe6.zip |
Adding dotimes macro.
* eval.c (me_dotimes): New function.
(eval_init): Registering dotimes macro.
* txr.1: Documented dotimes.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | eval.c | 21 | ||||
-rw-r--r-- | txr.1 | 41 |
3 files changed, 71 insertions, 0 deletions
@@ -1,3 +1,12 @@ +2015-04-16 Kaz Kylheku <kaz@kylheku.com> + + Adding dotimes macro. + + * eval.c (me_dotimes): New function. + (eval_init): Registering dotimes macro. + + * txr.1: Documented dotimes. + 2015-04-15 Kaz Kylheku <kaz@kylheku.com> Fix escaping issues in open-process on Windows. @@ -2836,6 +2836,26 @@ static val me_iflet_whenlet(val form, val env) cons(car(car(lastlet)), args)), nao); } +static val me_dotimes(val form, val env) +{ + val count = gensym(lit("count-")); + val args = rest(form); + val spec = pop(&args); + val counter = pop(&spec); + val count_form = pop(&spec); + val result = pop(&spec); + val body = args; + val lt = intern(lit("<"), user_package); + val raw = list(for_s, list(list(counter, zero, nao), + list(count, count_form, nao), + nao), + list(list(lt, counter, count, nao), result, nao), + list(list(inc_s, counter, nao), nao), + body, nao); + + return apply_frob_args(raw); +} + static val expand_catch_clause(val form, val menv) { val sym = first(form); @@ -3976,6 +3996,7 @@ void eval_init(void) reg_mac(intern(lit("whilet"), user_package), me_whilet); reg_mac(iflet_s, me_iflet_whenlet); reg_mac(intern(lit("whenlet"), user_package), me_iflet_whenlet); + reg_mac(intern(lit("dotimes"), user_package), me_dotimes); reg_fun(cons_s, func_n2(cons)); reg_fun(intern(lit("make-lazy-cons"), user_package), func_n1(make_lazy_cons)); @@ -10370,6 +10370,47 @@ is returned. (format t "frobosity value ~a exceeds 150\en" fv)) .cble +.coNP Macro @ dotimes +.synb +.mets (dotimes >> ( var < count-form <> [ result-form ]) << body-form *) +.syne +.desc +The +.code dotimes +macro implements a simple counting loop. +.meta var +is established as a variable, and initialized to zero. +.meta count-form +is evaluated one time to produce a limiting value, which should be a number. +Then, if the value of +.meta var +is less than the limiting value, the +.metn body-form -s +are evaluated, +.meta var +is incremented by one, and the process repeats with a new comparison +of +.meta var +against the limiting value possibly leading to another evaluation of +the forms. + +If +.meta var +is found to equal or exceed the limiting value, then the loop terminates. + +When the loop terminates, its return value is +.code nil +unless a +.meta result-form +is present, in which case the value of that form specifies the return value. + +.metn body-form -s +as well as +.meta result-form +are evaluated in the scope in which the binding of +.meta var +is visible. + .coNP Operator @ unwind-protect .synb .mets (unwind-protect < protected-form << cleanup-form *) |