Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
329 lines (263 sloc) 13.3 KB
@head
@title Statements
@h2 Blocks
@grammar
block :: ((lvar-def | statement) br)*
statement :: expression | assignment-stmt | operator-assignment-stmt
| if-stmt | switch-stmt | while-stmt | repeat-stmt | for-stmt
| break-stmt | return-stmt | try-stmt | raise-stmt
@end
<p>A block contains any number of statements and local variable definitions.
It is the basic building block
of functions, methods and compound statements. A block is evaluated by
evaluating its statements sequentially. If one of the statements either raises
an exception or is a break or return statement, the execution of the block
terminates and the rest of the statements are not evaluated.
@h2 Expression statement
<p>Any expression is also a valid statement. An expression statement simply
evaluates the expression and discards its result. Expression statements are
typically used for calling functions or methods.
@h2 Assignment statement
@grammar
assignment-stmt :: expression "=" expression
@end
<p>Assign the value of the expression on the right-hand side of the assignment
operator to the lvalue on the left-hand side. The left-hand side must be a
valid lvalue expression. Otherwise, a compile error is reported.
<p>If the left expression is not an array constructor, assign the value of the
expression like this:
<ul>
<li>If the expression is a global or local variable reference, assign the
value to that variable.
<li>If the expression is a member variable reference, call the setter method
related to the referred member variable of the base object, with
the value of the right-hand side expression as the argument.
<li>If the expression is a subscript expression, call the <tt>_set</tt>
method of the subscripted object, with the value of the bracketed
expression as the first argument and the value of the right-hand side
expression as the second argument.
<li>If the expression is a superclass member variable reference (see
@href{Superclass member references}), call the
relevant setter method defined in the superclass. This is performed in
a similar fashion as ordinary setter calls (see above).
<li>In a <tt>create</tt> method only: If the expression refers to an explicit
member constant defined in the same class as the method, assign the value
directly to the value slot associated with the constant.
</ul>
<p>If the left expression is a tuple or array constructor, the assignment is a
<i>multi-assignment</i>. The right
expression must evaluate to a tuple or array with the same number of items as
in the lvalue, or otherwise a @ref{std::ValueError} or @ref{std::TypeError}
exception will be raised. Each
item expression in the left side will be assigned a value from the right
side value, the first item getting the first array item, the second the
second one, etc. These assignments are performed according to the rules in the
above list.
<p>If the setter or the <tt>_set</tt> method mentioned above is not defined, a
@ref{std::MemberError} exception will raised when evaluating the assignment
statement.
@h2 Operator assignment statement
@grammar
operator-assignment-stmt :: expression operator-assignment expression
operator-assignment :: "+=" | "-=" | "*=" | "/=" | "**="
@end
<p>Evaluate the value of the expression on the left-hand side of the operator
assignment token and the value of the right-hand-side expression.
Evaluate the binary operation suggested by the
operator assignment token, with the value of the left expression as the left
operand, and the value of the right expression as the right
operand, and assign the resulting value to the left expression, which is now
interpreted as an lvalue. The subexpressions of the left expression are
evaluated only once during the evaluation of the statement, however.
<p>The semantics of the assignment are essentially identical to the assignment
statement, but the left expression must not be an array constructor. The
semantics of the binary operation are described in section
@href{Binary operations}.
@h2 Local variable definition
@grammar
lvar-def :: "var" id-list [ "=" expression ]
@end
<p>Define one or more local variables. If the optional initialization part
is missing, the variables will be initialized to refer to the <tt>nil</tt>
object.
Otherwise, the initialization expression is evaluated and its results are
assigned to the variables. The semantics are similar to the assignment
statement: If there is a single variable, the result of the expression is
assigned to that variable. If there are multiple variables, the result should
be an <tt>Array</tt> object with as many items as there are variables. The
array items will be assigned sequentially to the variables. If the result is
not an <tt>Array</tt> object or contains a wrong number of items, an exception
will be raised.
<p>The local variables are visible and can be accessed only in the block that
contains the definition and only in statements that follow the definition.
@h2 If statement
@grammar
if-stmt ::
"if" expression br block
( "elif" expression br block )*
[ "else" br block ]
"end"
@end
<p>An if statement tests the truth value of a condition expression or
expressions, and executes at most a single block related to a true condition
(or the else block if no conditions are true).
All the condition expressions are evaluated in a boolean context.
<p>First, the expression after <tt>if</tt> is evaluated. If it is true, the
first block will be evaluated. Otherwise, if there are <tt>elif</tt>
conditions, they are evaluated sequentially until one of them evaluates to
true or until they
have all been evaluated. If one of them evaluated to true,
the block following that expression will be evaluated. If no
condition evaluates to true and the else part is provided, the block in the
else part will be evaluated. Otherwise, no blocks will be evaluated. After
evaluating a block the evaluation of the statement is complete.
<p>If any expression causes an exception to be raised, or any expression
evaluates to a non-boolean value, the evaluation of the statement will be
terminated.
@h2 Switch statement
@grammar
switch-stmt ::
"switch" expression br
( "case" expression-list br block )+
[ "else" br block ]
"end"
expression-list :: single-expression ("," single-expression)*
@end
<p>Switch statement first evaluates the expression after the <tt>switch</tt>
keyword. Then, the expressions after the case keywords are evaluated
sequentially. After evaluating each expression, the value of the expression is
compared for equality with the value of the switch expression. If they compare
equal, the block after the case expression is evaluated, and the statement
finishes.
<p>If no case expression is equal to the switch expression, the block
following the else keyword is evaluated, if it exists. Otherwise, no block will
be evaluated.
@h2 Loops
<p>Loops are used to perform a block (the body of the loop) repeatedly until
some condition is fulfilled.
<p>Any loop will be terminated if an exception is raised within the body (and
not caught within the body) or
while evaluating the conditional expression, or if a break or return statement
is used to break out of the loop.
<h3>While statement</h3>
@grammar
while-stmt :: "while" expression br block "end"
@end
<p>The while statement is evaluated by evaluating the expression in a
boolean context, and if the expression evaluates to <tt>True</tt>, the body
of the statement is evaluated. The evaluation of the loop continues by
evaluating the expression and body until the expression evaluates to
<tt>False</tt>, after which the evaluation of the statement is finished.
<h3>Repeat statement</h3>
@grammar
repeat-stmt :: "repeat" br block "until" expression
@end
<p>The repeat statement is evaluated by evaluating the body and then evaluating
the expression in a boolean context. If the expression evaluates to
<tt>True</tt>,
the loop terminates. If it evaluates to <tt>False</tt>, evaluation of
the loop continues by evaluating the body and the expression repeatedly until
the expression evaluates to <tt>True</tt>.
<h3>For statement</h3>
@grammar
for-stmt :: "for" id-list "in" expression br block "end"
@end
<p>The for statement is evaluated as follows:
<ol>
<li>Evaluate the expression after <tt>in</tt>.
<li>Call the method <tt>iterator</tt> of the expression result
value with no arguments. The result of the method call is the iterator
object, and a reference to it is stored during the execution of the loop.
<li>Call the method <tt>hasNext</tt> of the iterator with no arguments
in a boolean context. If the result is <tt>False</tt>, end the loop.
Otherwise, continue to the next step.
<li>Call the method <tt>next</tt> of the iterator with no arguments.
Assign the return value to the variable list located before <tt>in</tt>,
using the semantics described above in @href{Local variable definition}.
The variables in the list are visible only in the loop body. Unlike other
local variables, they cannot be used as lvalues, i.e. they behave like
constants.
<li>Evaluate the body of the loop.
<li>Return to step 3.
</ol>
@h2 Break statement
@grammar
break-stmt :: "break"
@end
<p>The break statements jumps out of the innermost enclosing for, while or
repeat loop in the source file. After evaluation, execution continues
in the next statement or expression to be evaluated after the loop statement,
unless there are any try-finally statements between break and the loop.
In the latter case, the finally block or blocks are evaluated before execution
continues.
<p>It is an error to use break outside a loop. You cannot break out of a loop
defined in another, enclosing function.
@h2 Return statement
@grammar
return-stmt :: "return" [ expression ]
@end
<p>Return from a function or method. If the expression is provided, evaluate
the expression before returning and pass it to the caller as the return value
of the function or method. If the expression is omitted, <tt>nil</tt>
is provided as the return value.
<p>In the presence of nested function definitions, this statement always
returns from the innermost function or method that contains the statement.
It is an error to use return outside a function.
<p>If the return statement is within a try-finally block, the finally block
or blocks will be evaluated before returning from the function.
@h2 Try statement
@grammar
try-stmt ::
"try" br block
( ("except" [ id "is" ] gvar br block)+ | "finally" br block )
"end"
@end
<p>The try statement actually refers to two different statements:
<i>try-except</i> and <i>try-finally</i>. They are both used for dealing with
raised exceptions. The try variant is determined by the keyword following the
first block in the statement (<tt>except</tt> or <tt>finally</tt>).
<h3>Try-except</h3>
<p>The try-except statement contains one or more <i>except blocks</i> after
the statement body. Each except block contains a global variable
reference that must refer to a class definition (a type), a block, and
optionally an identifier before the <tt>is</tt> keyword that defines a local
variable. The identifier, if present, must be a valid name for a local
variable at that context.
<p>The try-except statement evaluates the block after the <tt>try</tt>
keyword. If no exception propagating outside the block is raised within the
block, the evaluation of the statement ends there. Otherwise, the except
blocks are consulted in the order they appear in the statement, and the type
of the uncaught exception object is compared against the type references after
each <tt>except</tt> keyword. If the exception object belongs to one of the
types, the block after the <tt>except</tt> keyword is evaluated, and after this
the statement evaluation is finished. In this case, the exception was
<i>caught</i>, and the exception object is no longer active.
If no types match, the exception will be propagated further as if the try
statement did not exist.
<p>If the except block that matches the exception contains a local variable
definition (before <tt>is</tt>), the exception object will be assigned to
that local variable before evaluating the block.
<h3>Try-finally</h3>
<p>The try-finally statement contains an additional <i>finally block</i> after
the <tt>finally</tt> keyword. The block after the <tt>try</tt> keyword is
evaluated, as
in the try-except variant. If no uncaught exception was raised within the
block, the finally block will then be evaluated and the evaluation of the
statement ends there. If an uncaught exception was raised, the finally block
will be evaluated as well, but the original exception object will be raised
again after evaluating the finally block, provided that no uncaught exception
was raised within the finally block.
<p>If a break statement is used to leave the body of the try-finally
statement, the finally block will be evaluated before execution is continued
normally outside the innermost loop.
<p>Similarly, a return statement within the body causes the finally block
to be evaluated before returning from the function or method.
@h2 Raise statement
@grammar
raise-stmt :: "raise" expression
@end
<p>First, the expression is evaluated. It should evaluate to an instance of
@ref{std::Exception} or any subtype of @ref{std::Exception}. In that case, the
value of the expression will be raised as an exception. Otherwise if the type
of the expression is invalid, a @ref{std::TypeError} exception will be
raised.
Something went wrong with that request. Please try again.