Statements form the bodies of classes. Within the sequence of statements forming a class definition, there may (and indeed, typically will) also occur definitions of actions and requests, which themselves have statement sequences as their bodies.
Statements will typically have side-effects, affecting the state of objects or the external world. This implies that the order of statements within a sequence is important.
Expressions within a statement sequence may furthermore refer to the state variables of the enclosing object. The values thus obtained are the current state values at the time of executing each statement. In particular, a function referencing to a state variable in its body is referring to the value of that variable at the point of function definition, not the possible values the variable might have when the function is called.
The available statement forms are:
svar := expr
Here svar is a state variable. These have the same syntax as ordinary variables and share namespace, but there are no rules for shadowing, so a state variable must be distinct from all ordinary variables in scope (and from other, already defined state variables in scope). The variable being defined may not occur in the right hand side. Initialization implicitly declares this variable as part of the state of objects instantiated from this class.
These have the same syntax as binding lists in general; adjacent bindings are mutually recursive and the bound variables scope over the rest of the statement sequence.
In addition, bindings in a statement sequence can be of the special form
pat = new exprwhich is the syntax used for instatiating objects from a class. Here expr must evaluate to a class; the effect is that a new object is created, its state initialized and its interface is matched against to pat
result exprIn the sequence of statements of a class, this must be the last statement. It defines the interface of the class; i.e., how the creator of an object may interact with it.
Within an action or a request, the result statement thod and the value returned (for requests; for actions the result is (), the dummy value of type ()).
The forms of statements up to now are the only forms that may occur in the statement sequence of a class; creating an object may only involve initiating the state, creating other objects and returning the proper interface. The remaining forms occur only within methods and procedures.
svar (! expr )* := exprThe left hand side is here either a state variable or an array L-value (when the svar is an array). Array indexing is denoted by the ! operator; several indexing operations may occur for multidimensional arrays. The right hand side may mention this and other state variables.
pat <- exprHere the right hand side must evaluate to a request or procedure; the statement expresses a call of this method and matching the pattern against the returned value.
The alternative form
exprmay also denote a request or procedure call where the binding is omitted or an action call (which does not return a value).
After/before expressions are often used as statements in this way.
if expr then stmts elsif expr then stmts else stmts
The elsif may occur zero or more times; the else part zero or one time.
case expr of (pat -> stmts)+The alternatives may use guards and/or where clauses just as in function bindings.
forall (qual)+ do stmtsHere the simplest form of qual is var <- expr, where expr evaluates to a list. The statement sequence in the body will be executed once for each element of the list, with var bound to that element. Note especially that if an expression in qual references a state variable, the value thus obtained will be the state variable value at the beginning of the loop, not any new state that might result after executing the enclosed statement sequence.
struct Counter where inc :: Action read :: Request Int reset :: Action counter = class s := 0 inc = action s := s+1 read = request result s reset = action s := 0 result Counter {..}