Control structures - if, try, for, while, until¶
Control structures control the flow of execution by providing mechanism for branching and repeating execution of code. Imba has several different control structures.
ifblocks control branchingtryblocks handle exceptions- loops (
for,while,until) allow repetitive execution of code blocks
Cheats¶
- Imba has the
if,try,while,untilandforblocks. - All blocks are expressions which can be assigned and passed around.
- There are no parentheses around conditions.
- There is no punctuation in blocks (e.g.,
if x). ifblock can haveelse ifandelsebranches.for,white,untilcan be passed and assigned as arrays.for,white,untilcanbreakandcontinue.for x in arrorfor x, idx in arrto loop over arrays.for key of objorfor key, val of objto loop over object properties.- There is no
for i; i < j; i++version offorloop in Imba. catchis optional intryblock.
The if block¶
Sometimes we want to do different things depending on some condition. For instance, 'if user is logged in, show them the profile page, and otherwise take them to the log in page.'
Just like the name suggests, the if blocks are only evaluated if some
condition is met. The condition can be any valid Imba expression, including any
of the control blocks found in this section (yes, if block itself, too!).
For example:
1 2 3 4 | var lives = 0
if lives is 0
'You are dead'
|
We can also specify what happens in the other case:
1 2 3 4 5 6 7 | var lives = 3
if lives is 0
'You are dead'
else
lives -= 1
"You have {lives} more lives"
|
The if block is not restricted to just if and else branches. One or
more additional conditions can be specified as else if branches. For
example:
1 2 3 4 5 6 7 8 9 10 | var lives = 3
if lives is 0
'You are dead'
else if lives is 1
lives -= 1
'You are mine next time!'
else
lives -= 1
"You have {lives} more lives".
|
If blocks can be assigned to variables.
1 2 3 4 5 6 7 8 9 10 | var lives = 3
var x = if lives is 0
'You are dead'
else
lives -= 1
"You have {lives} more lives"
x
# "You have 2 more lives"
|
Ternary expression¶
In some cases, we can write the if block as a ternary expression to save
space. Ternary expression is not technically a control structure, but we will
mention it here because we don't have a better things to do anyway.
1 2 | var lives = 3 var isDead = if lives is 0 then yes else no |
The else if branches cannot be used in ternary expressions.
The try block¶
Perfectly valid code will sometimes throw exceptions. Exceptions are objects generated by some error condition or thrown by some code. Exception objects will propagate through the application from the point where it was thrown, then back up through the path that lead to the point. If it is not caught somewhere on the path, it will eventually reach the JavaScript engine itself, and be treated as an 'uncaught' exception. (This is usually going to show up as a traceback in the developer console or in the terminal.)
1 2 3 4 5 6 7 | def foogGun
throw Error 'bug!'
try
footGun
catch e
console.log "That was close! Let's do it again!"
|
The e variable in the catch branch is the error object that was thrown by
the footGun method.
Note that the catch branch is optional. If we simply wish to suppress an
exception without doing anything, we can completely omit it.
1 2 3 | try
fooGun
# Look, mom, no catch!
|
Like if blocks, the try block can be assigned
1 2 3 4 | var afermath = try
footGun
catch e
'Feeling exceptionally good!'
|
The while loop¶
The while loop is the simplest control structure for repeating blocks of
code. It repeats the block while some condition is met, hence the name.
1 2 3 4 | var bullets = 1000
white bullets > 0
bullets--
|
Other than letting the while loop run until the condition no longer applies,
we can also end it prematurely by using the break or return statements.
1 2 3 4 5 6 7 8 | var count = 0
while yes # yes is always yes, so this will loop indefinitely
count++
break
count
# 1
|
The return statement can only be used inside methods or do blocks as it
doesn't really terminate the while loop, but returns from the method or do
block completely.
While looping inside a while loop, we can use continue to skip the rest
of the block. It's basically like jumping back to the top of the block.
1 2 3 4 5 6 7 | var evenNumbers = []
var i = 0
while i++ < 200
if i % 2
continue
evenNumbers.push i
|
The until loop¶
The until loop is similar to the while loop, with a reverse condition: it
will stop only once the condition is met. It is just a shorter way to say
while not condition.
1 2 3 4 | var baloons = [1, 2, 3, 4, 5]
until baloons:length is 0
baloons.pop
|
We can use break, return and continue inside until just like in the
while loops.
The for loop¶
Whereas the while and until loops are more generic, for loop is used
specifically for iterating over array members and object properties.
There are two variants of for loops:
for ... infor arrays, strings, and array-like objects.for ... offor object properties.
The for ... in loop is used like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var colorIndex = {
R: '#ff0000'
G: '#00ff00'
B: '#0000ff'
C: '#00ffff'
M: '#ff00ff'
Y: '#ffff00'
}
var colorSequence = ['R', 'M', 'R', 'G', 'B', 'C', 'M']
var colors = []
for colorKey in colorSequence
colors.push colorIndex[colorKey]
|
For loops are actually arrays, and they can be assigned and passed. In the
previous example we kept pushing into the colors array. This can be written
simply like so:
1 2 | var colors = for colorKey in colorSequence
colorIndex[colorKey]
|
In for loops, we can also access the the indices of members we are iterating
over.
1 2 3 | var colors = for colorKey, index in colorSequence
intensity: (index + 1) * 100
color: colorIndex[colorKey]
|
The for ... of loop is used for objects. In it's simpler form, for ... of
iterates over the keys.
1 2 3 4 5 6 7 8 9 10 11 | var colorIndex = {
R: '#ff0000'
G: '#00ff00'
B: '#0000ff'
C: '#00ffff'
M: '#ff00ff'
Y: '#ffff00'
}
var allColors = for key of colorIndex
key
|
We can also use for ... of to iterate over both keys and values.
1 2 3 4 | var reverseIndex = {}
for key, val of colorIndex
reverseIndex[val] = key
|
Just like the while loop, we can use break, return and continue to
terminate the loop or skip iterations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var players = [
{name: 'OP', dmg: 400, hp: 100}
{name: 'Nuclear', dmg: 300, hp: 200}
{name: 'Voe', dmg: 280, hp: 210}
{name: 'Polygon', dmg: 220, hp: 180}
{name: 'Glitter', dmg: 440, hp: 120}
{name: 'Vanilla J', dmg: 300, hp: 50}
]
var strongPlayers = for player in players
if player:dmg >= 300
player:name
else
continue
strongPlayers
# ['OP', 'Nuclear', 'Glitter', 'Vanilla J']
|