aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2020-12-25 08:19:54 +1000
committerSteve Bennett <steveb@workware.net.au>2020-12-26 18:08:30 +1000
commit0127e81ddcc824d2985e5c63dd2942689b5d39e3 (patch)
treed5f9ba387846cc30960cdf513931c3c0b0825dd3
parent5283ac52f4b93748b5aac560cd26ae0a71153a63 (diff)
downloadjimtcl-0127e81ddcc824d2985e5c63dd2942689b5d39e3.zip
jimtcl-0127e81ddcc824d2985e5c63dd2942689b5d39e3.tar.gz
jimtcl-0127e81ddcc824d2985e5c63dd2942689b5d39e3.tar.bz2
loop: Allow start value to be omitted
It is convenient to be able to do just: loop i 5 { body } Where the start value is 0. Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c23
-rw-r--r--jim_tcl.txt6
-rw-r--r--tests/loop.test8
3 files changed, 28 insertions, 9 deletions
diff --git a/jim.c b/jim.c
index bd5a819..bfec675 100644
--- a/jim.c
+++ b/jim.c
@@ -12198,17 +12198,26 @@ static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
jim_wide incr = 1;
Jim_Obj *bodyObjPtr;
- if (argc != 5 && argc != 6) {
- Jim_WrongNumArgs(interp, 1, argv, "var first limit ?incr? body");
+ if (argc < 4 || argc > 6) {
+ Jim_WrongNumArgs(interp, 1, argv, "var ?first? limit ?incr? body");
return JIM_ERR;
}
- if (Jim_GetWideExpr(interp, argv[2], &i) != JIM_OK ||
- Jim_GetWideExpr(interp, argv[3], &limit) != JIM_OK ||
- (argc == 6 && Jim_GetWideExpr(interp, argv[4], &incr) != JIM_OK)) {
- return JIM_ERR;
+ retval = Jim_GetWideExpr(interp, argv[2], &i);
+ if (argc > 4 && retval == JIM_OK) {
+ retval = Jim_GetWideExpr(interp, argv[3], &limit);
+ }
+ if (argc > 5 && retval == JIM_OK) {
+ Jim_GetWideExpr(interp, argv[4], &incr);
+ }
+ if (retval != JIM_OK) {
+ return retval;
+ }
+ if (argc == 4) {
+ limit = i;
+ i = 0;
}
- bodyObjPtr = (argc == 5) ? argv[4] : argv[5];
+ bodyObjPtr = argv[argc - 1];
retval = Jim_SetVariable(interp, argv[1], Jim_NewIntObj(interp, i));
diff --git a/jim_tcl.txt b/jim_tcl.txt
index 1a2b18a..24ea60b 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -58,6 +58,7 @@ Changes since 0.80
2. Many commands now accept "safe" integer expressions rather than simple integers:
`loop`, `range`, `incr`, `string repeat`, `lrepeat`, `pack`, `unpack`, `rand`
3. String and list indexes now accept integer expressions (<<_string_and_list_index_specifications,STRING AND LIST INDEX SPECIFICATIONS>>)
+4. `loop` can now omit start value
Changes between 0.79 and 0.80
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -3068,7 +3069,7 @@ Also see `defer` as another mechanism for cleaning up at the end of a procedure.
loop
~~~~
-+*loop* 'var first limit ?incr? body'+
++*loop* 'var ?first? limit ?incr? body'+
Similar to `for` except simpler and possibly more efficient.
If +'incr'+ is positive, the effect is, equivalent to:
@@ -3079,11 +3080,12 @@ If +'incr'+ is positive, the effect is, equivalent to:
While if +'incr'+ is negative, the count is downwards.
+If +'first'+ is not specified, 0 is used.
If +'incr'+ is not specified, 1 is used.
Note that setting the loop variable inside the loop does not
affect the loop count.
-Integer parameters may be any integer expression.
++'first'+, +'limit'+ and +'incr'+ may be any integer expression.
lindex
~~~~~~
diff --git a/tests/loop.test b/tests/loop.test
index df9001b..c6144e0 100644
--- a/tests/loop.test
+++ b/tests/loop.test
@@ -75,6 +75,14 @@ test loop-1.10 {no exec infinite loop} {
set a
} {}
+test loop-1.11 {no start} {
+ set a {}
+ loop i 5 {
+ lappend a $i
+ }
+ set a
+} {0 1 2 3 4}
+
test loop-2.1 {loop shimmering tests} {
loop i 1 6 {
}