5. Statements
A Korrin program is a sequence of statements, executed top to bottom. Each
statement occupies one logical line (§1.2), except the compound statements
(if, while, for, fn, class), whose header is one line and whose body is
an indented block.
5.1 Expression statements
Any expression on its own line is a statement; its value is discarded. The common case is a call:
print("hello")
# => hello
5.2 Assignment
assignment = assignable , "=" , expression ;
assignable = NAME | attribute | index ;
target = value evaluates value, then stores it:
name = value— binds per the nearest-binding rule (ADR 0011): ifnamealready exists in this or an enclosing scope, that binding is updated; otherwise a new binding is created in the current scope.object.field = value— sets a field on an instance.object[key] = value— sets a list element (index must be in range) or a map entry (creating it if absent).
There is no compound assignment (+= etc.) and no multiple assignment
(a, b = ...) in Milestone 1. Assigning to anything else — a literal, a call, an
operator expression — is E0104.
counter = 0
counter = counter + 1
print(counter)
# => 1
5.3 if / elif / else
if_statement =
"if" , expression , block ,
{ "elif" , expression , block } ,
[ "else" , block ] ;
Conditions are tested in order. The first truthy one's block runs; if none is
truthy and an else is present, its block runs. Truthiness:
only nil and false are falsy
(ADR 0009).
n = 2
if n == 1:
print("one")
elif n == 2:
print("two")
else:
print("many")
# => two
5.4 while
while_statement = "while" , expression , block ;
The condition is tested before each iteration; the block runs while it is truthy.
i = 0
while i < 3:
print(i)
i = i + 1
# => 0
# => 1
# => 2
5.5 for
for_statement = "for" , NAME , "in" , expression , block ;
NAME is bound to each element of the iterable in turn. Iterables in
Milestone 1: lists (elements), strings (characters as one-character strings),
maps (keys), and the ranges produced by the range builtin. A malformed header
is E0106.
total = 0
for x in [10, 20, 30]:
total = total + x
print(total)
# => 60
5.6 break and continue
break exits the innermost enclosing loop; continue skips to its next
iteration. Outside any loop they are E0202 / E0203,
reported by the resolver before the program runs.
5.7 pass
The do-nothing statement. Its only purpose is to be the body of a block that would otherwise be empty (ADR 0001):
fn todo():
pass
5.8 return
Valid only inside a function body (E0201 otherwise). return
with an expression yields that value; bare return yields nil. Reaching the
end of a function body without return also yields nil. See
§6.
5.9 fn and class
fn defines a function (§6) and class defines a class (§7). Both are
statements: they bind a name in the current scope when executed.