The simplest form of assignment assigns the value of a single expression to a single variable. In addition, there are two forms of multiple assignments, one for assigning a set of expressions to a set of variables, and one for assigning a set of return results (from a single invocation) to a set of variables. (Theta supports multi-valued routines.)
An assignment statement has one of two forms:
<statement> -> <lhs> ":=" <expr> ["," <expr>]* | <lhs> ":=" <invoc>where
<lhs> -> <var> ["," <var> ]* <var> -> <idn> | <primary> "." <idn>A variable var is either an idn, a field selector (for a "record" or "struct"), or an instance variable; the form primary"."idn is used to select a field of a "record" or "struct" (B.11,B.12), or an instance variable of an object (7.5,10.4). (Instance variables can be accessed only within the module containing the object's class (10.1).) A primary is a limited kind of expression (7.16).
If the right hand side consists of one or more expressions, the number of expressions on the right hand must match the number of variables on the left hand side, and their types must be subtypes of the types of the corresponding variables. The primaries and expressions are evaluated in arbitrary order; if no exceptions are raised (see 8.14), the result of the first expression is assigned to the first variable and so on; as a result the variables (including fields of "record"s, "struct"s, and instance variables) refer to the objects obtained from evaluating the expressions. This form allows a permutation of variables, e.g.,
x, y := y, xcauses "x" to refer to the object previously referred to by "y", and "y" to refer to the object previously referred to by "x".
If the right hand side consists of an invocation, the number of return results must match the number of variables and the result types must be subtypes of those of the corresponding variables. The primaries on the left hand side and the invocation are evaluated in an arbitrary order and if no exceptions occur, the results of the invocation are assigned to the corresponding variables. An example of the use of this form is:
quotient, remainder := intdiv(a, b)
It is illegal to invoke a multi-valued routine in a context where a single result is expected (6.1). Such a routine can only be invoked in a multiple assignment statement, or in an invocation statement (8.1) (where the return results are discarded).
The assignment examples shown above use already-declared variables on the left hand side. Assignment can also be combined with declarations of new variables, so that new variables can be declared and initialized in one statement. In this case, the left hand side has the form
<lhs> -> <decl> ["," <decl>]*Declarations can be used with either expressions or an invocation on the right hand side, as above. If there are multiple expressions on the right hand side, they are evaluated in arbitrary order. If no exceptions result from evaluating the right hand side, the new variables are created and the result objects assigned to them. The statement is legal if the number of objects resulting from evaluation of the right hand side matches the number of variables declared and the types of these objects are subtypes of the corresponding variable types.
Note that either an assignment affects already-declared variables, or it affects newly-declared variables; the two forms are never mixed. Note also that the newly-declared variables cannot be used in the right hand side of the initialization assignment that creates them.
The following are legal initialization assignments:
x: int := foo + 5 c: char, i: int := 'a', 42 quotient, remainder: int := intdiv(a, b) val: int, in_range: bool := search(myset, low, high)provided "foo", "intdiv", and "search" have the following types:
foo: int intdiv: proc(int,int) returns(int,int) search: proc(set,int,int) returns(int,bool)