Skip to content

Commit ce8838f

Browse files
committed
Add PAIR! support for REPEAT
This change allows PAIR! values as value argument of REPEAT. This enables convenient traversal over a 2D space: >> repeat p 3x3 [print p] 1x1 2x1 3x1 1x2 2x2 3x2 1x3 2x3 3x3 Similar to REPEAT over decimals, REPEAT over pairs implies a start of 1.0x1.0 and a default bump of 1.0 for each component. The first pair component ("X") is varied first, which is in line with pair!-based indexing into image!s. For the sake of completeness, PAIR! support is also enabled in the legacy C-style FOR: >> for p 10x10 15x20 5x5 [print p] 10x10 15x10 10x15 15x15 10x20 15x20 >> for p 3x1 1x2 -1x1 [print p] 3x1 2x1 1x1 3x2 2x2 1x2 This implements CureCode wish #1995.
1 parent 25033f8 commit ce8838f

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/boot/natives.r

+4-4
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ find-script: native [
150150
for: native [
151151
{Evaluate a block over a range of values. (See also: REPEAT)}
152152
'word [word!] "Variable to hold current value"
153-
start [series! number!] "Starting value"
154-
end [series! number!] "Ending value"
155-
bump [number!] "Amount to skip each time"
153+
start [series! number! pair!] "Starting value"
154+
end [series! number! pair!] "Ending value"
155+
bump [number! pair!] "Amount to skip each time"
156156
body [block!] "Block to evaluate"
157157
]
158158

@@ -258,7 +258,7 @@ reduce: native [
258258
repeat: native [
259259
{Evaluates a block a number of times or over a series.}
260260
'word [word!] {Word to set each time}
261-
value [number! series! none!] {Maximum number or series to traverse}
261+
value [number! series! pair! none!] {Maximum number or series to traverse}
262262
body [block!] {Block to evaluate each time}
263263
]
264264

src/core/n-loop.c

+34
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,31 @@
135135
}
136136

137137

138+
/***********************************************************************
139+
**
140+
*/ static void Loop_Pair(REBVAL *var, REBSER* body, REBD32 xstart, REBD32 ystart, REBD32 xend, REBD32 yend, REBD32 xincr, REBD32 yincr)
141+
/*
142+
***********************************************************************/
143+
{
144+
REBD32 xi;
145+
REBD32 yi;
146+
REBVAL *result;
147+
148+
VAL_SET(var, REB_PAIR);
149+
for (yi = ystart; (yincr > 0.) ? yi <= yend : yi >= yend; yi += yincr) {
150+
for (xi = xstart; (xincr > 0.) ? xi <= xend : xi >= xend; xi += xincr) {
151+
VAL_PAIR_X(var) = xi;
152+
VAL_PAIR_Y(var) = yi;
153+
result = Do_Blk(body, 0);
154+
if (THROWN(result) && Check_Error(result) >= 0) return;
155+
if (!IS_PAIR(var)) Trap_Type(var);
156+
xi = VAL_PAIR_X(var);
157+
yi = VAL_PAIR_Y(var);
158+
}
159+
}
160+
}
161+
162+
138163
/***********************************************************************
139164
**
140165
*/ static void Loop_Number(REBVAL *var, REBSER* body, REBVAL *start, REBVAL *end, REBVAL *incr)
@@ -486,6 +511,12 @@ skip_hidden: ;
486511
//if (ANY_SERIES(end) && VAL_SERIES(start) != VAL_SERIES(end)) Trap_Arg(end);
487512
Loop_Series(var, body, start, ANY_SERIES(end) ? VAL_INDEX(end) : (Int32s(end, 1) - 1), Int32(incr));
488513
}
514+
else if (IS_PAIR(start) && IS_PAIR(end) && IS_PAIR(incr)) {
515+
Loop_Pair(var, body,
516+
VAL_PAIR_X(start), VAL_PAIR_Y(start),
517+
VAL_PAIR_X(end), VAL_PAIR_Y(end),
518+
VAL_PAIR_X(incr), VAL_PAIR_Y(incr));
519+
}
489520
else
490521
Loop_Number(var, body, start, end, incr);
491522

@@ -630,6 +661,9 @@ skip_hidden: ;
630661
else if (IS_INTEGER(count)) {
631662
Loop_Integer(var, body, 1, VAL_INT64(count), 1);
632663
}
664+
else if (IS_PAIR(count)) {
665+
Loop_Pair(var, body, 1., 1., VAL_PAIR_X(count), VAL_PAIR_Y(count), 1., 1.);
666+
}
633667

634668
return R_TOS1;
635669
}

0 commit comments

Comments
 (0)