Control Flow Statements

FOR ... NEXT statement

 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

```

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

```

Note well ! 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 statement

 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`
Statements
`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%`[``100``]`
`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`

```

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, `"Robert"`;`","`;`"Wishlaw"`
`FPRINT` FPOUT, `"Kevin"`;`","`;`"Diggins"`
`FPRINT` FPOUT, `"Wayne"`;`","`;`"Halsdorf"`
`CLOSE`

```' Read in from file
``````' and display input.
```
`TYPE` tagLink
`DIM` szFirst\$
`DIM` szLast\$
`DIM` ptNxt `AS` tagLink `PTR`
`END` `TYPE`

`DIM` pzNames `AS` tagLink `PTR`
`DIM` ptCurrent `AS` tagLink `PTR`
pzNames `=` `(`tagLink`*``)`calloc`(``1`, `sizeof``(`tagLink`)``)`
`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`

```

Example 3:

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

```
`TYPE` tagRECORD
`DIM` sName`[``16``]` `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`
`DIM` ptHead `AS` tagRECORD `PTR`

AddRec`(``"Jim"`,`22``)`
AddRec`(``"Jane"`,`23``)`
AddRec`(``"Alex"`,`22``)`
AddRec`(``"Mary"`,`24``)`
AddRec`(``"John"`,`26``)`
AddRec`(``"Steve"`,`29``)`
AddRec`(``"Sally"`,`25``)`
AddRec`(``"Zak"`,`21``)`
AddRec`(``"Betty"`,`29``)`
AddRec`(``"Clive"`,`26``)`
AddRec`(``"Doris"`,`28``)`
AddRec`(``"Kelly"`,`22``)`

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`

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

`IF` ptHead `=` NULL `THEN`
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`

`IF` ptREC `=` ptHead `THEN`
ptTMP`-`>ptNXT `=` ptHead
ptHead`-`>ptPRV `=` ptTMP
ptHead `=` ptLOW `=` ptTMP
`ELSE`
ptTMP`-`>ptNXT `=` ptREC
ptREC`-`>ptPRV`-`>ptNXT `=` ptTMP
ptTMP`-`>ptPRV `=` ptREC`-`>ptPRV
ptREC`-`>ptPRV `=` ptTMP
`END` `IF`

`END` `SUB`

```

WHILE ... WEND statement

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

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 ```

or

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

or

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

or

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

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

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 ```

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.

Also allowed are less than greater than comparisons like

```
CASE > 5 `AND` < 9

```

The OR operator also may be used, for example,

```
CASE < 4 `OR` > 9

```

The NOT operator may be used as well, for example,

```
CASE <> "BCX"

```

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

```
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"

```

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`
```

may be used. This statement suppresses breaks between CASE statements and performs a binary `AND` on all `CASE` statements. 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

```

Here is an another example using

```SELECT CASE `BAND`:
```

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`.

```

Note well that breaks are suppressed when using the

```
SELECT CASE `BAND`,

```

otherwise the flow would exit after the first match.

```
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: Redirects program flow to a label.

 Syntax: ``` GOTO Label ```

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

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 ```

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

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 inner most loop named. The code generated results in the exiting of the inner most 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"`

`DIM` WatchaGonnaDo\$, IsItReadyToBeDone\$, TheThing\$, What\$

IsItReadyToBeDone\$ `=` `"Not Yet"`
What\$ `=` `"One"`
TheThing\$ `=` ToBeDone\$`(`What\$`)`
`PRINT` WatchaGonnaDo\$
`PRINT` TheThing\$
`PRINT`

IsItReadyToBeDone\$ `=` `"Dunno"`
What\$ `=` `"Two"`
TheThing\$ `=` ToBeDone\$`(`What\$`)`
`PRINT` WatchaGonnaDo\$
`PRINT` TheThing\$
`PRINT`

IsItReadyToBeDone\$ `=` `"Yeah"`
What\$ `=` `"One"`
TheThing\$ `=` ToBeDone\$`(`What\$`)`
`PRINT` WatchaGonnaDo\$
`PRINT` TheThing\$
`PRINT`

IsItReadyToBeDone\$ `=` `"What?"`
What\$ `=` `"Three"`
TheThing\$ `=` ToBeDone\$`(`What\$`)`
`PRINT` WatchaGonnaDo\$
`PRINT` TheThing\$

`FUNCTION` ToBeDone\$`(`DoSomething\$`)`

`DIM` Retstr\$

`SELECT` `CASE` DoSomething\$

`CASE` `"One"`

`IF` IsItReadyToBeDone\$ `=` `"Not Yet"` `THEN`
WatchaGonnaDo\$ `=` `"Then wait some more ... "`
Retstr\$ `=` `"forever if you have to!"`
`EXIT` `SELECT`
`ELSE`
WatchaGonnaDo\$ `=` `"Good! "`
Retstr\$ `=` `"O.K. then do it!"`    ```' Only if IsItReadyToBeDone is not equal to "Not Yet"
```    `END` `IF`

`CASE` `"Two"`
WatchaGonnaDo\$ `=` `"Why? "`
Retstr\$ `=` `"You'd better figure it out!"`

`CASE` `ELSE`
WatchaGonnaDo\$ `=` `"Can't. "`
Retstr\$ `=` `"There's more than Two."`

`END` `SELECT`

`FUNCTION` `=` Retstr\$

`END` `FUNCTION`

```

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

```

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

```

Here's another sample.

```
DIM a
a = -10

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

```

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

```

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

```