Loops
Loops provide a way to repeat certain operations multiple times. Consider this function:
module main
# This func prints: 1 2 3 4 5 6 7 8 9 10 done
func start()
console::init()
console::print_int(1)
console::print(" ")
console::print_int(2)
console::print(" ")
console::print_int(3)
console::print(" ")
console::print_int(4)
console::print(" ")
console::print_int(5)
console::print(" ")
console::print_int(6)
console::print(" ")
console::print_int(7)
console::print(" ")
console::print_int(8)
console::print(" ")
console::print_int(9)
console::print(" ")
console::print_int(10)
console::print(" ")
console::print("done")
end func
end module
Instead of duplicating the code multiple times, we can make a variable i which counts upwards.
module main
# This func prints: 1 2 3 4 5 6 7 8 9 10 11 12...
func start()
var i: int
0 -> i
console::init()
loop
i + 1 -> i
console::print_int(i)
console::print(" ")
end loop
end func
end module
The code between loop and end loop will repeat endlessly. Each time through this loop, i + 1 -> i will increase the value of i by one. This prints the numbers 1 through 10, but then it keeps counting forever. How to end the loop?
Dropโ
The drop statement is used to exit a loop. (The drop keyword is often called break in other programming languages.) It moves control to the next statement after end loop. Here is how to use drop to stop counting when we reach 10:
module main
# This func prints: 1 2 3 4 5 6 7 8 9 10 done
func start()
var i: int
0 -> i
console::init()
loop
i + 1 -> i
# Stop when we reach 10
if i > 10 then
drop
end if
console::print_int(i)
console::print(" ")
end loop
console::print("done")
end func
end module
Liftโ
The lift statement causes control to move immediately to the top of the loop. (The lift keyword is often called continue in other programming languages.) In other words, it skips the rest of the loop. We can use lift to skip the even numbers:
module main
# This func prints: 1 3 5 7 9 done
func start()
var i: int
0 -> i
console::init()
loop
i + 1 -> i
# Skip the even numbers
if i % 2 = 0 then
lift
end if
# Stop when we reach 10
if i > 10 then
drop
end if
console::print_int(i)
console::print(" ")
end loop
console::print("done")
end func
end module
Relationship to JUMPโ
If you look at the Chombit assembly language that the compiler produces, you will see that loop is implemented using JUMP instructions. Normally programs go step by step, executing one statement after another. A jump causes the CPU to move to an arbitrary step, instead of the next one.
We can understand loop in terms of jumps:
. . .
loop
# ๐ฏ Position A
i + 1 -> i
if i % 2 = 0 then
# ๐ Jump up to position A
lift
end if
# Stop when we reach 10
if i > 10 then
# ๐ Jump down to position B
drop
end if
console::print_int(i)
console::print(" ")
# ๐ Jump up to position A
end loop
# ๐ฏ Position B
console::print("done")
. . .
Some programming languages allow arbitrary jumps, for example using goto statement. This is much more flexible, however it turns out that jumps are very difficult to understand and debug. Code is much easier to understand if we restrict ourselves to use only loop, lift, drop, and if for jumping around. In practice, this restriction does not limit the kinds of programs that we can write.