t3x.org / t3x / t3x-manual / 261.html
 
T3X - A Minimum Procedural Language
Version 8.1.5, Online Edition
Copyright(C) 1996-2004
Nils M Holm
 
Previous:
2.6 Expressions
TOC | Index | Back Next:
2.6.2 Unary Operators

2.6.1 Procedure Calls and Subscripts

The operators (), [], and :: are the only postfix operators. They always bind to primary factors in the form of symbols. Subscripts and call operators may be considered a part of a factor rather then an operator applied to a factor.

The ()-operator is the only variadic operator. Given the procedure call

P(a1, ..., aN)

its arity is N+1 (P plus N arguments). The meaning of the operator is the application of the procedure P to the (optional) arguments a1 through aN. If P does not have any formal arguments, it is called using

P()

The value of the operation depends on the semantics of P. See the description of the RETURN statement for further details.

() may only be applied to symbols of the type `procedure'. The procedure must have been declared before its first application using either a procedure definition or declaration. The number of arguments to a procedure call will be checked against the arity of the called procedure. If the numbers do not match, an error will be signalled.

Each argument to a procedure call may itself be any valid expression, which includes, of course, procedure calls. Given the binary function P2, the following expression is perfectly valid:

P2( P2(1, 2), P2( 3, P2(4, 5) ) )

An indirect procedure call may be performed using the CALL operator which is in fact an extension of the () operator. The expression

CALL PP(a1, ..., aN)

evaluates to the result of the application of PP to a1...aN, but in this case, PP is a procedure pointer instead of an actual procedure. A procedure pointer is an ordinary variable which has been assigned the address of a procedure using the address operator:

PP := @P;

In indirect procedure calls, no type checking (as described above) will be performed. If PP is the name of a procedure instead of a variable, the CALL keyword is ignored.

In direct and indirect calls, the calling scheme is call by value. This means that all arguments of the call will be evaluated before control is transferred to the called procedure, so that the value of each parametric expression will be transported to the procedure. For further details on argument passing, see the procedures section in this manual.

Procedure parameters are guranteed to be evaluated in the order of occurence (from the left to the right). For example, given the expression

P( Q(), R() );

the programmer may rely on the fact that Q() will be applied before R().

The []-operator may be applied to vectors as well as to atomic variables. The subscript in

symbol[subscript]

may be any valid expression. If a is a vector, the subscript operation

a[b]

evaluates to the b'th member of a. If a is an atomic variable, the operation evaluates to the b'th member of the vector pointed to by a. This means that both subscripts in the following example would evaluate to the same value:

var v[100], pv;
var a1, a2;

pv := v;
a1 := v[25];
a2 := pv[25];

The reason is as follows: since vectors evaluate to their addresses, the assignment

pv := v;

stores the address of v in pv. Atomic variables, on the other hand, evaluate to their values and therefore, pv evaluates to the address of v which has been previously stored in it. Consequently, v and pv both evaluate to the address of v in the above example. Hence, a variable which holds the address of a vector may be used in the place of that vector. For this reason, the subscript operator may be applied to atomic variables.

Since there is no nesting limit for vectors, any number of subscript operators may follow a single symbol. Assuming that v5 holds a vector containing five levels of nested vectors, the expression

v4[i1][i2][i3][i4][i5]

may be used to access single elements at the deepest nesting level. Such chains of subscripts evaluate from the left to the right.

The ::-operator (aka byte (subscript) operator) differs from the ordinary (word) subscript operator in serveral ways. First, it addresses bytes in (byte) vectors and second, it is right-associative. The expression

a::b

evaluates to the b'th byte of the the vector a. Therefore, :: is mostly used to access characters in strings. Since the results of ::-operations are always limited to byte-width, they cannot be assumed to return valid addresses. Byte subscripts are right-associative, since their results may very well be a valid subscripts, though). If the expression

a :: b :: c

would evaluate from the left to the right (a::b :: c) the result of a::b would probably not be a valid address, since it is limited to eight bits. In this case, however, the following subscript would reference the position c of a non-vector - which is certainly not the desired result. If, on the other hand, the expression evaluates from the right to the left (a :: b::c) the subexpression b::c is evaluated first and will probably return a valid subscript. This subscript is then applied to the (also valid) vector a.

Finally, the :: operator differs from [] in the fact that it has no righthand side delimiter. Therefore, the righthand side of :: is always a single factor and expressions like

a::b+c

actually evaluate to

(a::b)+c

This is because :: has the highest precedence. To address the b+c'th byte in the array a, the subscript must be parenthesized:

a::(b+c)
Previous:
2.6 Expressions
TOC | Index | Back Next:
2.6.2 Unary Operators