# Control Flow Statements

FOR ... NEXT loop

 Syntax: ``` FOR Counter = StartNumber TO EndNumber [ STEP StepNumber% ] Statements [ EXIT FOR ] NEXT ``` Parameters: Counter Integer variable or array. StartNumber Integer, single or double variable or literal number. EndNumber Integer, single or double variable or literal number. StepNumber Integer variable or literal number.

Here is an easy to follow example that shows how BCX handles positive and negative STEP values (step up and step down).

```
CLS

DIM i, j, k, q

j = 10
k =  1
q = -1

FOR i = j TO k STEP q
PRINT i
NEXT

PRINT

j =  1
k = 10
q =  1

FOR i = j TO k STEP q
PRINT i
NEXT

KEYPRESS

```

Result:

```
10
9
8
7
6
5
4
3
2
1

1
2
3
4
5
6
7
8
9
10

```

To start the next iteration of a NEXT early in control loops see the description of the ITERATE function.

FOR INTEGER | SINGLE | DOUBLE ... NEXT statement

BCX allows INTEGER, SINGLE, and DOUBLE loop variable declarations. Using this option makes the variable local to the loop. Variables used in defining a loop are local to the loop and cannot be accessed from outside the loop. Here is an example.

```
DIM I = 100, J = 200

FOR DOUBLE I = 1.1 TO 18.7 STEP 1.1
FOR INTEGER J = 1 TO 10 STEP 5
? USING\$("#.##",I), " .....", J
NEXT
NEXT

? : ? : ? I , " ....." , J

```

Result:

```
1.10 ..... 1
1.10 ..... 6
2.20 ..... 1
2.20 ..... 6
3.30 ..... 1
3.30 ..... 6
4.40 ..... 1
4.40 ..... 6
5.50 ..... 1
5.50 ..... 6
6.60 ..... 1
6.60 ..... 6
7.70 ..... 1
7.70 ..... 6
8.80 ..... 1
8.80 ..... 6
9.90 ..... 1
9.90 ..... 6
11.00 ..... 1
11.00 ..... 6
12.10 ..... 1
12.10 ..... 6
13.20 ..... 1
13.20 ..... 6
14.30 ..... 1
14.30 ..... 6
15.40 ..... 1
15.40 ..... 6
16.50 ..... 1
16.50 ..... 6
17.60 ..... 1
17.60 ..... 6
18.70 ..... 1
18.70 ..... 6

100 ..... 200

```

Using floating point numbers for the start and end value of a FOR ... NEXT loop can cause problems. The basis of the difficulty is that some floating point numbers will be rounded up or down because they can not be represented, with absolute accuracy, bit for bit. One specific problem in a FOR ... NEXT loop is that this rounding of the floating point numbers, and more specifically that the rounding up of the accumulated value, may push beyond the end value causing the loop to end prematurely as in the following example.

```
DIM I = 100, J = 200

FOR DOUBLE I = 9.9 TO 18.7 STEP 1.1
FOR INTEGER J = 1 TO 10 STEP 5
? USING\$("#.##",I), " .....", J
NEXT
NEXT

? : ? : ? I , " ....." , J

```

Result:

```
9.90 ..... 1
9.90 ..... 6
11.00 ..... 1
11.00 ..... 6
12.10 ..... 1
12.10 ..... 6
13.20 ..... 1
13.20 ..... 6
14.30 ..... 1
14.30 ..... 6
15.40 ..... 1
15.40 ..... 6
16.50 ..... 1
16.50 ..... 6
17.60 ..... 1
17.60 ..... 6

100 ..... 200

```

The problem is not simply the number of steps. For example, in the example above the start value is different but the end value and STEP are the same as in the previous example which works as expected. The upward rounding problem can be guarded against by adding one-half of the STEP value to the end value. To apply this correction in the example above, the line

```
FOR DOUBLE I = 9.9 TO 18.7 STEP 1.1

```

would be changed to

```
FOR DOUBLE I = 9.9 TO 19.25 STEP 1.1

```

To start the next iteration of a NEXT early in control loops see the description of the ITERATE function.

XFOR ... XNEXT loop

 Syntax: ``` XFOR [StartParameters] [ WHILE ... UNTIL Condition] [ BY VariableChanges] Statements [ EXIT XFOR ] XNEXT ``` Parameters: StartParameters This can be any of the normal variables in a typical FOR ... NEXT loop and, as well, can be a pointer to a type or string. WHILE ... UNTIL Condition This can be any condition that applies to WHILE and UNTIL. BY VariableChanges This parameter can increment and decrement variables and reassign pointers.

Remarks:

With all of the parameters being optional, the following is legal and results in generation of a for ever loop

```
XFOR WHILE BY
PRINT "Type Ctrl C to stop this!"
XNEXT

```

Example 1:

Here is an example that uses XFOR ... XNEXT in the program which calculates and prints the combinations of a subset of items in a set.

```
DIM SetItemCount%
DIM SubSetItemCount%
DIM SubSetCount%
DIM start AS clock_t
DIM finish AS clock_t
DIM duration#

INPUT "Total number of items in set? ", SetItemCount%
INPUT "Number of items in one subset combination? ", SubSetItemCount%
PRINT

start = clock()
SubSetCount% = SubSets(SetItemCount%, SubSetItemCount%)
finish = clock()
duration# = ROUND((DOUBLE)(finish - start) / CLOCKS_PER_SEC, 2)

PRINT
PRINT "It took", duration#, " seconds to calculate that"
PRINT "there are", SubSetCount%, " combinations of", SubSetItemCount%, " item subsets in a set of", SetItemCount%, " items."

FUNCTION SubSets%(n%, k%)
RAW buffer%
DIM i% = 0
DIM j%
DIM SSCnt%

XFOR j = 0 WHILE j <= n BY j++
buffer[j] = 0
XNEXT

WHILE i >= 0
IF (buffer[i] < n + i - k + 1) THEN
buffer[i]++
IF (i = k - 1) THEN
XFOR j = 0 WHILE j < k BY j++
PRINT buffer[j];
XNEXT
PRINT
SSCnt++
ELSE
buffer[++i] = buffer[i - 1]
END IF
ELSE
i--
END IF
WEND
FUNCTION = SSCnt%
END FUNCTION

```

Result:

```
Total number of items in set? 5
Number of items in one subset combination? 3

1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

It took 0 seconds to calculate that
there are 10 combinations of 3 item subsets in a set of 5 items.

```

Example 2:

Here is a more complex example using XFOR ... XNEXT.

```
' Make a file of names.

OPEN "NAMES.TXT" FOR OUTPUT AS FPOUT
FPRINT FPOUT, "John G.";",";"Kemeny"
FPRINT FPOUT, "Thomas E.";",";"Kurtz"
FPRINT FPOUT, "Mary Kenneth";",";"Keller"
CLOSE

' and display input.

DIM szFirst\$
DIM szLast\$
END TYPE

OPEN "NAMES.TXT" FOR INPUT AS FPIN

XFOR ptCurrent = pzNames WHILE NOT EOF(FPIN) BY ptCurrent = ptCurrent->ptNxt = (tagLink*)calloc(1,SIZEOF(tagLink))
FINPUT FPIN, ptCurrent->szFirst\$, ptCurrent->szLast\$
XNEXT

XFOR ptCurrent = pzNames WHILE ptCurrent BY ptCurrent = ptCurrent->ptNxt
PRINT ptCurrent->szFirst\$; " "; ptCurrent->szLast\$
XNEXT
PAUSE

```

Result:

```
John G. Kemeny
Thomas E. Kurtz
Mary Kenneth Keller

```

Example 3:

And here is an even more complex example using XFOR ... XNEXT.

```
TYPE tagRECORD
DIM sName AS CHAR
DIM iAge AS int
DIM ptPRV AS tagRECORD PTR
DIM ptNXT AS tagRECORD PTR
END TYPE

DIM szBuf\$
DIM ptHIGH AS tagRECORD PTR
DIM ptLOW AS tagRECORD PTR

sprintf(szBuf, "%12s%4s%3s", "Name", "", "Age")
PRINT szBuf\$

XFOR INT i = 1,  tagRECORD PTR ptRL = ptLOW WHILE ptRL <> NULL BY i++, ptRL = ptRL->ptNXT
sprintf(szBuf, "%14s  %3i", ptRL->sName, ptRL->iAge)
PRINT szBuf\$
XNEXT

PRINT
sprintf(szBuf, "%12s%4s%3s", "Name", "", "Age")
PRINT szBuf\$;" ";szBuf\$
XFOR INT i = 1, INT j = 12, tagRECORD PTR ptRL = ptLOW, tagRECORD PTR ptRH = ptHIGH  WHILE i < j BY i++, j--, ptRL = ptRL->ptNXT, ptRH = ptRH->ptPRV
sprintf(szBuf, "%14s  %3i %14s  %3i", ptRL->sName, ptRL->iAge, ptRH->sName, ptRH->iAge)
PRINT szBuf\$
XNEXT

PAUSE

RAW ptTMP AS tagRECORD PTR
ptTMP = (tagRECORD *)calloc(1,SIZEOF(tagRECORD))
ptTMP->sName\$ = pszN\$
ptTMP->iAge = iA

ptHIGH = ptLOW = ptHead = ptTMP
EXIT SUB
END IF

RAW ptREC AS tagRECORD PTR
XFOR ptREC = ptHead WHILE ptREC <> NULL AND ptREC->iAge < iA BY ptREC = ptREC->ptNXT
XNEXT

IF ptREC = NULL THEN
ptHIGH->ptNXT = ptTMP
ptHIGH->ptNXT->ptPRV = ptHIGH
ptHIGH = ptTMP
EXIT SUB
END IF

ELSE
ptTMP->ptNXT = ptREC
ptREC->ptPRV->ptNXT = ptTMP
ptTMP->ptPRV = ptREC->ptPRV
ptREC->ptPRV = ptTMP
END IF

END SUB

```

Result:

```
Name    Age
Zak   21
Kelly   22
Alex   22
Jim   22
Jane   23
Mary   24
Sally   25
Clive   26
John   26
Doris   28
Betty   29
Steve   29

Name    Age         Name    Age
Zak   21          Steve   29
Kelly   22          Betty   29
Alex   22          Doris   28
Jim   22           John   26
Jane   23          Clive   26
Mary   24          Sally   25

```

WHILE ... WEND statement

 Syntax: ``` [ DO ] WHILE expression ' "DO" is optional EXIT LOOP OR EXIT DO WEND ```

Example:

```
DIM RetStr\$

RetStr\$ = NumberToRoman\$(3999)
?  RetStr\$

RetStr\$ = NumberToRoman\$(0xF9F)
?  RetStr\$

RetStr\$ = NumberToRoman\$(%07637)
?  RetStr\$

RetStr\$ = NumberToRoman\$(0b111110011111)
?  RetStr\$

FUNCTION NumberToRoman\$(NumberToConvert%)

DIM FunctionReturnString\$

SET RomanNumerals[] AS PCHAR
"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
END SET

SET ArabicNumerals%[]
1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
END SET

DIM Counter%
WHILE (NumberToConvert)
WHILE (NumberToConvert / ArabicNumerals[Counter])
CONCAT(FunctionReturnString\$, RomanNumerals[Counter])
NumberToConvert -= ArabicNumerals[Counter]
WEND
Counter++
WEND
FUNCTION = FunctionReturnString\$
END FUNCTION

```

Result:

```
MMMCMXCIX
MMMCMXCIX
MMMCMXCIX
MMMCMXCIX

```

Remarks:

To start the next iteration of a WEND early in control loops see the description of the ITERATE function.

DO [UNTIL] ... LOOP [UNTIL] [WHILE] statement

 Syntax 1: ``` DO Statements IF Condition THEN EXIT LOOP | EXIT DO END IF More Statements LOOP ```

Example:

```
DIM a

DO
a++
IF a > 45 THEN
EXIT LOOP
END IF
?  a
LOOP

```

Result:

```
1
...
45

```
 Syntax 2: ``` DO UNTIL Condition Statements LOOP ```

Example:

```
DIM a

DO UNTIL a > 45
a++
?  a
LOOP

```

Result:

```
1
...
46

```
 Syntax 3: ``` DO Statements LOOP UNTIL Condition ```

Example:

```
DIM a

DO
a++
?  a
LOOP UNTIL a > 45

```

Result:

```
1
...
45

```
 Syntax 4: ``` DO Statements LOOP WHILE Condition ```

Example:

```
DIM a

DO
a++
?  a
LOOP WHILE a < 45

```

Result:

```
1
...
45

```

Remarks:

See ITERATE to start the next iteration of a LOOP early in control loops.

ITERATE statement

Purpose: ITERATE will start the next iteration of a loop early in control loops

 Syntax 1: ``` ITERATE ```

Remarks:

ITERATE has the effect of jumping to the instruction just before the LOOP, WEND, NEXT or END REPEAT statement in the currently executing block

Example:

```
DIM A,B

CLS

PRINT "This will print Iterations 7 thru 10 of the outer loop"
PRINT "and will print the numbers 999 and 1000 from within"
PRINT "the inner loop. All 10,000 iterations still occur,"
PRINT "it's the ADDED LEVEL OF CONTROL within your loops that "
PRINT "ITERATE gives to you."

FOR B = 1 TO 10
IF B < 7 THEN ITERATE
PRINT
PRINT "<Outer Loop> Iteration Number", B
FOR A=1 TO 1000
IF A < 999 THEN ITERATE
PRINT ">Inner Loop< Iteration Number", A
NEXT
NEXT

```

IF ... THEN ... ELSE ... ELSEIF ... END IF [ENDIF] statements

 Syntax 1: ``` IF Expression THEN Statement END IF ```
 Syntax 2: ``` IF Expression1 THEN Statements ELSEIF Expression THEN Statements ELSE Statements END IF ```

Example:

```
DIM i

WHILE i < 10
INCR i
IF i = 5 THEN
PRINT "Five"
ELSEIF i = 7 THEN
PRINT "Seven"
EXIT WHILE
END IF
WEND

PRINT "The final value of i =" ; i

PAUSE

```

Result:

```
Five
Seven
The final value of i = 7

```

Example:

The IF ... THEN code above can be expressed as a single line but only with a modification. ELSEIF will not be parsed correctly when embedded in a single line conditional statement. ELSE IF, instead, must be used.
```
DIM i

WHILE i < 10
INCR i
IF i = 5 THEN PRINT "Five" ELSE IF i = 7 THEN PRINT "Seven" : EXIT WHILE
WEND

PRINT "The final value of i =" ; i

PAUSE

```

Result:

```
Five
Seven
The final value of i = 7

```

SELECT CASE statement

 Syntax: ``` SELECT CASE Expression CASE Expression1 your code here CASE Expression2 ... ' CASE Expression is tested for equality against all ... ' SELECT CASE expression and executes the instructions ... ' following if CASE found TRUE. CASE Expression N your code here CASE ELSE your default code here END SELECT ```

Remarks:

CASE statements allow the following common construct:

```
CASE 1 TO 10

```

which will capture the flow if the CASE is any number between 1 and 10.

When AND or OR is used as a Boolean comparison operator, scalar operators (= or < or > etc.) must be used preceding the test expression.

```
CASE = "Selector" OR = "Selectee"

```

The following line is not valid and will cause an error.

```
CASE "Selector" OR "Selectee"

```

However, in the example above, the OR can be replaced with a comma to form a valid CASE test statement.

```
CASE "Selector", "Selectee"

```

Also allowed are less than, greater than, comparisons like

```
CASE > 5 AND < 9

```

The OR operator also may be used for less than, greater than, comparisons, for example,

```
CASE < 4 OR > 9

```

The scalar not equal <> operator may be used as well, for example,

```
CASE <> "BCX"

```

Arrays, functions and variations of variables that contain the dereferencing operator (->) may be used as arguments to the CASE statement, for example,

```
CASE A TO A

CASE foo->f,foo->g

CASE > foo->f AND < Funfoo(A)

```

Example 1:

```
DIM Choose\$

Choose\$ = "SelectOR"

SELECT CASE Choose\$
CASE = "SelectOR" OR = "SelectXOR"
PRINT "Selected"
END SELECT

```

Example 2: SELECT CASE variants:

```
DIM i

INPUT "Enter a number: ", i

SELECT CASE i
CASE <1
PRINT "less than 1"

CASE 1
PRINT "1"

CASE 2 TO 4
PRINT "2 to 4 inclusive"

CASE 5
PRINT "5"

CASE >5 AND <9
PRINT "greater than 5 and less than 9"

CASE 9
PRINT "9"

CASE >9
PRINT "greater than 9"
END SELECT

```

SELECT CASE BAND also may be used. This statement performs a binary AND on all CASE statements.

In the C code translation, breaks normally inserted between the CASE statements are suppressed when using SELECT CASE BAND, otherwise the flow would exit after the first match.

Here is an example.

```
SELECT CASE BAND Style
CASE WS_CHILD   : CONCAT(StyleString\$,"WS_CHILD,")
CASE WS_VISIBLE : CONCAT(StyleString\$,"WS_VISIBLE,")
CASE WS_TABSTOP : CONCAT(StyleString\$,"WS_TABSTOP")
END SELECT

```

A status code is returned in lParam from which, depending on the bits set, the messages can be determined. This is how it would normally be written:

```
IF lParam BAND CE_BREAK    THEN err\$=err\$ + "CE_BREAK "
IF lParam BAND CE_FRAME    THEN err\$=err\$ + "CE_FRAME "
IF lParam BAND CE_IOE      THEN err\$=err\$ + "CE_IOE "
IF lParam BAND CE_MODE     THEN err\$=err\$ + "CE_MODE "
IF lParam BAND CE_OVERRUN  THEN err\$=err\$ + "CE_OVERRUN "
IF lParam BAND CE_RXOVER   THEN err\$=err\$ + "CE_RXOVER "
IF lParam BAND CE_RXPARITY THEN err\$=err\$ + "CE_RXPARITY "
IF lParam BAND CE_TXFULL   THEN err\$=err\$ + "CE_TXFULL"

```

Here is a similar solution using SELECT CASE BAND.

```
SELECT CASE BAND lParam
CASE CE_BREAK : CONCAT(err\$,"CE_BREAK ")
CASE CE_FRAME : CONCAT(err\$,"CE_FRAME ")
CASE CE_IOE : CONCAT(err\$,"CE_IOE ")
CASE CE_MODE : CONCAT(err\$,"CE_MODE ")
CASE CE_OVERRUN : CONCAT(err\$,"CE_OVERRUN ")
CASE CE_RXOVER : CONCAT(err\$,"CE_RXOVER ")
CASE CE_RXPARITY : CONCAT(err\$,"CE_RXPARITY ")
CASE CE_TXFULL : CONCAT(err\$,"CE_TXFULL")
END SELECT

```

GOTO statement

Purpose: GOTO redirects program flow to a label.

 Syntax: ``` GOTO Label Label: ```

Remarks:

• Labels must appear on their own on a line and must be appended with a colon ":"
• Labels are not case sensitive.

BCX Console Sample Programs using GOTO function.

GOSUB ... RETURN statement

Purpose: GOSUB redirects program flow to a label. The flow continues from the label until a RETURN statement is encountered and the flow is returned to the line following the GOSUB Label statement.

 Syntax: ``` GOSUB Label Label: Statements RETURN ```

Remarks:

• Labels must appear on their own on a line and must be appended with a colon ":"
• Labels are not case sensitive.

BCX Console Sample Programs using GOSUB statement.

EXIT statement

Purpose: Causes EXIT from a DO ... LOOP, FOR ... NEXT, SELECT ... END SELECT, REPEAT ... END REPEAT loop, or FUNCTION or SUB.

 Syntax: ``` EXIT CASE EXIT DO EXIT FOR EXIT LOOP EXIT REPEAT EXIT SELECT EXIT WHILE EXIT FUNCTION EXIT SUB ```

When translated with the BCX -w flag, the following code generates a warning with the code generated exiting out of inner most FOR ... NEXT loop

```
DIM iW, iX, iY
FOR iW = 1 TO 2
FOR iX = 1 TO 5
iY = iX+1
WHILE iY < 10
PRINT iX;iY
IF iY = iX THEN EXIT FOR
iY++
iY = IMOD(iY,10)
WEND
NEXT
PRINT iX;iY
NEXT

```

When translated with the BCX -w flag, the following code generates a warning with code generated exiting out of the XFOR ... XNEXT loop

```
DIM iW, iX, iY
XFOR iW = 1 WHILE iW < 2 BY iW++
FOR iX = 1 TO 5
FOR iY = 1 TO 5
IF iY + iX + iW = 10 THEN EXIT XFOR
PRINT iW;iX;iY
NEXT
NEXT
XNEXT
PRINT iW;iX;iY

```

When translated with BCX, the following code will generate an error since there is no DO ... LOOP.

```
DIM iX, iY
FOR iX = 1 TO 5
FOR iY = iX+1 TO 5
PRINT iX;iY
IF iY +iY > 7 THEN EXIT DO
NEXT
NEXT

```

EXIT without a control named results in a warning message with the innermost loop named. The code generated results in the exiting of the innermost control loop.

EXIT NEST statement

Purpose: Causes an EXIT out of the nest of current loop types to the positon in the code where a different loop type is encountered.

 Syntax: ``` EXIT NEST ```

Example 1: This example will EXIT from the nested DO loops when (w+x)*(y+z) > 20.

```
DIM w, x, y, z
w = 0

WHILE w < 10
x = 0
WHILE x < 5
y = 0
DO
z = 0
DO
IF (w+x)*(y+z) > 20 THEN
PRINT "Exit Nest"
EXIT NEST
END IF
z++
PRINT "z Pass"; z
LOOP UNTIL z > 4
y++
LOOP UNTIL y > 4
PRINT "w equals"; w
x++
WEND
w++
WEND
PRINT "At end w equals"; w
PAUSE

```

EXIT SELECT statement

Purpose: Causes an EXIT out of the SELECT ... END SELECT.

 Syntax: ``` EXIT SELECT ```

Example 1: Here is a general example of when one might need EXIT SELECT

```
SELECT CASE SomeCondition

CASE Condition_1

IF SomeFlagIsSet THEN
EXIT SELECT
ELSE
Do_Condition_1_Thing() ' Only if SomeFlagIsSet = FALSE
END IF

CASE Condition_2
Do_Condition_2_Thing()

CASE Condition_3
Do_Condition_3_Thing()

END SELECT

```

Example 2: Here is an specific example using EXIT SELECT

```
\$BCXVERSION "6.50"

SelexitFlag\$ = "Selexit"
What\$ = "One"
TheThing\$ = ToBeDone\$(What\$)
PRINT TheThing\$
PRINT

SelexitFlag\$ = "NoSelexit"
What\$ = "One"
TheThing\$ = ToBeDone\$(What\$)
PRINT TheThing\$
PRINT

FUNCTION ToBeDone\$(DoSomething\$)

DIM Retstr\$

SELECT CASE DoSomething\$

CASE "One"

IF SelexitFlag\$ = "Selexit" THEN
Retstr\$ = "See if I care ..."
EXIT SELECT
ELSE
WajYaDoing\$ = "I'm not Selexiting. "
END IF

END SELECT

FUNCTION = Retstr\$

END FUNCTION

```

Result:

```
I'm Selexiting.
See if I care ...

I'm not Selexiting.

```

END statement

Purpose: Immediately terminates a running program

 Syntax: ``` END ```

REPEAT ... END REPEAT statement

Purpose: REPEAT ... END REPEAT blocks allow you to create loops without the need of a loop variable. BCX translates these to "C" style for/next loops that instead use temporary variables that are local to the loop.

Example:

```
CLS

REPEAT 2
REPEAT 5
PRINT "Here is an example of nested REPEATS"
END REPEAT
END REPEAT

PRINT

DIM Iterations

INPUT "Type a number, press ENTER ", Iterations

REPEAT(Iterations+1+((Iterations+1)*2))
PRINT "Calculated Expressions Allowed in REPEAT/END REPEAT"
END REPEAT

```

Result:

```
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS
Here is an example of nested REPEATS

Type a number, press ENTER 3
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT
Calculated Expressions Allowed in REPEAT/END REPEAT

```

To count backwards, the argument must begin with a minus sign. The "add a minus sign" rule is the same rule that BCX has always used in FOR ... NEXT statements that contain a negative STEP clause. "add a minus sign" is the only way that BCX can detect and respond to the logic flow at compile time.

Examples :

```
REPEAT -10
REPEAT -A
REPEAT -(A*2+100)

```

See ITERATE to start the next iteration of a END REPEAT early in control loops.

EXIT REPEAT immediately breaks the flow out of a REPEAT block.

BCX_REPEAT variable

The BCX_REPEAT variable automatically keeps count of how many times REPEAT has been executed within a REPEAT ... END REPEAT block.

Example:

```
REPEAT 2
PRINT BCX_REPEAT
REPEAT 5
PRINT "... ", BCX_REPEAT
END REPEAT
END REPEAT

```

Result:

```
1
...  1
...  2
...  3
...  4
...  5
2
...  1
...  2
...  3
...  4
...  5

```

Here's another sample.

```
DIM a
a = -10

REPEAT -ABS(a)
PRINT BCX_REPEAT
IF BCX_REPEAT = 5 THEN EXIT REPEAT
END REPEAT

```

Result:

```
1
...  1
...  2
...  3
...  4
...  5
2
...  1
...  2
...  3
...  4
...  5

```

WITH ... END WITH statement

Purpose: WITH ... END WITH allows repeated reference to be made to an user defined type object or structure.

 Syntax: ``` WITH UserDefinedTypeObject [ statements ] END WITH ```

Example 1:

```
TYPE QWERTY
DIM a
DIM b!
DIM c AS CHAR
DIM q AS RECT
END TYPE

GLOBAL MyType [10,10,10] AS QWERTY

WITH MyType[2,3,4]
.a = 1
.b! = 2.345
.c\$ = "Hello world from a poly-dimensional udt!"
WITH .q
.left = 100
.right = 200
.top = 150
.bottom = 300
END WITH
PRINT .a
PRINT .b!
PRINT UCASE\$(.c\$)
END WITH

```

Result:

```
1
2.345
HELLO WORLD FROM A POLY-DIMENSIONAL UDT!

```

Example 2:

```
TYPE Foo
One AS LONG
Two AS LONG
Three AS LONG
END TYPE

DIM MyArray AS Foo

WITH MyArray
.One = 1
.Two = 2
.Three= 3
PRINT .One
PRINT .Two
PRINT .Three
END WITH

```

Result:

```
1
2
3

```