# Loop Statements

Source: https://rungs.dev/docs/structured-text/loops

> Reference for FOR…DO, WHILE…DO, REPEAT…UNTIL, and EXIT loop statements in Structured Text on rungs.dev — syntax, semantics, and examples.

## FOR…DO…END_FOR; [#fordoend_for]

### Syntax [#syntax]

```iecst
FOR Counter := Start_Value TO Limit_Value [BY Step_Value] DO
  Statements
END_FOR;
```

### Rules [#rules]

- `BY` is optional; if not specified, it defaults to `1`.

- If `BY` equals `0`, a runtime error occurs.

- `Start_Value`, `Limit_Value`, and `Step_Value` are evaluated once when the loop begins.

- Positive steps run ascending; negative steps run descending.

- The loop counter is read-only within the body.

- Only integer expressions are allowed for counter and step.

### Example [#example]

```iecst
// Ascending loop (default BY 1)
Sum_Result := 0;
FOR Counter := 1 TO 5 DO
  Sum_Result := Sum_Result + Counter;
END_FOR;
// Result: Sum_Result = 15

// Descending loop
Reverse_Sum := 0;
FOR Counter := 5 TO 1 BY -1 DO
  Reverse_Sum := Reverse_Sum + Counter;
END_FOR;
// Result: Reverse_Sum = 15
```

## WHILE…DO…END_WHILE; [#whiledoend_while]

### Syntax [#syntax-1]

```iecst
WHILE Condition DO
  Statements
END_WHILE;
```

### Rules [#rules-1]

- The condition is checked before each iteration.

- The body executes only while the condition evaluates to `1`.

- If the condition never changes, the loop never ends — see [Endless Loops Are Stopped](#endless-loops-are-stopped).

### Example [#example-1]

```iecst
Value_Now := 0;
WHILE Value_Now < 5 DO
  Value_Now := Value_Now + 1;
END_WHILE;
// Result: Value_Now = 5
```

## REPEAT…UNTIL…END_REPEAT; [#repeatuntilend_repeat]

### Syntax [#syntax-2]

```iecst
REPEAT
  Statements
UNTIL Condition
END_REPEAT;
```

### Rules [#rules-2]

- The body runs once before checking the condition.

- The loop ends when the condition evaluates to `1`.

### Example [#example-2]

```iecst
Cycle_Count := 0;
REPEAT
  Cycle_Count := Cycle_Count + 1;
UNTIL Cycle_Count >= 3
END_REPEAT;
// Result: Cycle_Count = 3
```

## Loop Conditions Must Be `BOOL` [#loop-conditions-must-be-bool]

Loop and branch conditions must evaluate to `BOOL` (`0` or `1`). When working with numeric flags, compare them to an explicit value before using them in a condition.

```iecst
Is_Active := 1; // Numeric flag
WHILE Is_Active <> 0 DO
  Is_Active := 0; // Clear the flag and exit next iteration
END_WHILE;
```

## Early Termination with `EXIT;` [#early-termination-with-exit]

Exits the innermost loop immediately.

```iecst
FOR Task_Index := 1 TO 5 DO
  IF Task_Index = 3 THEN
    EXIT;
  END_IF;
END_FOR;
// Result: Task_Index = 3 because EXIT stops before the BY step runs
```

```iecst
Loop_Index := 0;
WHILE Loop_Index < 10 DO
  IF Loop_Index = 3 THEN
    EXIT; // Leave the loop once the target is reached
  END_IF;
  Loop_Index := Loop_Index + 1;
END_WHILE;
// Result: Loop_Index = 3
```

## Endless Loops Are Stopped [#endless-loops-are-stopped]

A scan must finish before the controller can update its inputs and outputs, so a loop that never ends would freeze the whole program. rungs stops the scan if its loops run more than 1,000,000 times in total during a single scan, and reports an error naming the loop it stopped in and its line number.

Real controllers protect themselves the same way: a program that runs too long triggers a _watchdog_ fault — a built-in timer that stops the controller when a scan takes longer than expected.

If you see this error, check the loop's exit condition (or a FOR loop's start, end, and step values) — something inside the loop must eventually make it stop.

## Summary Table [#summary-table]

| Construct                | Condition Checked | One Iteration Guaranteed | Supports BY       | Early Exit | Typical Use                           |
| ------------------------ | ----------------- | ------------------------ | ----------------- | ---------- | ------------------------------------- |
| FOR…DO…END_FOR;          | Fixed range       | No                       | Yes (default = 1) | Yes        | Counted iteration or array processing |
| WHILE…DO…END_WHILE;      | Before body       | No                       | No                | Yes        | Repetition while condition is `1`     |
| REPEAT…UNTIL…END_REPEAT; | After body        | Yes                      | No                | Yes        | Do-once-then-check or retry logic     |