[an error occurred while processing this directive]
HP OpenVMS Systems Documentation |
HP Pascal for OpenVMS
|
Previous | Contents | Index |
A set operator forms the union, intersection, difference, or exclusive-OR of two sets, compares two sets, or tests an ordinal value for inclusion in a set. Its result is either a set or a Boolean value. Table 4-7 lists the set operators.
Operator | Example | Result |
---|---|---|
+ | A+B | Set that is the union of sets A and B |
* | A*B | Set that is the intersection of sets A and B |
- | A-B | Set of those elements of set A that are not also in set B |
= | A=B | TRUE if set A is equal to set B |
<> | A<>B | TRUE if set A is not equal to set B |
<= | A<=B | TRUE if set A is a subset of set B |
>= | A>=B | TRUE if set B is a subset of set A |
IN | C IN B | TRUE if C is an element of set B |
NOT IN | C NOT IN B | TRUE if C is not an element of B |
Most set operators require both operands to be set expressions. The IN and NOT IN operators, however, require an ordinal expression as the first operand and a set expression as the second operand. The ordinal expression must be of the same type as the set's base type. For example:
2*3 IN [1..10] 5*3 NOT IN [1..10] |
The result of this IN operation is TRUE because 2 * 3 evaluates to 6,
which is a member of the set [1..10], and the
NOT IN operation also returns TRUE because 5 * 3 evaluates to 15, which
is not a member of the set [1..10].
The XOR predeclared routine can return the set of elements that do not
appear in both sets.
Normally, HP Pascal associates each variable with one type: the type with which the variable was declared. In some systems' programming applications, you can perform operations more efficiently by relaxing HP Pascal's strict type-checking rules. HP Pascal provides the type cast operator for this purpose.
The type cast operator changes the context in which you can use a variable or an expression of a certain data type. The actual representation of the object being cast is not altered by the type cast operator. HP Pascal overrides the type only for the duration of one operation. It has one of the following forms:
{variable-identifier } {(expression) } :: type-identifier |
The type cast operator (::) separates the name of a variable or an expression in parentheses from its target type, the type to which it is being cast. The operator alters the type of the cast object at that point only.
Once you cast a variable or an expression, the object has all the properties of its target type during the execution of the operation in which the type cast operator appears. A variable and its target type must have the same allocation size. Therefore, you cannot cast a conformant-array parameter, but you can cast a fixed-size component of a conformant-array parameter. A schema variable or parameter cannot be type cast since it does not have a size that is known at compile time.
When you cast an expression in parentheses, the value of that expression can be either truncated on the left or padded on the left with zeros, so that the allocation size of the expression's value and its target type become the same. The type of a cast expression cannot be VARYING OF CHAR, a conformant-array parameter, or a discriminated schema. In addition, the target type of a cast expression cannot be VARYING OF CHAR or a discriminated schema.
Consider the following example:
TYPE F_float = PACKED RECORD Frac1 : 0..127; Expo : 0..255; Sign : BOOLEAN; Frac2 : 0..65535; END; VAR A : REAL; {In the executable section:} A::F_float.Expo := A::F_float.Expo + 1; |
In this example, the record type F_float shows the layout of an F_floating real number. The real variable A is cast as a record of this type, allowing you to access the fields containing the mantissa, exponent, sign, and fraction of A. Adding 1 to the field containing the exponent gives the same result as multiplying A by 2.0.
The operators in an expression establish the order in which HP Pascal combines the operands. The compiler performs operations with higher-precedence operators before operations with lower-precedence operators. Table 4-8 lists the order of operator precedence, from highest to lowest (operators on the same line are of equal precedence).
Operators | Precedence |
---|---|
:: | Highest |
NOT | |
** | |
*, /, DIV, REM, MOD, AND, AND_THEN | |
+, -, OR, OR_ELSE, unary +, unary - | |
=, <>, <, <=, >, >=, IN | Lowest |
In Pascal, operators of equal precedence (such as plus and minus) are combined from left to right within the expression.
You must use parentheses for correct evaluation of an expression that combines relational operators. Consider the following expression:
a<=x AND b<=y |
Without parentheses, this expression is interpreted as A<= (X AND B) <=Y. The logical operator AND requires its operands X and B to be Boolean expressions and returns a Boolean result, which is then used as an operand in evaluating one of the relational operators (<=). This operation causes an error because you cannot use relational operators with Boolean operands. You can modify the expression with parentheses as follows:
( a<=x ) AND ( b<=y ) |
In the rewritten expression, the compiler combines the Boolean values of the two relational expressions with the AND operator.
You can use parentheses in an expression to force a particular order for combining the operands. For example:
Expression | Result |
---|---|
8 * 5 DIV 2-4 | 16 |
8 * 5 DIV (2-4) | -20 |
The compiler evaluates the first expression according to normal precedence rules.
First, 8 is multiplied by 5 and the result (40) is divided by 2. Then 4 is subtracted to get 16. The parentheses in the second expression, however, force the subtraction of 4 from 2 (yielding -2) to be performed before the division of 40 by -2. The result is -20.
Parentheses can help to clarify an expression. For instance, you could write the first example as follows:
( ( 8 * 5 ) DIV 2 ) -4 |
The parentheses eliminate any confusion about how the compiler associates the operands in the expression.
The desired results of your program should not depend on the order of
subexpression evaluation. Unless you use the AND_THEN or
OR_ELSE operators, the compiler does not guarantee the order in which
subexpressions and complex expressions are evaluated. In fact, if the
result of an expression can be determined without complete evaluation,
HP Pascal can partially evaluate some logical operations.
Usually the order of evaluation does not prevent the correct result from being produced. However, order of evaluation is very important when you write logical operations involving function designators that have side effects. (A side effect is an assignment to a nonlocal variable or to a variable parameter within a function block.)
For example, the following IF statement contains two function designators for function f:
IF f( a ) AND f( b ) THEN {Statement...} |
The compiler can evaluate these two function designators in any order. Regardless of which function designator the compiler evaluates first, if the result is FALSE the other function designator does not have to be evaluated.
Suppose that function f assigns the value of its parameter to a nonlocal variable. Because you cannot know which function designator was evaluated first, you cannot be sure of the value of the nonlocal variable after the IF statement is performed.
Syntactically, a function call is an expression since it returns a value. If a function returns a pointer, an array, or a record, you can directly dereference, index, or select the returned value. For example:
WRITELN( Make_Node( 10 )^.Data[1] ); WRITELN( Make_Vector( 15 )[2] ); Make_Node( 10 )^.Data[1] := 42; |
Because HP Pascal is a strongly typed language, you cannot normally treat a value of one type as though it were of a different type, as you can in many languages. For example, you cannot assign the character '1' to a variable of type INTEGER, because '1' is not an integer constant but a character constant. However, there are times when it makes sense to combine values of two different types because the values have some aspect in common. For example, suppose you wish to add a value of type REAL to a value of type INTEGER. This operation is legal because the value of type INTEGER is converted to its equivalent value of type REAL before the operation is performed. The result of the operation is of type REAL.
In HP Pascal, values are converted from one type to another when the conversion is required for an operation, an assignment, or a formal/actual parameter association. Before any type conversion, the arithmetic types are ranked as follows, from lowest to highest:
Similarly, the character types are also ranked as follows, from lowest to highest:
When values of two different arithmetic or character types are combined
in an expression, the lower-ranked operand is converted to its
equivalent in the higher-ranked type. The result of an operation in
which conversion occurs is always of the higher-ranked type.
All conversions or assignments to values of type UNSIGNED or UNSIGNED64
are never checked for overflow. When combined with other unsigned
values, negative integer values are converted to large unsigned values
by the calculation of the modulus with respect to 2**32 or 2**64.
Conversions or assignments to values of type INTEGER or INTEGER64 can
overflow. Overflow will be detected at run time if overflow checking is
enabled. Overflow will occur if the value is outside the range -MAXINT
to MAXINT for converting to INTEGER, or outside the range -MAXINT64 to
MAXINT64 for converting to INTEGER64.
A special case of conversion can occur when you attempt to assign an expression of type VARYING OF CHAR STRING strings to a variable of type PACKED ARRAY OF CHAR or if you try to pass a string expression to a formal value parameter of type PACKED ARRAY OF CHAR. If the varying-length string has less than or exactly the same number of components as the packed array, the varying-length string is converted to a packed array of characters before the assignment is made and padded with blanks as necessary. If you attempt to perform this assignment with a varying-length string that has more components than the packed array, a run-time error occurs.
HP Pascal statements specify actions to be performed and appear in executable sections. This chapter discusses the following statements:
When coding, separate statements with a semicolon (;). The semicolon is
not syntactically part of a statement, so it is not included in the
syntax examples in this chapter.
5.1 Assignment Statement
The assignment statement uses an assignment operator (:=) to assign a value to a variable or to a function identifier. An assignment statement has the following form:
variable-access := expression |
variable-access
An identifier, array component, record component, pointer dereference, pointer-function dereference, or file buffer.expression
A run-time expression whose type is assignment compatible with the type of the variable. The value of the expression is the value assigned to the variable.
You cannot assign values to a variable of a record type with variants if you allocated this variable using the NEW procedure. You can assign values to a field of such a record variable.
Consider the following example:
VAR x : INTEGER; y, z : RECORD f1 : real; f2 : integer END; {In the executable section:} x := 1; {type of expression is same type as the variable} y := z; {variables are assignment compatible} Func_Return_Ptr_To_Integer( 3 )^ := 19; |
The BREAK statement immediately transfers control to the first statement past the end of the FOR, WHILE, or REPEAT statement that contains the BREAK statement. The BREAK statement appears as a single word:
BREAK |
BREAK is equivalent to a GOTO to a label placed just past the end of the closest FOR, WHILE, or REPEAT statement. The following example shows the usage of the BREAK statement:
REPEAT name := GetInput('Your name?'); IF ExitKeyPressed THEN BREAK; address := GetInput('Your address?'); IF ExitKeyPressed THEN BREAK; Person[Num].Name := name; Person[Num].Addr := address; Num := SUCC(Num); UNTIL Num > 50; |
In the example, a user-defined function GetInput interacts with the user and sets a global Boolean variable ExitKeyPressed if the user presses an Exit key. The BREAK statement exits the loop here, without storing data in the array.
Use caution when using the BREAK statement because future additions to the code can result in the BREAK statement leaving a different loop than was originally intended.
The CASE statement causes one of several statements to be executed. Execution depends on the value of an ordinal expression called the case selector. A CASE statement has the following form:
CASE case-selector OF [[{{case-label-list};...: statement};...]] [[ [[;]] OTHERWISE {statement};... ]] [[;]] END |
case-selector
An expression of an ordinal type.case-label-list
One or more case labels of the same ordinal type as the case selector, separated by commas. A case label can be a single constant expression, such as 1, or a range of expressions, such as 5..10.statement
Any statement to be executed depending on the values of both the case-selector and the case-label.
You can specify case labels in any order within the case-label-list. Each case label can appear only once within a given CASE statement.
At run time, the system evaluates the case selector expression and chooses which statement to execute. If the value of the case selector does not appear in the case-label-list, the system executes the statement in the OTHERWISE clause. If you omit the OTHERWISE clause, the value of the case selector must be equal to one of the case labels. If the value is not equal to a label, the CASE statement result is undefined.
Consider the following example:
CASE Age OF 1..4 : School := 'preschool'; {Subranges} 5..8 : School := 'elementary'; 9..13 : School := 'middle'; 14..18 : BEGIN School := 'high'; WRITELN( 'Difficult years!' ); END; {Compound statements} 19 : School := 'reform'; {Single ordinal value} OTHERWISE School := 'graduated'; {If 1 > Age > 18 ...} END; |
A compound statement groups a series of statements so that they can appear anywhere that language syntax calls for a single statement. A compound statement has the following form:
BEGIN {statement};... END |
statement
Any Pascal statement, including other compound statements.
The statements that make up the compound statement must be separated with semicolons (;), although the semicolon before the END delimiter is optional.
Consider the following example:
IF a < 10 THEN BEGIN {A compound statement} x := 10; y := 20; z := x + y; END {No semicolon in THEN clause before an ELSE} ELSE z := 29; {A single statement} |
The body of a FOR, WHILE, or REPEAT loop can include the CONTINUE statement. The CONTINUE statement is equivalent to a GOTO to a label placed at the end of the statements in the body of the FOR, WHILE, or REPEAT statement. The CONTINUE statement appears as a single word:
CONTINUE |
In a loop that processes a series of data items, you can use the
CONTINUE statement to indicate that the rest of the loop does not apply
to the current item, and that the program should continue to the next
statement.
Use caution when using the CONTINUE statement because future additions
to the code can result in the CONTINUE statement continuing with a
different loop than was originally intended.
Previous | Next | Contents | Index |