Popup YouTube Video
Sheerpower Logo

Looping and FOR/NEXT


Repeating Actions with Loops

Loops are one of the most powerful concepts in programming. They allow you to run the same block of code over and over again without rewriting it. This is essential for everything from counting to processing lists of data. Let's explore how loops work in Sheerpower.

1. The Simplest Loop: DO/LOOP

The simplest loop in Sheerpower is the DO/LOOP. It repeats the code between the DO and LOOP keywords forever.

If you run an infinite loop, you can stop it by pressing ALT+B or closing the console window.

! This is an infinite loop. It will never stop! ! You would have to manually stop the program. ! Typically by typing ALT+B or closing the window. do print "Help, I'm stuck in a loop!" loop

An infinite loop isn't very useful on its own. We need a way to control it.

2. Controlling the Loop: UNTIL and EXIT DO

Let's create a simple guessing game. The program needs to keep asking for the magic word until the user guesses it correctly. The UNTIL statement is ideal for this.

Flowchart: A DO/LOOP with a Condition

Start
↓
Code to Repeat
↓
Condition Met?
↝ (Loop Back)
magic_word$ = "Sheerpower" guess$ = "" do line input "Guess the magic word: ": guess$ loop until lcase$(guess$) = lcase$(magic_word$) print "You guessed it!"

Sheerpower's Unique Feature: Flexible Conditions

Unlike many other languages, Sheerpower allows you to place multiple WHILE (run while true) and UNTIL (run until true) conditions anywhere inside a DO/LOOP. This lets you create complex, multi-exit loops without messy IF statements.

3. Validation Block: DO/END DO

Sometimes you need to try something, check if it worked, and either continue or try again with helpful feedback. Traditional loops handle this awkwardly because the validation logic gets separated from the user interaction.

The Problem with Traditional Approaches:

! Messy approach - duplicates the validation condition do input "Enter a number between 1 and 10: ": num if num < 1 or num > 10 then print "Invalid input. Please try again." end if loop until num >= 1 and num <= 10 print "Looks good"

The DO/END DO Solution:

This construct runs once by default, but gives you clean control over whether to repeat with feedback:

do input "Enter a number between 1 and 10: ": num if num < 1 or num > 10 then print "Invalid input. Please try again." repeat do ! Try again end if print "Thank you" end do

Why This Can Be Easier to Maintain:

  • No duplicated conditions - validation logic appears only once
  • Clear success path - the "Thank you!" message is right where it belongs
  • Embedded feedback - error messages happen immediately after detecting the problem
  • Single responsibility - the block handles one complete interaction cycle

This pattern is ideal for any "try until successful" scenario: file operations, user input, network connections, or data validation.

4. The Counting Loop: FOR/NEXT

When you know exactly how many times you need to repeat an action, the FOR/NEXT loop is the perfect tool. It's designed specifically for counting.

1. The Initializer

i = 1

Sets the starting value of the loop counter. This may be any numeric expression.

The starting value is required.

2. The Target Value

to 10

Defines the target value the counter moves toward.

The loop runs while the counter has not yet passed this value in the direction of the step.

The target value can be any numeric expression.

If omitted, the loop has no automatic end condition.

3. The Step

step 1

Specifies how the counter changes after each iteration. The step may be positive or negative and may be any numeric expression.

If omitted, the step defaults to 1.

Example: A Rocket Launch Countdown

print "Starting countdown..." for i = 10 to 1 step -1 print i; "..." delay 1 ! Pause for 1 second next i print "Blast off!"

5. Advanced Loop Control: ITERATE and REPEAT

Sometimes you need to handle special cases *inside* a loop. ITERATE FOR skips the rest of the current loop run and moves immediately to the next item.

Example: Processing a To-Do List

dim chores$(3) chores$(1) = "Take out trash" chores$(2) = "DONE" chores$(3) = "Feed the cat" for i = 1 to size(chores$) ! Skip chores that are already marked as "DONE" if chores$(i) = "DONE" then iterate for print "Completing chore: "; chores$(i) next i

Run the Same Pass Again: REPEAT FOR

REPEAT FOR runs the current pass of a FOR loop again from the top. The counter is not stepped and its limit is not tested, so the same item is handled again — a reading that was not ready, or an answer that has to be asked for again.

Example: Reading a Sensor Again

dim readings(3) fill readings with 12, -1, 30 ! -1 means the sensor was not ready for sensor_no = 1 to 3 if readings(sensor_no) < 0 then print "Sensor"; sensor_no; "not ready -- reading it again" readings(sensor_no) = 25 ! the second reading works repeat for end if print "Sensor"; sensor_no; "reads"; readings(sensor_no) next sensor_no

Output:

Sensor 1 reads 12 Sensor 2 not ready -- reading it again Sensor 2 reads 25 Sensor 3 reads 30

Something in the pass must change before REPEAT FOR (here, the reading), or the same pass repeats forever. In a FOR EACH loop, REPEAT FOR visits the same row again.

Repeat from the Bottom: ITERATE DO

ITERATE DO repeats a DO loop by jumping to the bottom, its LOOP line: the rest of the current pass is skipped, and a LOOP WHILE or LOOP UNTIL test on that line still runs. REPEAT DO repeats from the top instead, and skips that test.

Example: Adding Up Sales, Skipping Refunds

dim amounts(5) fill amounts with 40, -5, 25, 35, -10 ! a negative amount is a refund total = 0 entry_no = 0 do entry_no++ if amounts(entry_no) < 0 then iterate do ! skip refunds total = total + amounts(entry_no) print "Added"; amounts(entry_no) loop until entry_no = size(amounts) print "Total:"; total

Output:

Added 40 Added 25 Added 35 Total: 100

The last amount is a refund. ITERATE DO still runs the LOOP UNTIL test, so the loop ends there. With REPEAT DO in its place the test would be skipped, and the loop would go on to entry 6, past the end of the array (Subscript out of bounds).

A DO WHILE or DO UNTIL test at the top is checked again after either statement. In a DO/END DO block the bottom is END DO, which does not loop back, so ITERATE DO leaves the block; use REPEAT DO to run the block again.

Which Statement Goes Where

Each statement acts on the nearest loop of its own kind, even from inside a loop of the other kind: an ITERATE DO inside a FOR loop that is inside a DO loop goes to the DO loop's LOOP line. A WHILE or UNTIL in the middle of a body tests for the nearest DO the same way: when it ends that loop it leaves any FOR loop it is in as well. It takes no name. To reach an outer loop instead, name it (section 6).

StatementGoes toThen
iterate forthe bottom: the NEXT linesteps the counter and tests its limit
repeat forthe top, for the same passno step, no limit test
exit forthe statement after NEXTthe counter keeps its value
iterate dothe bottom: the LOOP line — or END DO, which ends a DO/END DO blockruns its WHILE / UNTIL test, then any test at the top
repeat dothe top: the DO lineruns a DO WHILE / UNTIL test; skips the LOOP line's
exit dothe statement after LOOP or END DOno test runs

6. Named Loops: Reaching an Outer Loop

Every statement above acts on the innermost loop of its kind. To leave, skip or repeat an outer loop from inside an inner one, put the outer loop's name after the statement. A FOR loop is named by its counter and a FOR EACH loop by its cluster — the names their NEXT lines already use — and a DO loop gets a name with DO NAMED. Named jumps replace the flags that are otherwise set in an inner loop and tested after it.

Example: Skip a Whole Row

const row_count = 3 const col_count = 4 dim grid(row_count, col_count) for r = 1 to row_count for c = 1 to col_count grid(r, c) = r * 10 + c next c next r grid(2, 3) = -1 ! row 2 holds a negative value total = 0 for r = 1 to row_count for c = 1 to col_count if grid(r, c) < 0 then iterate for r ! skip the whole row next c for c = 1 to col_count total = total + grid(r, c) next c next r print 'Total of the clean rows:'; total

Output:

Total of the clean rows: 180

iterate for r leaves the inner FOR c loop and goes on with the next row, so rows 1 and 3 are added (50 + 130).

Example: Skip a Cluster Row from an Inner Loop

cluster orders: customer$, amount add cluster orders orders->customer$ = 'Crane' orders->amount = 300 end add add cluster orders orders->customer$ = 'Acme' orders->amount = 120 end add add cluster orders orders->customer$ = 'Bolt' orders->amount = 75 end add dim blocked$(2) fill blocked$ with 'bolt', 'Dyna' collect cluster orders sort by orders->customer$ end collect for each orders for k = 1 to size(blocked$) if same(orders->customer$, blocked$(k)) then iterate for orders next k print orders->customer$; orders->amount next orders

Output:

Acme 120 Crane 300

Naming a DO Loop: DO NAMED

do named and a name start a named DO loop, and its closer repeats the name — loop order, or end do confirm for a block — just as NEXT repeats a FOR loop's counter. A WHILE or UNTIL goes after the name: do named scan while x < 10, loop scan until done?. Then exit do order, iterate do order and repeat do order reach that loop from anywhere inside it.

Example: Answers for Each Customer (the answers come from a list here, so the example runs on its own; with line input it works the same way)

dim answers$(*) fill answers$ with 'Acme', 'maybe', 'y', 'Bolt', 'skip', 'Crane', 'n', '' answer_no = 0 do named order answer_no++ customer$ = answers$(answer_no) if customer$ = '' then exit do order do named confirm answer_no++ answer$ = answers$(answer_no) select case lcase$(answer$) case 'skip' repeat do order ! the next customer case 'y' print 'Shipped to '; customer$ case 'n' print 'Held for '; customer$ case else repeat do confirm ! ask again end select end do confirm loop order print 'done'

Output:

Shipped to Acme Held for Crane done

A bare repeat do in the skip case would have repeated the inner confirm block — the wrong loop.

The Named Forms

StatementGoes to
exit for rthe statement after next r
iterate for rthe next pass of FOR r (step, then the limit test)
repeat for rthe same pass of FOR r again
exit for ordersthe statement after next orders
iterate for ordersthe next row of FOR EACH orders
exit do scanthe statement after DO scan's closer
iterate do scanthe bottom of DO scan: its LOOP line
repeat do scanthe top of DO scan

A named statement does exactly what its bare form does, aimed at the named loop; every loop in between is left. The rules, all checked by the compiler:

  • The word after exit, iterate or repeat must match the loop: FOR for a FOR or FOR EACH loop, DO for a DO loop.
  • The name must belong to a loop that is open around the statement, in the same routine.
  • A loop name is letters, digits and underscores, with no type suffix; WHILE, UNTIL and ELSE cannot be names.
  • Loop names are their own: a DO named total and a variable total do not meet. Two DO loops one after the other may share a name; a DO inside an open DO of the same name may not.
  • Without a name, every statement works as it always has, on the innermost loop of its kind — inside named loops too.

Leaving Other Blocks

A jump — named or not — can also leave other blocks on its way out. It ends each WHEN EXCEPTION block it leaves, as END WHEN would, and it may leave a USE part: exit do there is allowed as well. A jump that leaves an ADD TABLE block, or a COLLECT or EXTRACT block, cancels it, as CANCEL ADD and CANCEL EXTRACT would: the half-built record is not written, and the collection is empty. To keep what was built so far, use EXIT ADD or EXIT EXTRACT first. A jump out of an ADD CLUSTER block keeps the row: a cluster row is added at ADD, with whatever fields were set before the jump. After a jump out of an EXTRACT or COLLECT block, the record or row it was on stays current, so a routine that finds a record and leaves with EXIT ROUTINE hands that record to its caller.

Summary: You have learned the essential looping tools in Sheerpower.
  • Use DO/LOOP when you don't know how many repetitions you need.
  • Use DO/END DO for a single-pass block that you can exit or repeat, great for validation.
  • Use FOR/NEXT when you need to loop a specific number of times.
  • Use EXIT, ITERATE and REPEAT to leave a loop, go on to its next pass or run a pass again; add a name to reach an outer loop.

(Show/Hide Sheerpower Looping Takeaways)
Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.