- 6.1 Expression syntax
- 6.2 Function calls
- 6.3 Set constructors
- 6.4 Value typecasts
- 6.5 The @ operator
- 6.6 Operators

6. Expressions

When using multiple operands in an expression, the precedence rules of
table (OperatorPrecedence) are used.

When determining the precedence, the compiler uses the following rules:

- In operations with unequal precedences the operands belong to the
operater with the highest precedence. For example, in
`5*3+7`, the multiplication is higher in precedence than the addition, so it is executed first. The result would be 22. - If parentheses are used in an epression, their contents is evaluated
first. Thus,
`5*(3+7)`would result in 50.

**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 expression
is evaluated first should be made in such a case.
The compiler will decide which expression to evaluate first based on
optimization rules. Thus, in the following expression:

a := g(3) + f(2);

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);

The following are valid expressions:

Expressions

GraphResult<>grError (DoItToday=Yes) and (DoItTomorrow=No); Day in WeekendAnd here are some simple expressions:

A + B -Pi ToBe or NotToBeTerms consist of factors, connected by multiplication operators.

Here are some valid terms:

Terms

2 * Pi A Div B (DoItToday=Yes) and (DoItTomorrow=No);Factors are all other constructions:

Factors

The variable reference must be a procedural type variable reference. A method designator can only be used inside the method of an object. A qualified method designator can be used outside object methods too. The function that will get called is the function with a declared parameter list that matches the actual parameter list. This means that

Function calls

- The number of actual parameters must equal the number of declared parameters.
- The types of the parameters must be compatible. For variable reference parameters, the parameter types must be exactly the same.

Type FuncType = Function: Integer; Var A : Integer; Function AddOne : Integer; begin A := A+1; AddOne := A; end; Var F : FuncType; N : Integer; begin A := 0; F := AddOne; { Assign AddOne to F, Don't call AddOne} N := AddOne; { N := 1 !!} end.In the above listing, the assigment to F will not cause the function AddOne to be called. The assignment to N, however, will call AddOne. A problem with this syntax is the following construction:

If F = AddOne Then DoSomethingHorrible;Should the compiler compare the addresses of

If F = @AddOne Then WriteLn ('Functions are equal');The left hand side of the boolean expression is an address. The right hand side also, and so the compiler compares 2 addresses. How to compare the values that both functions return ? By adding an empty parameter list:

If F()=Addone then WriteLn ('Functions return same values ');Remark that this behaviour is not compatible with Delphi syntax.

All set groups and set elements must be of the same ordinal type. The empty set is denoted by

Set constructors

[today,tomorrow] [Monday..Friday,Sunday] [ 2, 3*2, 6*2, 9*2 ] ['A'..'Z','a'..'z','0'..'9']

Value typecasts cannot be used on the left side of assignments, as variable typecasts. Here are some valid typecasts:

Typecasts

Byte('A') Char(48) boolean(1) longint(@Buffer)The type size of the expression and the size of the type cast must be the same. That is, the following doesn't work:

Integer('A') Char(4875) boolean(100) Word(@Buffer)This is different from Delphi or Turbo Pascal behaviour.

The

Address factor

Program tcast; {$T-} { @ returns untyped pointer } Type art = Array[1..100] of byte; Var Buffer : longint; PLargeBuffer : ^art; begin PLargeBuffer := @Buffer; end.Changing the

With the exception of

For unary operators, the result type is always equal to the expression type. The division (

I mod J = I - (I div J) * Jbut it executes faster than the right hand side expression.

The following are valid logical expressions:

A shr 1 { same as A div 2, but faster} Not 1 { equals -2 } Not 0 { equals -1 } Not -1 { equals 0 } B shl 2 { same as B * 2 for integers } 1 or 2 { equals 3 } 3 xor 1 { equals 2 }

**Remark: **Boolean expressions are ALWAYS evaluated with short-circuit
evaluation. This means that from the moment the result of the complete
expression is known, evaluation is stopped and the result is returned.
For instance, in the following expression:

B := True or MaybeTrue;The compiler will never look at the value of

'This is ' + 'VERY ' + 'easy !' Dirname+'\'The following is not:

Var Dirname = Pchar; ... Dirname := Dirname+'\';Because

The set type of the operands must be the same, or an error will be generated by the compiler.

Left and right operands must be of the same type. You can only mix integer and real types in relational expressions. Comparing strings is done on the basis of their ASCII code representation. When comparing pointers, the addresses to which they point are compared. This also is true for

2000-12-20