Documentation/Chapters

Decisions and repetition

On this page

Programs become useful when they choose what to do and repeat work over data. BASIL provides structured blocks so the start, end and cleanup of each operation are visible.

Choose a branch

temperature = 18
IF temperature < 10 THEN
    PRINT "Take a coat"
ELSEIF temperature < 20 THEN
    PRINT "Take a sweater"
ELSE
    PRINT "Enjoy the sunshine"
END IF
IF temperature >= 0 THEN PRINT "Above freezing"

The first true branch runs. An ELSE handles all remaining cases. A single-line IF is useful for one simple statement; use a block for multiple operations or nested control flow. An assignment in one branch does not prove a variable initialized in all branches. Declare and initialize shared results deliberately.

Count with FOR

total = 0
FOR number = 1 TO 4
    total += number
NEXT
PRINT total
FOR remaining = 3 TO 1 STEP -1
    PRINT remaining
NEXT

TO includes the final value. STEP defaults to 1. Start, end and step evaluate once when the loop begins, so changing a variable used in the end expression does not change that loop’s saved end. The counter is available after NEXT. A zero step is invalid; DOUBLE loops also reject nonfinite or stalled progress. Prefer INTEGER when you need an exact number of iterations.

Loop while a condition holds

remaining = 3
WHILE remaining > 0
    PRINT remaining
    remaining -= 1
WEND
DO
    remaining += 1
LOOP UNTIL remaining = 2
PRINT remaining

WHILE tests before each iteration and can run zero times. A footer-tested DO runs at least once. DO also permits a WHILE or UNTIL header; use either a header test or a footer test, rather than both. UNTIL stops when its condition becomes true. Ensure some operation can change the condition, or the loop will never end.

Visit elements

names = ["Ada", "Grace", "Mary"]
FOR EACH name IN names
    PRINT name
NEXT

FOR EACH avoids manual indexing. Its bindings are read-only. The collection stays protected against invalidating mutation while it is being visited, including when the body calls a helper or suspends. Build a separate result when filtering or transforming data. Dictionaries can bind both key and value.

Use EXIT FOR, EXIT WHILE or EXIT DO to leave that kind of loop early. Leaving a block releases its owned locals. There is no general CONTINUE or GOTO; use an IF around work that should run only for selected iterations.

Select a value

score = 85
SELECT CASE score
CASE 90 TO 100
    PRINT "Excellent"
CASE 70 TO 89
    PRINT "Passed"
CASE IS < 0
    PRINT "Invalid"
CASE ELSE
    PRINT "Try again"
END SELECT

The first matching case runs; there is no fallthrough. Cases can list values separated by commas, inclusive ranges, or relational tests. Put overlapping cases in a deliberate order. SELECT TYPE matches a closed choice’s alternatives; scheduler SELECT waits for task/channel/timer events. Those are separate forms, introduced in chapters 6 and 15.

From the BASIL documentation. View source ↗

Find your way around BASIL

Type to search the manual.