# 4. Control flow

## IF ... THEN ... ELSE

```basic
10 A# = 5
20 IF A# = 5 THEN PRINT "FIVE" ELSE PRINT "NOT FIVE"
```

```output
FIVE
```

The condition is a whole expression, so `AND`, `OR` and `NOT` all work in one:

```basic
10 A# = 5
20 IF A# > 0 AND A# < 10 THEN PRINT "IN RANGE"
```

```output
IN RANGE
```

**Everything after `THEN` on the line belongs to the condition**, which matters as soon
as you put several statements on a line:

| Line | Condition | What runs |
|---|---|---|
| `IF C THEN A : B` | true | `A`, `B` |
| `IF C THEN A : B` | false | nothing |
| `IF C THEN A ELSE B : D` | true | `A` |
| `IF C THEN A ELSE B : D` | false | `B`, `D` |

The remainder always belongs to whichever arm was written *last*.

### Blocks

`BEGIN` and `BEND` make an `IF` span lines:

```basic
10 A# = 5
20 IF A# = 5 THEN BEGIN
30   PRINT "IN THE BLOCK"
40   PRINT "STILL IN IT"
50 BEND
60 PRINT "AFTER"
```

```output
IN THE BLOCK
STILL IN IT
AFTER
```

When the condition is false every line up to the `BEND` is skipped.

## FOR ... NEXT

```basic
10 FOR I# = 1 TO 5
20   PRINT I#
30 NEXT I#
```

```output
1
2
3
4
5
```

`STEP` sets the stride, and a negative one counts down:

```basic
10 FOR I# = 10 TO 0 STEP -2
20   PRINT I#
30 NEXT I#
```

```output
10
8
6
4
2
0
```

The counter is an ordinary variable and the body may assign to it. Two things to know:

- **The counter does not survive the loop.** It lives in the loop's own scope, so
  reading it afterwards gives zero. On a C128 it keeps its final value.
- **A step that overshoots runs the body one extra time.** `FOR I = 1 TO 9 STEP 3` runs
  with 1, 4, 7 *and 10*. Both are recorded as known defects; see Chapter 13.

`EXIT` leaves the loop early:

```basic
10 FOR I# = 1 TO 100
20   IF I# = 5 THEN EXIT
30 NEXT I#
40 PRINT "OUT"
```

```output
OUT
```

## DO ... LOOP

The condition can go on either end, or neither:

```basic
10 I# = 0
20 DO WHILE I# < 3
30   PRINT I#
40   I# = I# + 1
50 LOOP
```

```output
0
1
2
```

```basic
10 I# = 0
20 DO
30   PRINT I#
40   I# = I# + 1
50 LOOP UNTIL I# = 3
```

```output
0
1
2
```

A condition on the `DO` is tested before the body, so the body may run zero times. A
condition on the `LOOP` is tested after, so it runs at least once. `DO` with no
condition at all loops forever until an `EXIT` or a `GOTO` leaves it.

`EXIT` works here too.

## GEN ... EMIT and FOR EACH / DO EACH

A `GEN` is a subroutine that hands back more than one value, one at a time, instead of
returning once. It looks like a multi-line `DEF`, except its body runs `EMIT` where a
function would `RETURN`, and it ends in `END GEN` rather than `RETURN`:

```basic
10 GEN COUNTUP(N#)
20     FOR I# = 1 TO N#
30         EMIT I#
40     NEXT I#
50 END GEN
60 FOR EACH V# IN COUNTUP(3)
70     PRINT V#
80 NEXT V#
```

```output
1
2
3
```

`FOR EACH` is what runs a `GEN`: it calls `COUNTUP(3)` the way `FOR EACH V# IN` says,
and each `EMIT` inside the generator's body becomes one trip through the loop, with `V#`
holding whatever was emitted. When the generator's body reaches `END GEN` with nothing
left to emit, the loop ends -- there is no separate "no more values" check to write.

`DO EACH ... LOOP` does the same thing:

```basic
10 GEN COUNTUP(N#)
20     FOR I# = 1 TO N#
30         EMIT I#
40     NEXT I#
50 END GEN
60 DO EACH V# IN COUNTUP(3)
70     PRINT V#
80 LOOP
```

```output
1
2
3
```

A `GEN`'s body is ordinary BASIC: it may hold its own `FOR`, `DO`, `IF` or `GOSUB`
around the `EMIT`s, and even invoke another `GEN` with its own `FOR EACH`/`DO EACH` --
the same generator invoked with different arguments, nested or side by side, is not
recursion. A `GEN` invoking *itself* from within its own currently-running body is
refused: unlike a function call, which runs to completion and returns, the outer
invocation is suspended mid-body waiting on the same loop, and there is no answer to
"which EMIT feeds which loop" that is not a surprise.

`EXIT` leaves a `FOR EACH`/`DO EACH` loop early, exactly as it does a plain `FOR` or
`DO`, and the generator it was consuming stops there -- nothing forces the rest of it to
run just because the loop started it:

```basic
10 GEN COUNTUP(N#)
20     FOR I# = 1 TO N#
30         EMIT I#
40     NEXT I#
50 END GEN
60 FOR EACH V# IN COUNTUP(100)
70     PRINT V#
80     IF V# = 3 THEN EXIT
90 NEXT V#
100 PRINT "STOPPED"
```

```output
1
2
3
STOPPED
```

`RETURN` ends a `GEN` from the inside, exactly as it ends a multi-line `DEF` or a
`GOSUB`: the generator is done, the loop consuming it ends, and the program carries on
after the loop. What a generator's `RETURN` cannot do is carry a value -- values leave
a `GEN` one at a time, through `EMIT`, and `RETURN 99` inside one is an error. Like a
`GOSUB`'s or a `DEF`'s, the `RETURN` must stand in the `GEN`'s own scope: from inside
a `FOR` or `DO` the body opened, it is an error, though `IF ... THEN RETURN` is fine
because `IF` opens no scope of its own.

```basic
10 GEN FIRSTFEW(N#)
20     EMIT 1
30     IF N# < 2 THEN RETURN
40     EMIT 2
50     IF N# < 3 THEN RETURN
60     EMIT 3
70 END GEN
80 FOR EACH V# IN FIRSTFEW(2)
90     PRINT V#
100 NEXT V#
110 PRINT "DONE"
```

```output
1
2
DONE
```

A `DO EACH`'s `LOOP` may carry a `WHILE` or `UNTIL`, and the two compose: the condition
is checked after each trip through the body, with the loop variable still holding that
trip's value, and a condition that says stop abandons the rest of the generator exactly
as `EXIT` does. The condition belongs on the `LOOP` -- putting it on the `DO` line is
an error, since the `DO` line already says what the loop consumes.

```basic
10 GEN COUNTUP(N#)
20     FOR I# = 1 TO N#
30         EMIT I#
40     NEXT I#
50 END GEN
60 DO EACH V# IN COUNTUP(10)
70     PRINT V#
80 LOOP UNTIL V# = 3
90 PRINT "STOPPED"
```

```output
1
2
3
STOPPED
```

A `GEN` shares its namespace with `DEF` -- the same name cannot be both -- but it is not
a function and cannot be called like one: `X# = COUNTUP(3)` is refused, because nothing
about an ordinary call means "resume where the last `EMIT` left off." `FOR EACH`/`DO
EACH` is the only thing that consumes a `GEN`.

## GOTO and GOSUB

```basic
10 GOSUB 100
20 PRINT "BACK"
30 END
100 PRINT "IN THE SUBROUTINE"
110 RETURN
```

```output
IN THE SUBROUTINE
BACK
```

`RETURN` goes back to the line after the `GOSUB`.

## Labels

A label is a name with no type suffix. It marks a line, and anything that takes a line
number takes a label instead:

```basic
10 GOTO SETUP
20 PRINT "SKIPPED"
100 LABEL SETUP
110 PRINT "ARRIVED"
```

```output
ARRIVED
```

**Labels are filed before the program runs**, so a forward `GOTO` works. This is worth
using for its own sake: a program written with labels is immune to `RENUMBER`, because
there is no number to rewrite.

Follow that one step further and the numbers stop earning their keep at all. A program
in a file can leave them out — see
[Chapter 2](02-getting-started.md#a-program-in-a-file-does-not-need-them) — and then
every branch it makes is by name:

```basic
GOSUB GREET
GOTO FINISH

PRINT "NOT REACHED"

LABEL GREET
PRINT "HELLO"
RETURN

LABEL FINISH
PRINT "DONE"
```

```output
HELLO
DONE
```

Nothing in that program can be broken by inserting a line into it, which is the whole
argument.

## ON

`ON` picks the *n*th target from a list, counting from one:

```basic
10 CHOICE# = 2
20 ON CHOICE# GOTO 100, 200, 300
30 PRINT "CHOICE WAS OUT OF RANGE"
40 END
100 PRINT "FIRST"
110 END
200 PRINT "SECOND"
210 END
300 PRINT "THIRD"
```

```output
SECOND
```

Out of range is not an error — it falls through to the next statement, which is what
lets you write the check as the line after. `ON ... GOSUB` works the same way and
returns.

## Trapping errors

`TRAP` sends an error to a handler instead of stopping the program:

```basic
10 TRAP HANDLER
20 DIM Q#(2)
30 PRINT Q#(9)
40 PRINT "CARRIED ON"
50 END
100 LABEL HANDLER
110 PRINT "CAUGHT " + ERR(ER#) + " ON LINE " + EL#
120 RESUME NEXT
```

```output
CAUGHT Out Of Bounds ON LINE 30
CARRIED ON
```

Two variables are set when the trap fires: **`ER#`** is the error code and **`EL#`** is
the line it happened on. `ERR(ER#)` gives the message text. On a C128 these are called
`ER` and `EL` with no suffix; this dialect has no bare variable names.

**[Chapter 15](15-error-codes.md) is the complete list** of what `ER#` can hold and
what each code means. The short version is that the interpreter's own codes are 512 to
519 and are the only numbers worth comparing against; two codes render as the same
`ERR()` text, so compare the number rather than the text.

`RESUME` comes in three forms:

| Form | Where it goes |
|---|---|
| `RESUME` | back to the line that failed, and tries again |
| `RESUME NEXT` | on to the line after the one that failed |
| `RESUME (line)` | to a line you name |

Bare `RESUME` only terminates if the handler fixed whatever was wrong — that is what
it is for.

`TRAP` with no argument turns trapping off. An error *inside* a handler is reported
normally rather than re-entering it, so a broken handler cannot loop forever.

## STOP, END and CONT

`STOP` stops the program and returns to the prompt; `CONT` resumes from there. `END`
stops it without arming `CONT`. `QUIT` ends the interpreter itself.
