EXPRESSIONS

expression = value-expression | reference-expression | designational-expression value-expression = arithmetic-expression | Boolean-expression | character-expression reference-expression = object-expression | text-expression

The primary constituents of programs describing algorithmic processes are expressions. Constituents of these expressions, except for certain delimiters, are constants, variables, function designators, labels, class and attribute identifiers, switch designators and elementary operators. Since the syntactic definition of both variables and function designators (see below) contain expressions, the definition of expressions and their constituents is necessarily recursive.

A value expression is a rule for obtaining a value.

An object expression is a rule for obtaining an object reference.

A text expression is a rule for obtaining an identification of a text variable (and thereby a text reference).

A designational expression is a rule for obtaining a reference to a program point.

Any value expression or reference expression has an associated type, which is textually defined.

variable = simple-variable-1 | subscripted-variable simple-variable-1 = identifier-1 subscripted-variable = array-identifier-1 "(" subscript-list ")" array-identifier-1 = identifier-1 subscript-list = subscript-expression { , subscript-expression } subscript-expression = arithmetic-expression

A variable local to a block instance is a memory device whose "contents" are either a value or a reference, according to the type of the variable. The contents of a variable may be changed by an appropriate assignment operation, see 4.1. A reference is a piece of information which identifies a value, called the "referenced" value. The distinction between a reference and the referenced value is determined by context.

Variables are of two kinds, corresponding to the values being represented, namely value type variables and reference type variables.

A value type variable has a value which is the contents of the variable. A reference type variable is said to have a value which is the one referenced by the contents of the variable.

The value of an array identifier is the ordered set of values of the corresponding array of subscripted variables.

**Examples**

delta a17 q(7,2) x(sin(n*pi/2),q(3,n,4))

A simple-variable-1 is any variable which is not a subscripted variable. The corresponding values are described in chapter 2.

**Note**: Certain syntax classes (such as simple-variable-1) are marked with
a "-1". The corresponding program terms may contain a remote identifier
(see 5.5.6).

Value type variables have values of integer type, real type, **Boolean** or
**character**.

An object reference variable has an object as its value (or the value **none**).
Text variables are described below.

A text variable is conceptually an instance of a composite structure with four constituent components (attributes):

ref(TEXTOBJ) OBJ;integerSTART, LENGTH, POS;

Let X be a text variable. Then X.OBJ, X.START, X.LENGTH and X.POS denote the components of X, respectively. These four components are not directly accessible to the user. Instead, certain properties of a text variable are represented by procedures accessible through the dot notation. These procedures are described in chapter 8.

The components OBJ, START and LENGTH constitute the text reference part of the variable. They identify the frame referenced (see 2.5.1). POS is used for accessing the individual characters of the frame referenced (see 9.2).

The components of a text variable always satisfy one of the following two sets of conditions:

1) OBJ =/=noneSTART >= 1 LENGTH >= 1 START + LENGTH <= OBJ.SIZE + 1 1 <= POS <= LENGTH + 1 2) OBJ ==noneSTART = 1 LENGTH = 0 POS = 1

The latter alternative defines the contents of a variable which references no
frame. Note that this alternative thereby defines the special text reference
**notext**.

Subscripted variables designate values which are components of multi- dimensional arrays. Each arithmetic expression of the subscript list occupies one subscript position of the subscripted variable and is called a subscript. The complete list of subscripts is enclosed by the subscript parentheses ( ) . The array component referred to by a subscripted variable is specified by the actual value of its subscripts.

Each subscript position acts like a variable of type **integer** and the
evaluation of the subscript is understood to be equivalent to an assignment to
this fictitious variable. The value of the subscripted variable is defined
only if the actual integer value of each subscript expression is within the
associated subscript bounds of the array. A subscript expression value outside
its associated bounds causes a run time error.

function-designator = procedure-identifier-1 [ actual-parameter-part ] procedure-identifier-1 = identifier-1 actual-parameter-part = "(" actual-parameter { , actual-parameter } ")" actual-parameter = expression | array-identifier-1 | switch-identifier | procedure-identifier-1

A function designator defines a value which results through the application of a given set of rules defined by a procedure declaration (see 5.4) to a fixed set of actual parameters. The rules governing specification of actual parameters are given in 4.6.

**Note**: Not every procedure declaration defines rules for determining the
value of a function designator (cf. 5.4.1).

**Examples**

sin(a-b) j(v+s,n) r ss(s-5, !Temperature; T, !Pressure; P) compile ("( := )", !Stack; q)

identifier-1 = identifier | remote-identifier remote-identifier = simple-object-expression . attribute-identifier | text-primary . attribute-identifier attribute-identifier = identifier

Let X be a simple object expression qualified by the class C, and let A be an appropriate attribute identifier. Then the remote identifier "X.A", if valid, is an attribute identification whose object is the value X and whose qualification is C (cf. 5.5.6).

The remote identifier X.A is valid if the following conditions are satisfied:

- The value X is different from
**none**. - The object referenced by X has no
**class**attribute declared at any prefix level equal or outer to that of C.

**Note**: Condition 1 corresponds to a check which causes an error if the
value of X is **none**.

Condition 2 is an ad hoc rule intended to simplify the language and
its implementations.

A remote identifier of the form

text-primary.attribute-identifier

identifies an attribute of the text variable identified by evaluating the text primary, provided that the attribute identifier is one of the procedure identifiers defined in chapter 8.

**Note**: Even if the text primary references **notext**, the attribute access
is legal (in contrast to object expressions).

**Example**

Let P1 and P2 be variables declared and initialized as in example 2 of 4.1.4. Then the value of the expression

P1.plus (P2)is a new "point" object which represents the vector sum of P1 and P2. The value of the expression

P1quapolar.plus (P2)is a new "polar" object representing the same vector sum.

Boolean-expression = simple-Boolean-expression | if-clause simple-Boolean-expressionelseBoolean-expression simple-Boolean-expression = Boolean-tertiary {orelseBoolean-tertiary } Boolean-tertiary = equivalence {andthenequivalence } equivalence = implication {eqvimplication } implication = Boolean-term {impBoolean-term } Boolean-term = Boolean-factor {orBoolean-factor } Boolean-factor = Boolean-secondary {andBoolean-secondary } Boolean-secondary = [not] Boolean-primary Boolean-primary = logical-value | variable | function-designator | relation | "(" Boolean-expression ")"

A Boolean expression is of type **Boolean**. It is a rule for computing a
logical value. Except for the operators **and** **then** and **or** **else** (see 3.4)
the semantics are entirely analogous to those given for arithmetic expressions.

Variables and function designators entered as Boolean primaries must be of type
**Boolean**.

**Examples**

x = -2 Y>vorz<q a+b> -5andz-d>q**2 pandnotqorx<>y t.moreandthent.getchar x ==noneorelsex.a>0ifk<1thens>welseh<=cifififathenbelsecthendelsefthengelseh<k

relation = arithmetic-relation | character-relation | text-value-relation | object-relation | object-reference-relation | text-reference-relation value-relational-operator = < | <= | = | >= | > | <> reference-comparator = == | =/=

The value relational operators have the conventional meaning. Their specific interpretation is described below in connection to the respective types. The reference comparators have the same priority level as the relational operators.

arithmetic-relation = simple-arithmetic-expression value-relational-operator simple-arithmetic-expression

The relational operators <, <=, =, >=, > and <> have their conventional meaning
(less than, less than or equal to, equal to, greater than or equal to, greater
than, not equal to). Arithmetic relations assume the value **true** whenever the
corresponding relation is satisfied for the expressions involved, otherwise
**false**. If the two constituent expressions are of different arithmetic types
conversion to the type with maximum value range is assumed. Consequently
overflow cannot occur during the evaluation.

character-relation = simple-character-expression value-relational-operator simple-character-expression

Character values may be compared for equality and inequality and ranked with respect to the collating sequence. Let X and Y be simple character expressions, and let rel be any value relational operator. Then the relation "X rel Y" has the same Boolean value as the relation "rank(X) rel rank(Y)".

**Note**: Because of variations in collating sequences the value of a character
relation (and by implication that of a text relation, see below) is
implementation-defined. Implementation-independent comparison of
character values is obtained by using the procedure "isorank".

text-value-relation = simple-text-expression value-relational-operator simple-text-expression

Two text values are equal if they are both empty, or if they are both instances of the same character sequence, otherwise they are unequal.

A text value T ranks lower than a text value U if and only if they are unequal and one of the following conditions is fulfilled:

- T is empty.
- U is equal to T followed by one or more characters.
- When comparing T and U from left to right the first non-matching character in T ranks lower than the corresponding character in U.

object-relation = simple-object-expressionisclass-identifier | simple-object-expressioninclass-identifier

The operators **is** and **in** may be used to test the class membership of an
object.

The relation "X **is** C" has the value **true** if X refers to an object belonging
to the class C, otherwise the value is **false**.

The relation "X **in** C" has the value **true** if X refers to an object belonging
to a class C or a class inner to C, otherwise the value is **false**.

object-reference-relation = simple-object-expression reference-comparator simple-object-expression

The reference comparators == and =/= may be used for the comparison of
references (as distinct from the corresponding referenced values). Two object
references X and Y are said to be "identical" if they refer to the same object
or if they both are **none**. In that event the relation "X==Y" has the value
**true**, otherwise the value is **false**.

The value of the relation "X=/=Y" is the negation of that of "X==Y".

text-reference-relation = simple-text-expression reference-comparator simple-text-expression

Let T and U be text variables. The relation "T==U" is equivalent to

T.OBJ == U.OBJandT.START = U.STARTandT.LENGTH = U.LENGTH

**Note**: The POS components are ignored. Also observe that the relations
"T=/=U" and "T=U" may both have the value **true**. (T and U reference
different text frames which contain the same text value.)

The following relations are all true (cf. 2.5)

T =notexteqvT ==notext"" ==notext"ABC" =/= "ABC" (different occurrences)

**Example**

classC;begintextT; T:- "ABC"end;

The relation "**new** C.T == **new** C.T" is **true** here.

The meaning of the logical operators **not**, **and**, **or**, **imp**, and **eqv** is
given by the following function table:

b1falsefalsetruetrueb2falsetruefalsetrue---------------------------------------------------------notb1truetruefalsefalseb1andb2falsefalsefalsetrueb1orb2falsetruetruetrueb1impb2truetruefalsetrueb1eqvb2truefalsefalsetrue----------------------------------------------------------

The operation "b1 **and** **then** b2" denotes "conditional and". If the value of
b1 is **false** the operation yields the result **false**, otherwise it yields the
result of evaluating b2.

The operation "b1 **or** **else** b2" denotes "conditional or". If the value of b1
is **true** the operator yields the result **true**, otherwise it yields the result
of evaluating b2.

**Note**: The value of "b1 **and** **then** b2" is given by textual substitution of
the Boolean expression "(**if** b1 **then** b2 **else** **false**)". Similarly,
the operation "b1 **or** **else** b2" is defined by substitution of "(**if** b1
**then** **true** **else** b2)". These definitions imply that the evaluation
of the second operand is suppressed when the evaluation result is
already evident from the value of the first operand alone.

The sequence of operations within one expression is generally from left to right, with the following additional rules.

According to the syntax given in 3.2 the following rules of precedence hold:

first: non-Boolean expressions second: < <= = >= > <> == =/=isinthird:notfourth:andfifth:orsixth:impseventh:eqveighth:andthennineth:orelse

The use of parentheses is interpreted in the sense given in 3.5.2.

arithmetic-expression = simple-arithmetic-expression | if-clause simple-arithmetic-expressionelsearithmetic-expression simple-arithmetic-expression = [ + | - ] term { ( + | - ) term } term = factor { ( * | / | // ) factor } factor = primary { ** primary } primary = unsigned-number | variable | function-designator | "(" arithmetic-expression ")"

An arithmetic expression is a rule for computing a numerical value. In the case of simple arithmetic expressions this value is obtained by executing the indicated arithmetic operations on the actual numerical values of the primaries of the expression, as explained in detail in 3.5.1 below. The value of a primary is obvious in the case of numbers. For variables it is the current value (assigned last in the dynamic sense), and for function designators it is the value arising from the computing rules defining the procedure when applied to the current values of the procedure parameters given in the expression. Finally, for arithmetic expressions enclosed by parentheses the value must through a recursive analysis be expressed in terms of the values of primaries of the other three kinds.

In the more general arithmetic expressions, which include if-clauses, one out
of several simple arithmetic expressions is selected on the basis of the actual
values of the Boolean expressions (see 3.2). This selection is made as follows:
The Boolean expressions of the if-clauses are evaluated one by one in sequence
from left to right until one having the value **true** is found. The value of the
arithmetic expression is then the value of the first arithmetic expression
following this Boolean (the longest arithmetic expression found in this
position is understood). If none of the Boolean expressions has the value
**true**, then the value of the arithmetic expression is the value of the
expression following the final **else**.

In evaluating an arithmetic expression, all primaries within that expression are evaluated with the following exceptions:

- Primaries that occur within any expression governed by an if-clause but not selected by it.
- Primaries that occur within a Boolean expression
- after the operator
**or****else**when the evaluation of a preceding Boolean tertiary results in**false**, or - after the operator
**and****then**when the evaluation of a preceding equivalence results in**false**.

- after the operator
- Primaries that occur after a function designator, and the evaluation of the function terminates with a goto-statement. In this case the evaluation of the arithmetic expression is abandoned.

Primaries are always evaluated in strict lexical order.

**Examples**:

Primaries: 7.394_604&-8 sum w(i + 2,8) cos( y + z*3.141_592_653_589_793_324&&0 ) ( a - 3/y + vu**8) Factors: omega sum ** cos( y + z*3 ) 7.394&-8 ** w(i + 2,8) ** ( a - 3/y + vu ** 8 ) Terms: u omega * sum ** cos(y + z*3)/7.394&-8 ** (a - 3/y + vu**8) Simple arithmetic expression: u - yu + omega*sum**cos(y+z*3)/7.394&-8 **(a-3/y+vu**8) Arithmetic expressions: w*u - q(s+cu)**2ifq>0thens+3*q//aelse2*s+3*qifa<0thenu+velseifa*b>17thenu/velseifk >= ythenv/uelse0 0.57&12 * a( n*(n-1)//2 ,0 ) ( a*arctan(y)+z ) ** (7+Q)ifqthenn-1elsen

Apart from the Boolean expressions of if-clauses, the constituents of arithmetic expressions must be of arithmetic types. The meaning of the basic operators and the types of the expressions to which they lead are given by the following rules, where "i" and "j" are of integer type, "r" of real type, and "x" is any arithmetic type:

- The operators +, -, and * have their conventional meaning.
- The operator / denotes real division. Any operand of integer type is converted before the operation. Division by zero constitutes an error.
- The operator // denotes integer division. It is valid only for integer
type operands (no implicit conversion). The meaning of "i//j" is defined
by:
**integer****procedure**DIV(i, j);**integer**i, j;**if**j=0**then**error("..." !div by zero;)**else****begin****integer**m, n; m:= 0; n:= abs(i);**for**n:= n - abs(j)**while**n>=0**do**m:= m + 1; DIV:=**if**i<0**eqv**j>0**then**-m**else**m**end**DIV; - The operator ** denotes exponentiation. The value and type of the
operation depends upon the types of the operands as follows:
x**r: <type of r>

**procedure**EXPR(x,r);x; r; **if**x<0**or**(x=0**and**r<=0.0)**then**error("..." !EXPR undefined;);**else**EXPR :=**if**x>0**then**exp(r*ln(x))**else**0.0; i**j:**integer****procedure**EXPI(i,j);**integer**i,j;**if**j<0**or**i=0**and**j=0**then**error("..." !EXPI undefined;)**else****begin****integer**k,result; result:= 1;**for**k:= 1**step**1**until**j**do**result:= result*i; EXPI:= result**end**EXPI r**i: <type of r>**procedure**EXPN(r, i);r; **integer**i;**if**i=0**and**r=0.0**then**error("..." !EXPN undefined;)**else****begin**result; **integer**n; result:= 1.0;**for**n:= abs(i)**step**-1**until**1**do**result := result*r; EXPN:=**if**i<0**then**1.0/result**else**result**end**EXPN;

It is understood that the finite deviations of using the exponentiation operator may be different from those of using the procedures EXPR and EXPN.

If the operands of an arithmetic operator are of different types, or both
**short** **integer**, an appropriate type conversion function is understood to
be automatically invoked, except as explicitly noted above, before the
operation is evaluated as follows:

If one operand is of type

longrealthe other is converted tolongreal, else if one operand is of typerealthe other is converted toreal, elseshortintegeroperands are converted tointeger.

**Note**: The result of evaluating an arithmetic expression can never
be of type **short** **integer**.

Conversion from **short** **integer** to **integer** is always exact. Conversion from
an integer type to a real type is exact within an implementation-defined range
which includes zero. Conversion from **real** to **long** **real** is exact within
an implementation-defined range which includes zero.

The type of the operation (and by repeated application also the type of the arithmetic expression) is a consequence of the type conversion rule as follows:

SI I R LR SI I I R LR SI:shortintegerI I I R LR I:integerR R R R LR R:realLR LR LR LR LR LR:longreal

The rule also determines the type of a conditional expression, i.e. an arithmetic expression of the form

"

ifBthenSAEelseAE":The expression is of type

longrealif either SAE or AE islongreal. Otherwise, if either SAE or AE is of typereal, the type of the expression isreal, else the type isinteger.

**Note**: The type of a conditional expression is independent of the actual
value of the Boolean expression, i.e. it is completely determined by
the program text.

The sequence of operations within one expression is generally from left to right, with the following additional rules:

According to the syntax given in 3.3.1 the following rules of precedence hold:

first: ** second: * / // third: + -

The expression between a left parentheses and the matching right parenthesis is evaluated by itself and this value is used in subsequent calculations. Consequently the desired order of execution of operations within an expression can always be arranged by appropriate positioning of parentheses.

**Note**: The order of evaluation of the primaries is not influenced by the
use of parenthesis.

Numbers and variables of real type must be interpreted in the sense of numerical analysis, i.e. as entities defined inherently with only a finite accuracy. Similarly, the possibility of the occurrence of a finite deviation from the mathematically defined result in any arithmetic expression is explicitly understood. No exact arithmetic will be specified, however, and it is indeed understood that, different implementations may evaluate arithmetic expressions differently. The control of the possible consequences of such differences must be carried out by the methods of numerical analysis. This control must be considered a part of the process to be described, and is therefore expressed in terms of the language itself.

character-expression = simple-character-expression | if-clause simple-character-expressionelsecharacter-expression simple-character-expression = character-constant | variable | function-designator | "(" character-expression ")"

A character expression is of type **character**. It is a rule for obtaining a
character value (see 2.1.3). Apart from possible if-clauses, all constituents
of a character expression must be of type **character**.

text-expression = simple-text-expression | if-clause simple-text-expressionelsetext-expression simple-text-expression = text-primary { & text-primary } text-primary =notext| string | variable | function-designator | "(" text-expression ")"

A text expression is of type **text**. It is a rule for obtaining an
identification of a text variable. Apart from possible if-clauses, all
constituents of a text expression must be of type **text**.

Each textual occurrence of a non-empty string corresponds to a unique constant main text frame. A given occurrence always references that same frame, while different occurrences of the same non-empty string always reference different text frames.

The empty string ("") is textually equivalent to **notext**.

The operator & permits text concatenation. The simple text expression "TP1 & TP2 & ... & TPn", where TPi is a text primary (1<=i<=n), references a new alterable main frame whose contents is formed by concatenating copies of the frames referenced by TP1, TP2, ... , TPn (in that order). The expression is equivalent to CONCATENATE_n(T1,T2,...,Tn) defined by

textprocedureCONCATENATE_ _n(T1,T2,...,Tn);textT1,T2,...,Tn;begintexttemp; CONCATENATE_ _n :- temp :- blanks(T1.length+T2.length+ ... +Tn.length); temp.sub(1,t1.length) := T1; temp.sub(1+T1.length,T2.length) := T2; ... temp.sub(1+T1.length+T2.length+... ,Tn.length) := Tn;end;

**Note**: It follows that the text primary constituents of a simple text
expression are evaluated in strict lexical order. The evaluation
of Ti may influence the result of evaluating Tj, if i<j (due to
the specified "by reference" transmission of parameters to the
procedures CONCATENATE_n).

Observe further that it follows from the syntax (cfr. 3.1.5) that
. is evaluated before &, thus the two expressions
"T1 & T2.sub(1,2) & T3.main" and "T1 & (T2.sub(1,2)) & (T3.main)"
are equivalent.

The result of evaluating

**notext**, or an empty string, identifies an anonymous text variable whose contents are defined by (2) of 3.1.2.- a non-empty string identifies an anonymous text variable which references a constant text frame whose value is the internal representation of the external character sequence. This frame is always a main frame. The POS component of the anonymous variable equals 1.
- a text variable identifies the variable itself.
- a text function designator identifies an anonymous text variable which contains a copy of the final contents of the text variable associated with the procedure identifier during the execution of the procedure in question.
- a text expression enclosed by parentheses identifies an anonymous text variable which contains a copy of (the contents of) the text variable identified when evaluating the same expression without parentheses.
- a conditional text expression identifies an anonymous text variable which contains a copy of (the contents of) the text variable identified by the branch which was selected for evaluation.

For further information on the text concept, see chapter 8.

object-expression = simple-object-expression | if-clause simple-object-expressionelseobject-expression simple-object-expression =none| variable | function-designator | object-generator | local-object | qualified-object | "(" object-expression ")" object-generator =newclass-identifier [ actual-parameter-part ] local-object =thisclass-identifier qualified-object = simple-object-expressionquaclass-identifier

An object expression is of type **ref**(qualification). It is a rule for
obtaining a reference to an object. The value of the expression is the
referenced object or **none**. Apart from a possible if-clause all constituents
must be of object reference type.

The qualification of an object expression is defined by the following rules:

- The expression
**none**is qualified by a fictitious class which is inner to all declared classes. - A variable or function designator is qualified as stated in the declaration (or specification, see below) of the variable or array or procedure in question.
- An object generator, local object or qualified object is
qualified by the class of the identifier following the
symbol
**new**,**this**or**qua**respectively. - A conditional object expression is qualified by the innermost class which includes the qualifications of both alternatives. If there is no such class, the expression is illegal.
- Any formal parameter of object reference type is qualified according to its specification regardless of the qualification of the corresponding actual parameter.
- The qualification of a function designator whose procedure identifier is that of a virtual quantity depends on the access level (see 5.5.5). The qualification is that of the matching declaration, if any, occurring at the innermost prefix level equal or outer to the access level, or, if no such match exists, it is that of the virtual specification.

The value of an object generator is the object generated as the result of its evaluation. See 4.7.

A local object "**this** C" is valid provided that the expression is used within

- the class body of C or that of any subclass of C, or
- a connection block whose block qualification is C or a subclass of C (see 4.8).

The value of a local object in a given context is the object which is, or is connected by, the smallest textually enclosing block instance in which the local object is valid. If there is no such block the local object is illegal (in the given context). For an instance of a procedure or a class body, "textually enclosing" means containing its declaration.

Let X represent any simple reference expression, and let C and D be class
identifiers such that D is the qualification of X. The qualified object
"X **qua** C" is then a legal object expression, provided that C is outer to or
equal to D or is a subclass of D. Otherwise, since C and D belong to disjoint
prefix sequences, the expression is illegal.

If the value of X is **none** or is an object belonging to a class outer to C,
the evaluation of X **qua** C constitutes a run-time error. Otherwise, the value
of X **qua** C is that of X. Instantaneous qualification restricts or extends the
visibility of attributes of a concatenated class object accessible through
inspection or remote accessing (cf. 3.1.5 and 4.8).

designational-expression = simple-designational-expression | if-clause simple-designational-expressionelsedesignational-expression simple-designational-expression = label | switch-designator | "(" designational-expression ")" switch-designator = switch-identifier "(" subscript-expression ")" switch-identifier = identifier label = identifier

A designational expression is a rule for obtaining a reference to a program point. The principle of the evaluation is entirely analogous to that of arithmetic expressions. In the general case the Boolean expressions of the if-clauses select a simple designational expression. If this is a label the desired result is already found. A switch designator refers to the corresponding switch declaration and by the actual numerical value of its subscript expression selects one of the designational expressions listed in the switch declaration by counting these from left to right. Since the expression thus selected may again be a switch designator this evaluation is obviously a recursive process.

The evaluation of the subscript expression is analogous to that of subscripted variables. The value of a switch designator is defined only if the subscript expression assumes one of the values 1, 2, ... , n, where n is the number of entries in the switch list. A value outside this range causes a run time error.

**Note**: It is a consequence of the syntax that class attributes which are
labels or switches cannot be accessed by the dot notation.