Expressions occur in assignment statements or in tests.
Expressions are built of two components: operators and their operands. Most operators are binary, i. e. require two operands. Binary operators occur always between the operands (as in X/Y). Few operators are unary, i. e. require only one operand. A unary operator occurs always before the operand, as in -X.
An expression resolves into a value of a certain type. The resulting type is determined by the types of the values in the expression and the operators in the expression.
When using multiple operands in an expression, the precedence rules of table (12.1) are used.
Operator | Precedence | Category |
Not, unary +, unary -, @, ** | Highest (first) | Unary operators, power |
*, /, div, mod, and, shl, shr, as, <<, >> | Second | Multiplying operators |
+, -, or, xor, >< | Third | Adding operators |
=, <>, <, >, <=, >=, in, is | Lowest (Last) | relational operators |
When determining the precedence, the compiler uses the following rules:
In operations with unequal precedences the operands belong to the operator with the highest precedence. For example, in 5*3+7, the multiplication is higher in precedence than the addition, so it is ievaluated first. The result would be 22.
If parentheses are used in an expression, their contents is evaluated first. Thus, 5*(3+7) would result in 50.
Otherwise, binary operators of the same precedence are left-associative. 5 * 3 div 7 will evaluate to 2 and not 0.
Remark The order in which expressions of the same precedence are evaluated is not guaranteed to be left-to-right. In general, no assumptions on which subexpression is evaluated first should be made in such a case.
The compiler will decide which subexpression to evaluate first based on optimization rules. Thus, in the following expression:
a := g(3) + f(2);
f(2) may be executed before g(3). This behavior is distinctly different from Delphi or Turbo Pascal.
If one expression must be executed before the other, it is necessary to split up the statement using temporary results:
e1 := g(3); a := e1 + f(2);
A notable exception to this behavior is the evaluation of boolean expressions: if short-circuit boolean evaluation is enabled (the default) then the compiler will evaluate from left to right, but will still respect precedence, i. e. in parts with equal precedence the left operand will always be evaluated before the right one. Thus, the following example:
True or True and False
will evaluate to True, because it is equivalent to
True or (True and False)