summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-04-16 06:28:11 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-04-16 06:28:11 -0700
commit906f11fb2104c4f6f9770c0c4d747cf44c13bfe6 (patch)
tree9a2ec92d6e9968dd68e4058dac3d7341dab35ad6
parent56beef8defcb5944be1ee523400b382119dbe8fc (diff)
downloadtxr-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--ChangeLog9
-rw-r--r--eval.c21
-rw-r--r--txr.141
3 files changed, 71 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index b06f0dab..a9bc47a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/eval.c b/eval.c
index 4c44614b..e10a0057 100644
--- a/eval.c
+++ b/eval.c
@@ -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));
diff --git a/txr.1 b/txr.1
index 6b7c013c..e1c1394c 100644
--- a/txr.1
+++ b/txr.1
@@ -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 *)