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 aliases oh, yeah or baby – see below.
  • The else or otherwise keywords implicitly end the current block and start the alternate block for the current if.

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. Rockstar historically used a blank line to denote the end of a block; this turned out to be really confusing when you had nested blocks, so as well as a blank line, you can now 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)

For-in loops

Use for <variable> in <expression> to loop through all the characters in a string, or all the integers up to a limit.

String says hello
For character in string
Write character with "!"
End
(writes: h!e!l!l!o!)

Limit is 5
for counter in limit
Write counter
End
(writes: 01234)


Loops: While and Until

Conditional 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
)