• Keine Ergebnisse gefunden

EVALUATING EXPRESSIONS

Im Dokument Pascal Reference (Seite 159-165)

In cases of ambiguity, an operator at a higher level is applied before one at a lower level. For instance, the following expression evaluates to 7 and not to 9:

1 + 2

*

3

Use parentheses to change operator precedence.

Thus, the following evaluates to 9 rather than 7:

(1 + 2)

*

3

If the $SIMPLE switch is on, sequences of oper-ators of the same precedence are executed from left to right. If the switch is off, the compiler may rearrange expressions and evaluate common sub-expressions only once, in order to generate optimized code. The semantics of the precedence relationships are retained, but normal associative and distributive laws are used. For example,

x *

3 + 12

is an optimization of:

3

*

(6 + (X - 2»

These optimizations can occasionally give you unexpected overflow errors. For example,

(I - 100) + (J - 100)

are optimized into the following:

(I + J) - 200

This can result in an overflow error, although the original expression did not (for example, if 11111 and IIJII were each 16400).

This optimization can be suppressed by turning on the $ DEBUG switch (except for some constant folding, for example replacing an expression such as 3*6 by 18). The $SIMPLE metacommand does ~

The compiler does not optimize REAL expressions as much as, for example, INTEGER expressions, to make sure that the result of a REAL expression is always what a simple evaluation of the expression, as given, would be. For example, the INTEGER expression

«1 + I) - 1)

*

J is optimized to:

I

*

J

but the same expression with real variables is not optimized, since the results can be different due to precision loss. Common subexpressions, such as 2

*

X in SIN (2

*

X)

*

COS (2

*

X), can still be calculated just once and reloaded as necessary, but they are saved in a special 80-bit inter-mediate precision.

The order of evaluation can be fixed by parentheses:

(A + B) + C

is evaluated by adding A and B first, but A + B + C

can be evaluated by adding A and B, Band C, or even A and C first.

Any expression can be passed as a CONST or CONSTS parameter or have its "address" found. The expression is calculated and stored in a temporary variable on the stack, and the address of this temporary variable can be used as a CONST or CONSTS parameter or in some other address context.

To avoid ambiguities, enclose such an expression wi th operators or function calls in parentheses.

For example, to invoke a procedure FOO (CONST X, Y: INTEGER), FOO {I, (J+14» must be used instead of FOO (I, J+14).

Expressions 11-15

This implies a subtle distinction in the case of functions. For example:

FUNCTION SUM (CONST A, B: INTEGER): INTEGER;

BEGIN

SUM := A;

IF B <> 0 THEN

SUM : = SUM ( SUM, (SUM ( B, 0) - l» + 1 END;

In this example, SUM is called recursively sub-tracting one from B until B is zero.

The use of a function identifier in a WITH state-ment follows a similar rule. For example, given a parameterless function, COMPLEX, which returns a record, "WITH COMPLEX" means "WITH the current value of the function." This can only occur in-side the COMPLEX function itself. However, "WITH (COMPLEX)" causes the function to be called and the result assigned to a temporary local variable.

Another way to describe this is to distinguish between "address" and "value" phrases. The left-hand side of an assignment, a reference parameter,

the ADR and ADS operators, and the WITH statement all need an address. The right-hand side of an assignment and a value parameter all need a value.

If an address is needed but only a value, such as a constant or an express ion in parentheses, is available, the value must be put into memory so i t has an address. For constants, the value goes in static memory; for expressions, the value goes in stack (local) memory. A function identifier refers to the current value of the function as an address, but causes the function to be called as a value.

Finally, in the scope of a function, the intrinsic procedure RESULT permits a reference to the current value of a function. For a function F, this means ADR F and ADR RESULT (F) are the same:

the address of the current value of F. RESULT forces use of the current value while putting the function in parentheses, as in (F(X», forces

OTHER FEATURES OF EXPRESSIONS

EVAL and RESULT are two procedures available at the extend level for use with expressions. EVAL uses a function as a procedure: RESULT yields the current value of a function within a function or nested procedure or function.

At the extend level, the function RETYPE allows you to change the type of a value.

THE EVAL PROCEDURE

EVAL evaluates its parameters without actually calling anything. Generally, you use EVAL to use a function as a procedure. In such cases, the val ues returned by functions are of no interest, so EVAL is only useful for functions with side effects. For example, a function that advances to the next item and also returns the item might be called in EVAL just to advance to the next item, since there is no need to obtain a function return value.

Examples of the EVAL procedure:

EVAL (NEXTLABEL (TRUE»

EVAL (SIDEFUNC (X, Y), INDEX (4), COUNT) THE RESULT FUNCTION

Within the scope of a function, the intrinsic procedure RESULT permits a reference to the current value of a function instead of invoking it recursively. For a function F, this means ADR F and ADR RESULT (F) are the s arne: tha t i s , the address of the current value of F. RESULT forces use of the current value, while putting the function in parentheses as in (F (X» forces evaluation of the function.

Expressions 11-17

Examples of the RESULT function:

FUNCTION FACTORIAL (I: INTEGER): INTEGERi BEGIN

FACTORIAL := li WHILE I > 1 DO BEGIN

FACTORIAL := I * RESULT (FACTORIAL):

I := I - li END:

END:

FUNCTION ABSVAL (I: INTEGER): INTEGERi BEGIN

ABSVAL := Ii

IF I < 0 THEN ABSVAL := -RESULT (ABSVAL) END:

THE RETYPE FUNCTION

Occasionally, you need to change the type of a value. You can do this with the RETYPE function, available at the extend level. If the new type is a structure, RETYPE can be followed by the usual selection syntax.

NOTE

You must use RETYPE with caution.

complicated algorithm and is unpredictable.

Examples of the RETYPE function:

It uses a sometimes

RETYPE (COLOR, 3)

RETYPE (STRING2, I*J+K) [2]

{inverse of ORO}

{effect can vary}

12 STATEMENTS

The body of a program, procedure, or function con-tains statements. Statements denote actions that the program can execute.

This section first discusses the syntax of state-ments and then separates and describes two categories of statements: simple statements and structured statements. A simple statement has no parts that are themselves other statements; a structured statement consists of two or more other statements. Table 12-1 lists the statements in each category.

Table 12-1. Statements.

Simple Structured

Assignment (:=) Procedure GOTO BREAK CYCLE RETURN Empty

Compound IF/THEN/ELSE CASE

FOR WHILE REPEAT WITH

Statements 12-1

SYNTAX

Pascal statements are separated by a semicolon (;) and enclosed by reserved words such as BEGIN and END. A statement begins, optionally, with a label.

Each of these elements of statement syntax are discussed in the following sections.

Im Dokument Pascal Reference (Seite 159-165)