8. Statements and control flow
EBNF
statements = statement+ .statement = conditional | loop | reaction | expression .scoped_statements = ( (* not "end", "else:", or "elif:" *) statement )+ .A statement is either a conditional, a loop, a reaction, or an expression. Statements appear in the bodies of action fields such as conditions, scratch, and effects, as well as in other constructs that accept statement blocks.
Conditionals
Section titled “Conditionals”EBNF
conditional = conditional_branches [ "else:" alternative ] "end" .conditional_branches = "if" conditional_branch { "elif" conditional_branch } .conditional_branch = condition ":" consequent .condition = expression .consequent = scoped_statements .alternative = scoped_statements .A conditional is an if/elif/else/end construct that executes one of several statement blocks depending on which condition evaluates to a truthy value. The elif and else branches are optional.
if @person.mood > 50: @person.status = "happy"elif @person.mood > 25: @person.status = "neutral"else: @person.status = "sad"endConditions are evaluated in order. The first branch whose condition is truthy has its consequent executed; all remaining branches are skipped. If no condition is truthy and an else branch is present, its alternative is executed. If no condition is truthy and there is no else branch, execution continues past the end.
A conditional MUST be terminated by end:
// Illegal: missing 'end'if @person.mood > 50: @person.status = "happy"// Legalif @person.mood > 50: @person.status = "happy"endConditionals may be nested:
if @person.mood > 50: if @person.boldness > 50: @person.status = "confident" endendEBNF
loop = "loop" unary_expression "as" local_variable ":" scoped_statements "end" .local_variable = local_variable_sigil binding_type identifier .A loop iterates over a collection, binding each element to a local variable in turn. The body is a block of statements terminated by end.
loop @person.friends as _@friend: _@friend.trust += 5endThe collection expression MUST evaluate to an iterable value. The local variable is scoped to the loop body and is not accessible outside of it.
Loops may be nested:
loop @person.friends as _@friend: loop _@friend.items as _@item: _@item.value += 1 endendLocal variables
Section titled “Local variables”EBNF
local_variable = local_variable_sigil binding_type identifier .A local variable is a variable scoped to a single block, such as a loop body. Local variables are prefixed with the local sigil _, followed by a type sigil (@ or &) and an identifier:
_@friend_&valueLocal variables are introduced by loop statements using the as keyword. They are only accessible within the body of the construct that introduces them.