Flow Control
Conditionals: If / Else
Consider this instruction:
Go to the store. If they have oranges, get a dozen, then get some bagels.
If the store doesn’t have oranges, should you still get bagels?
C-style languages resolve this using braces and block syntax:
if (they have oranges) {
get a dozen
}
get some bagels
compared with:
if (they have oranges) {
get a dozen
get some bagels
}
Rockstar doesn’t have curly braces, because you can’t sing curly braces, so Rockstar has to use some syntactic tricks to resolve these kinds of ambiguities.
If statements can be one-liners, or conditional blocks.
One-line if
One-line if statements don’t create any block scope. However many if
statements you stack on the same line, the final statement on the line either runs or it doesn’t, and then you’re done:
if true print 1 (prints: 1)
when 1 is true say 1 else say 2 (prints: 1)
if nothing is true say "yeah" otherwise say "no" (prints: no)
if false otherwise print "rock on!" (prints: rock on!)
if 1 if 2 if 3 if 4 say 4 else say 3 else say 2 else say 1 else say 0 (prints: 4)
(the one-liner is done, so the next statement will always execute)
print 1 (prints: 1)
Multiline conditionals
Multiline conditionals are a little more complex, because they can create nested scopes. Here’s an example which uses some very un-Rockstar indentation to keep track of scope:
x is 6
if x > 1
if x > 2
if x > 3
if x > 4
if x > 5
write "six,"
end
write "five,"
end
write "four,"
end
write "three,"
end
write "two,"
otherwise
write "one,"
end
write "done!"
(writes: six,five,four,three,two,done!)
If the condition or the else
keyword is followed by a new line, it begins a new block. A block is a series of statements separated by statement separators (newlines or punctuation .!?;
). The end of a block is denoted by:
- An empty line (a line containing only whitespace and/or comments)
- The
end
keyword or any of its aliasesoh
,yeah
orbaby
– see below. - The
else
orotherwise
keywords implicitly end the current block and start the alternate block for the currentif
.
The end of file (EOF) will implicitly close any open blocks. This isn’t Lisp, folks. The parser knows what you mean.
This is the end, oh yeah, baby
Consider this example from a C-like language:
if (x) {
if (y) {
if (z {
print "this might get printed"
}
}
}
print "this always gets printed"
Before the final line, we need to close three blocks, so we use three closing braces – } } }
.
Languages like Python that use indentation to control scope don’t have this problem: indenting creates a block, and if you drop a level of indentation, the block’s over.
Rock lyrics don’t have curly braces, and they don’t have indentation. To end a block, you can use the keyword end
:
x is 4
if x is greater than 1
if x is greater than 2
if x is greater than 3
print "this appears if x is greater than 3"
oh yeah baby
print "this is always printed"
(prints: this appears if x is greater than 3
this is always printed)
Singing end end end
doesn’t sound very rock’n’roll, so Rockstar also supports the aliases oh
, yeah
and baby
- because it turns out you can get away with repeating that stuff almost ad infinitum and it just sounds like song lyrics. The Corrs’ “So Young” opens with the line “yeah, yeah, yeah, yeah, yeah”, Whitesnake’s “The Deeper The Love” has a “baby baby baby”, and if you throw in the odd “oh, yeah baby, yeah yeah yeah” you can close half-a-dozen nested blocks and nobody’s going to notice except the Rockstar parser.
My heart is empty
Your world is like a fire
The hunger is like a calling
the fire is like a hurricane heartbreak
If my heart is stronger than the hunger,
If my heart is stronger than your world,
If my heart is stronger than the fire...
Scream the fire, oh, yeah baby,
Scream the fire
(prints: 190)
Oooooh
You can also close as many blocks as you need to by using Rockstar’s oooh
keyword. This closes one block for every letter o
– so oh
closes one block, ooh
closes two blocks, oooh
closes three blocks, and so on. You can also combine oooh
with other keywords, so that oooh yeah baby
will close five blocks, and if there’s a blank line immediately after it, that’ll close a sixth block.
x = 5
if x > 1
if x > 2
if x > 3
if x > 4
if x > 5
print "this won't get printed because x is not greater than 5"
oooooh
print "this always gets printed"
(prints: this always gets printed)
Loops: While and Until
Loops are denoted by the while
and until
keywords.
(writes: 01234)
X is 0. While x is less than 5
Write x
X is with 1, yeah.
(writes: 01234)
x is 0
while x is less than 5
write x
x is with 1
end
(writes: 12345)
x is 1
until x is more than 5
write x
x is with 1
end
(writes: 54321)
x is 5
until x is nothing
write x
x is without 1
end
(writes: 1234)
The sky is like fire
the fire is like schizoidism
My heart is nothing
Until my heart is as high as the sky
It's with the fire
Write it, baby.
Nested loops create block scope: as with if
statements, you must end the block with a newline, end
, yeah
, baby
, and you can end one or more blocks using the oooh
syntax:
(writes: 0.0 0.1 0.2 1.0 1.1 1.2 2.0 2.1 2.2)
x is 0
While x is less than 3
Y is 0
While y is less than 3
write " " with x, ".", y
Y is with 1 yeah
X is with 1 yeah
To break out of a loop, use the break
keyword.
(writes: 12345)
x is 1
while x is less than 10
write x
x is with 1
if x is more than 5 break
end
X is nothing
While true
If x is 5 break
Build x up
End
Shout x (prints: 5)
To skip the rest of the current loop and start the next iteration, use the continue
keyword:
(writes: 135)
x is 0
while x is less than 5
x is with 1
if x is 2 continue
if x is 4 continue
write x
end
break
and continue
are wildcard keywords - everything between the keyword and the next end-of-statement is ignored, so the following are all equivalent:
break it down
break my heart
break on through to the other side
The angels are true... forever is nothing,
The waves are like pain
My heart says this is the end
My loneliness is nothing
Until forever
It's with the angels. Whisper it
If my loneliness is over the waves
Break my heart like glass, oh baby, whisper my heart
(writes: 1
2
3
4
5
this is the end
)