# Loops

A **loop** is a statement which allows code to be repeatedly executed. Sanny Builder supports three kinds of controls loops: [for](#for-end), [while](#while-end), [repeat](#repeat-until).

## FOR..END

The `FOR` loop has a strictly certain number of iterations (repetitions).

Syntax:\
`FOR <loop variable> = <initial value> TO/DOWNTO <final value> [step = 1]`\
`<the loop body>`\
`END`

`<loop variable>` - a [variable](/language/data-types/variables.md) used as a counter for iterations\
`<initial value>` - a value of the loop variable before the first iteration (any value including a [model identifier](/language/data-types.md#model-names))\
`TO` or `DOWNTO` - increment or decrement the loop variable between iterations\
`<final value>` - a value of the loop variable after the last iteration (any value including a model identifier)\
`<step>` - an optional value the loop variable will be incremented or decremented with between iterations. By default it is equal to `1`.

```pascal
var
    $value: int = 0
    $final: int = 100
end

FOR $MyCounter = 1 to $final step 2
    $value += $mycounter
end
```

If the `loop variable` is not [declared](/language/data-types/variables.md#var-end-construct) with any type before the loop it gets the `Integer` type. If `initial value`, `final value` or `step` are variables, they get the same type the `loop variable` has To use floating-point numbers for the initial and final values, declare the loop variable with the `Float` type.

```pascal
var
    $MyCounter: float
end

FOR $MyCounter = 1.0 to $final step 2.0
end
```

Variables `$MyCounter` and `$final` both have the `Float` type after the loop.

## WHILE..END

Syntax:\
`WHILE <loop condition>`\
`<the loop body>`\
`END`

`loop condition` - a single conditional opcode\
`loop body` - commands to execute on each iteration; can be omitted

```pascal
while not #AK47.Available
    wait 0
end
```

The `WHILE` loop works while the loop condition is true. The condition is evaluated before a loop iteration. Hence, if the condition is false, the loop body never gets executed.

```pascal
$var = 10

while $var > 11
    inc($var)
end

// as the loop condition is false, inc($var) never gets executed
```

[Constants](/language/data-types/constants.md) `True` and `False` can be used as a loop condition.

```pascal
while true
    <loop body>
end
```

This loop body executes infinitely until the loop is stopped with the `Break` command.

```pascal
while false
    <loop body>
end
```

This loop is ignored by the compiler as the condition is never met.

{% hint style="info" %}
Currently the compiler accepts only one opcode in the loop condition, but you can check more conditions before the loop body and use the commands `Break` and `Continue`.

```pascal
while true
    if and
       $var >= 0
       $var <= 100
    then
       Break
    end
    // loop executes while $var is in the range [0...100]
      
    <loop body>
end
```

{% endhint %}

## REPEAT..UNTIL

Syntax:\
`REPEAT`\
`<the loop body>`\
`UNTIL <loop condition>`

`loop body` - commands to execute on each iteration; can be omitted\
`loop condition` - a single conditional opcode

The `REPEAT..UNTIL` loop executes until the loop condition returns false. The condition is evaluated after iteration therefore the loop is guaranteed to be executed at least once.

[Constants](/language/data-types/constants.md) `True` and `False` can be used as the loop condition.

```pascal
repeat
  // the loop has the only iteration
until true 
```

```pascal
repeat
  // the loop executes infinitely until it's stopped with the Break command
until false
```

{% hint style="info" %}
Currently the compiler accepts only one opcode in the loop condition, but you can check more conditions after the loop body and use the commands `Break` and `Continue`.

```pascal
repeat  
   <loop body>
   if and
     $var >= 0
     $var <= 100
   then
     Break
   end
  // loop executes while $var is in the range [0...100]      
until false
```

{% endhint %}

## Continue and Break

If you want to skip the current iteration and proceed to the next one, use the `Continue` command.

The `Break` command causes the loop to stop immediately and proceed to the command after the loop body.

They can substitute an opcode parameter (e.g., `jf Continue`) or serve as a standalone statement.

```pascal
while true
  if
    not $currentactor.dead
  jf Break // exit the loop

  if
    $currentactor.dead
  then
    Continue // go to the next iteration
  end
end
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sannybuilder.com/language/control-flow/loops.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
