HP 3000 Manuals

Predefined Routines [ HP Pascal/iX Reference Manual ] MPE/iX 5.0 Documentation


HP Pascal/iX Reference Manual

Predefined Routines 

The system programming extensions define the following additional
predefined procedures and functions.

Addressing and Pointers 

Addr.   

The predefined function addr allows the user to create references to
routines or data.

Usage 

     addr(variable) 
     addr(variable,offset) 
     addr(routine-name) 

Parameters 

variable              A variable or reference parameter, or a component
                      of an unpacked structured variable or reference
                      parameter.  You can take the address of a component
                      of a packed or crunched structure, if the component
                      begins on a byte-aligned boundary.

offset                A signed integer expression.

routine-name          The name of a procedure or function.

Description 

The predefined function addr returns a pointer value that is the address
of the argument.  The type of the pointer returned by addr is assignment
compatible with any pointer type.  Addr returns a short or long pointer 
depending on the context in which it is called, the context being the
type of the target variable of an assignment, the type of a formal
parameter, or the target type of a type coercion.

If the type coercion target type is not a pointer type, addr returns a
globalanypointer.

If an integer argument is supplied, the pointer returned is offset by the
integer number of bytes from the original variable whose address was
taken.

It is illegal to take the address of a formal value or READONLY
parameter.

It is illegal to take the address of a component of a PACKED or CRUNCHED
structure, if the component does not begin on a byte-aligned boundary.

If addr is called with the name of a procedure or function, the value
returned is a reference to that procedure or function.  The function
result type is assignment compatible with a PROCEDURE or FUNCTION type
whose parameter list is congruent with the parameter list of the routine
passed to addr.

If the name passed to addr cannot be resolved, the value NIL is returned.

Example 

     $STANDARD_LEVEL 'HP_MODCAL', TYPE_COERCION 'CONVERSION'$
     TYPE
        p_to_p_type = ^ p_to_p_type;

     VAR
        p_to_p : p_to_p_type;

     BEGIN
        p_to_p := addr( p_to_p );
        p_to_p := p_to_p_type( addr( p_to_p^, sizeof( p_to_p^ ) ) )^;
     END

The first assignment points the pointer p_to_p to itself.  The second
assignment takes the address of the data referenced by p_to_p (which is
itself), offset by the size of the data that p_to_p points to, treats the
value at that location as a pointer, and assigns the value pointed to by
that pointer back to p_to_p.

Addtopointer.   

The predefined function addtopointer allows the user to perform address
arithmetic with pointers.

Usage 

     addtopointer(pointer, delta) 

Parameters 

pointer               A pointer expression.

delta                 A signed integer expression whose range restriction
                      is implementation dependent.

Description 

Addtopointer returns a pointer value that points delta bytes away from
where the argument pointer pointed.  The type of the pointer returned by
addtopointer is the same as the type of the parameter pointer.

The results of an overflow are implementation dependent.

Example 

     TYPE
        intptr = ^integer;

     VAR
        ptr1: intptr;
        ptr2: intptr;
        i:    integer;

     BEGIN
        ptr2 := addtopointer (ptr1, i);
        ptr1 := addtopointer (ptr1, sizeof(integer));
     END

Buildpointer.   

The predefined function buildpointer allows the user to construct pointer
values.

Usage 

     buildpointer(space,offset) 

Parameters 

space                 A space identifier whose range restriction and
                      semantics are implementation dependent.

offset                A bit32 expression whose range restriction is
                      implementation dependent.

Description 

buildpointer returns a pointer of type globalanyptr whose value is the
address offset bytes into space.

Example 

     CONST
        Global_Known_Space = 4916;

     VAR
        Ptr1 : GlobalAnyPtr;
        Ptr2 : GlobalAnyPtr;
        SID  : Integer;
        Off  : Integer;

     BEGIN
     Ptr1 := BuildPointer (Global_Known_Space, 0);
     off := 4;
     Ptr2 := BuildPointer (SID, Off);
     END.

In the above example, the constant Global_Known_Space represents the
value of a known space.

The first use of buildpointer creates a pointer to the location with an
offset of zero in the space whose space id is Global_Known_Space.

The second use of buildpointer creates a pointer to the location four
bytes from the beginning of the space whose space has been assigned to
the variable SID.

Move Routines 

The system programming extensions provide the predefined procedures
move_l_to_r, move_r_to_l, fast_fill, and move_fast for generalized and
efficient data copying.

Move_L_to_R.   

The predefined procedure move_l_to_r provides a generalized array copying
mechanism.

Usage 

     move_l_to_r(count,source,source_index,target,target_index) 

Parameters 

count                 A positive integer expression whose value is the
                      number of elements to move.

source                The source array from where elements will be moved.

source_index          An integer expression whose value is the index into
                      the source array of the leftmost element to be
                      moved.  The value must be greater than or equal to
                      the index of the first element in the source array,
                      and less than or equal to the index of the last
                      element in the source array minus the move count.

target                The target array to where elements are moved.

target_index          An integer expression whose value is the index into
                      the target array to where the move begins.  The
                      value must be greater than or equal to the index of
                      the first element in the target array, and less
                      than or equal to the index of the last element in
                      the target array minus the move count.

Description 

The syntax of the procedure is identical to the syntax of the predefined
procedure strmove.

move_l_to_r moves elements from left to right.  In a left to right move,
the first element to be moved is the left-most (lowest indexed) element,
and the last element to be moved is the right-most (highest indexed)
element.

Even if the elements of the array to be moved are arrays themselves, the
array will be moved as a single item.

The following diagram shows the order of copying elements for
move_l_to_r.

[]
Figure 11-6. Copying Order for move_l_to_r Example TYPE Index_Type_1 = 0..20; Index_Type_2 = -3..17; Array_Type_1 = PACKED ARRAY [Index_Type_1] of SHORTINT; Array_Type_2 = ARRAY [Index_Type_2] of SHORTINT; VAR Array_1 = Array_Type_1; Array_2 = Array_Type_2; Index = Integer; BEGIN Move_L_to_R ( 5, Array_1, 3, Array_2, -3 ) { is equivalent to: } FOR Index := 0 TO 4 DO Array_2[Index-3] := Array_1[3+Index] { is equivalent to: } Array_2[-3] := Array_1[3] Array_2[-2] := Array_1[4] Array_2[-1] := Array_1[5] Array_2[0] := Array_1[6] Array_2[1] := Array_1[7] Move_R_to_L. The predefined procedure move_r_to_l provides a generalized array copying mechanism. Usage move_r_to_l(count,source,source_index,target,target_index) Parameters count A positive integer expression whose value is the number of elements to move. source The source array from where elements will be moved. source_index An integer expression whose value is the index into the source array from where the move will begin. The value must be greater than or equal to the index of the first element in the source array, and less than or equal to the index of the last element in the source array minus the move count. target The target array to where elements will be moved. target_index An integer expression whose value is the index into the target array to where the move will begin. The value must be greater than or equal to the index of the first element in the target array, and less than or equal to the index of the last element in the target array minus the move count. Description The syntax of the procedure is identical to the syntax of the predefined procedure strmove. move_r_to_l moves the elements from right to left. In a right to left move, the first element to be moved is the right-most (highest indexed) element, and the last element to be moved is the left-most (lowest indexed) element. Even if the elements of the array to be moved are arrays themselves, the array will be moved as a single item. The following diagram shows the order of copying for move_r_to_l.
[]
Figure 11-7. Copying Order for move_r_to_l Fast_Fill. The predefined procedure fast_fill provides a generalized method of initializing an array to a single 8 bit constant. Usage fast_fill (ptr,fill_char,count); Parameters ptr A pointer expression. fill_char A constant expression. count A positive integer expression that contains the number of bytes to fill with fill_char. Description fast_fill provides a fast alternative to for loops or assignment statements for initializing each element of a structure or an array to the same 8 bit value. fill_char and ptr should of compatible types. fill_char must also satisfy the following requirement: 0 <= ord(fill_char) <=255 Example $standard_level 'ext_modcal'$ program fill; var p100 : packed array [1..100] of char; var i1000 : packed array [1..1000] of integer; type heap_p = array [0..9] of integer; var p : ^heap_p; begin fast_fill(addr(p100),' ',sizeof(p100)); {fill a string array} {with spaces.} fast_fill(addr(i1000),0,sizeof(i1000)); {fill an integer array} {with 0s. } new(p); fast_fill(p,hex('ff'),sizeof(p^)); {fill an array in the } {heap to -1 (all bits on).} end. Move_Fast. The predefined procedure move_fast provides another generalized array copying mechanism. Usage move_fast(count,source,source_index,target,target_index) Parameters count A positive integer expression whose value is the number of elements to move. source The source array from where elements will be moved. source_index An integer expression whose value is the index into the source array of the leftmost element to be moved. The value must be greater than or equal to the index of the first element in the source array, and less than or equal to the index of the last element in the source array minus the move count. target The target array to where elements will be moved. target_index An integer expression whose value is the index into the target array to where the move begins. The value must be greater than or equal to the index of the first element in the target array, and less than or equal to the index of the last element in the target array minus the move count. Description The syntax of the procedure is also identical to the syntax of the predefined procedure, strmove. Move_fast provides an alternative to move_l_to_r or move_r_to_l for generating simpler and faster code when certain restrictions are met by the parameters. These restrictions are: * The source and target arrays must not overlap. * The source and the target must have elements with the same sizes. The size of each element must be greater than or equal to one byte. * If the source or the target array is packed, then the packing should be such that the wasted space per word; for example, space left between elements, should be the same for both arrays. * Both the source and the target arrays must be aligned on byte boundaries. Therefore, one of the following must be true: * All elements of the source and the target arrays must each be aligned on byte boundaries. * The leftmost source and target element must be aligned on byte boundaries, and the total size of the elements to be moved must be an integral multiple of one byte. Example { This example assumes certain packing which may not apply to your implementation. } TYPE IxType1 = 0..20; IxType2 = -3..17; Array1 = PACKED ARRAY [IxType1] of SHORTINT; Array2 = ARRAY [IxType2] of SHORTINT; Array3 = PACKED ARRAY [1..20] of -256..255; Array4 = CRUNCHED ARRAY [1..20] of -256..255; VAR Avar1 : Array1; Avar2 : Array2; Avar3 : Array3; Avar4 : Array4; Ix : Integer; BEGIN Move_Fast (5, AVar2, -3, AVar1, 3); { legal } FOR Ix := 0 TO 4 DO { equivalent FOR loop } AVar1[Ix+3] := AVar2[Ix-3]; Move_Fast (5, AVar3, 2, AVar4, 9); { illegal, because } { - AVar4 does not have byte-aligned elements } { - AVar4[9] starts on the 27th bit of a word } { (also not byte-aligned) } { besides, the number of bits to be moved is not a } { multiple of eight, anyway } Move_Fast (8, AVar4, 1, AVar4, 9) { legal, because } { - even though the individual elements of AVar4 are } { not byte-aligned, } { - AVar4[1] and AVar4[9] are each byte-aligned, and } { - The total size of the elements to be moved is an } { integral multiple of eight. } END; Error Handling Routines Escape. Usage escape(escape_value) Parameters escape_value An integer expression whose value will be available through the predefined function escapecode. Description Calling this predefined procedure indicates that a software error has been detected. Execution passes to the statement following the reserved word RECOVER of the first enclosing TRY-RECOVER statement. The parameter is evaluated before control is passed and, its value is available to the escapecode function. If escape is called with no surrounding TRY-RECOVER the program aborts. Example PROCEDURE proc; ... BEGIN ... IF ( {something has gone wrong} ) THEN ESCAPE( 0 ); ... END; ... BEGIN TRY ... proc; ... RECOVER WRITELN( 'fatal error. program terminates' ); END. Escapecode. The predefined function escapecode returns the last execution error number. Usage escapecode The function returns the value passed to the last implicit or explicit call to the predefined procedure escape. An explicit call to escape is a call that was made by the user. In this case escapecode returns the value of the escape code passed by the user. An implicit call to escape is a call that was made by a subsystem on the user's behalf or by the run-time library. In this case, escapecode returns a predefined value based on the type of error detected. See the HP Pascal/iX Programmer's Guide or the HP Pascal/HP-UX Programmer's Guide, depending on your implementation, for more details about the escape code values. If escape has never been called (implicitly or explicitly), the value returned by escapecode is undefined. If escapecode is called outside of the recover part of a TRY-RECOVER statement, the value returned is undefined. Example TRY ... { perform normal processing } RECOVER CASE escapecode OF ... { fix-up after an error that can be handled } OTHERWISE { send errors that cannot be handled } escape( escapecode ); END; The example above shows a possible control structure for trapping software errors. Within the recover section of the TRY-RECOVER statement, escapecode is used to recover information about the nature of the error that caused the trap to the recover section. Note the use of escapecode to pass certain errors on to a next enclosing TRY statement with an explicit call to escape. Parameter Mechanisms Haveextension. The predefined Boolean function haveextension determines if an extension parameter is accessible. Usage haveextension(parameter_name) Parameters parameter_name The name of a formal parameter in the current scope or a containing scope that is EXTENSIBLE. In a routine with extension parameters it may be necessary to check a formal parameter to ensure that an actual parameter was supplied, as a result of a parameter being passed by the user or being defaulted. The predefined function haveextension indicates, for a formal extension parameter name, whether that parameter exists and can be accessed. Example PROCEDURE proc_with_opt_parms( parm1 : type1; VAR parm2 : type2; parm3 : type3; VAR parm4 : type4 ) OPTION EXTENSIBLE 2; BEGIN ... IF (haveextension( parm4 )) THEN { implies that parm4 and parm3 have values } ... IF (haveextension( parm3 )) THEN { implies that parm3 has values } ... ... END; proc_with_opt_parms( var1, var2 ); ... proc_with_opt_parms( var1, var2, var3 ); In the previous example, haveextension is used to determine whether either or both of the EXTENSIBLE parameters are passed in the call to the procedure. Note that if parm4 is present, then by definition parm3 must also be present. See the description of routine OPTION EXTENSIBLE for more information. In the first call to proc_with_opt_parms, both calls to haveextension return false because none of the extension parameters are passed. In the second call, haveextension returns true for the third parameter only. PROCEDURE proc_with_opt_parms( parm1 : type1; VAR parm2 : type2; parm3 : type3; VAR parm4 : type4 ) OPTION EXTENSIBLE 2 DEFAULT_PARMS ( parm3 := 0, parm4 := nil ); BEGIN ... IF (haveextension( parm3 )) THEN ... IF (haveextension( parm4 )) THEN ... ... END; In the above example, haveextension( parm4 ) returns true only if the fourth parameter was actually supplied by the user. If it was not supplied, then the default value is ignored, and the parameter is not passed. Haveextension( parm3 ) is true if either of the following conditions are true: * The third or fourth parameters are supplied by the user. * The fourth parameter is supplied and the third is defaulted. Because the fourth parameter is EXTENSIBLE, and, therefore, by definition all parameters to its left must be passed, the default value for the third parameter is passed even though it was not supplied by the user. Haveoptvarparm. The predefined Boolean function haveoptvarparm determines if a default reference parameter is accessible. Usage haveoptvarparm(parameter_name) Parameters parameter_name The name of a default formal parameter of this or a containing scope. In a routine with default reference parameters, it may be necessary to check a formal parameter to ensure that its actual parameter was supplied by the user. The predefined function haveoptvarparm indicates for a formal reference parameter name whether the corresponding actual parameter was supplied by the user. The argument to haveoptvarparm must be the name of a formal parameter that: * Is a VAR, ANYVAR, or PROCEDURE/FUNCTION parameter. * Specifies a default value of NIL. See the routine OPTION DEFAULT_PARMS. Example PROCEDURE proc_with_opt_parms( VAR parm1 : type1; VAR parm2 : type2; VAR parm3 : type3 ) OPTION DEFAULT_PARMS( parm2 := nil, parm3 := nil ); BEGIN ... IF (haveoptvarparm( parm2 )) THEN { ok to use parm2 } ... IF (haveoptvarparm( parm3 )) THEN { ok to use parm3 } ... END; The procedure proc_with_opt_parms in the previous example has three VAR parameters, two of which are optional. Before using one of the two parameters within proc_with_opt_parms, a check is made to ensure that the parameters were supplied by the user. This check is accomplished by calling haveoptvarparm with the name of the parameter in question as its argument. Routine Mechanisms Call. The predefined procedure call invokes a procedure. Usage call(procedure_expression) call(procedure_expression,parameter ...) Parameters procedure_expression An expression whose value is a reference to a procedure whose formal parameter list is congruent with the parameters specified in the call. parameter An actual parameter that is compatible with the corresponding formal parameter of the PROCEDURE type of procedure_expression, that is passed to the invoked procedure. Description The predefined procedure call causes the indicated procedure to be called with the indicated parameters. If, during the execution of the procedure, call accesses any non-local variables, the variables accessed are the variables that were accessible at the time the reference to the procedure was made, when it was passed as an argument to the predefined function, addr. It is an error if the procedure expression has the value NIL or is undefined. It may not be possible to detect an undefined procedure reference. Example TYPE procedure_type = PROCEDURE( i : integer ); VAR int : integer; proc_var : procedure_type; PROCEDURE proc( int : integer ); BEGIN ... END; BEGIN proc( int ); proc_var := addr( proc ); call( proc_var, int ); END; In the above example, the two calls to the routine proc are effectively identical. Fcall. The predefined function fcall invokes a function. Usage fcall(function_expression) fcall( function_expression, parameter ... ) Parameters function_expression An expression whose value is a reference to a function whose formal parameter list is congruent with the parameters specified in the call. parameter An actual parameter that is compatible with the corresponding formal parameter of the FUNCTION type of function_expression, that is passed to the invoked function. The predefined function fcall causes the function referenced by the first FUNCTION variable parameter to be invoked with the supplied parameters. The type returned by fcall is the same as the type returned by the FUNCTION expression. See the description of call for more information. Size Functions Bitsizeof. The predefined function bitsizeof returns an integer representing the size of its argument in bits. Usage bitsizeof(variable) bitsizeof(record_variable,tag_value ...) bitsizeof(type_name) bitsizeof(record_type_name,tag_value ...) bitsizeof(struc_constant) bitsizeof(string_literal) Parameters variable The name of a variable. record_variable The name of a record variable with variants. tag_value The name of a case constant in the variant part of a record declaration. Case constants for nested variants may appear separated by commas. type_name The name of a type. record_type_name The name of a record type with variants. struc_constant The name of an array, record, set, or string constructor. string_literal A string literal. The bitsizeof function returns the number of bits needed to represent the data value part of a data item of the given type, or the actual allocated size of a variable. If the first parameter is a record type or variable with variants, a variant may be selected by specifying a case constant with the subsequent parameters. Otherwise, the size with the largest variant is used. bitsizeof(type) returns the minimum number of bits of storage for the type, and bitsizeof(variable) returns the number of bits of storage for the variable. For an ANYVAR parameter, two cases exist: If an additional hidden size parameter is passed along with the ANYVAR parameter, bitsizeof gives the number of bits in the number of bytes allocated to represent the actual parameter. If the hidden length parameter is not passed, bitsizeof gives the number of bits required to represent the formal parameter as a given type. Example TYPE int_type = integer; rec_type = RECORD int : integer; CASE flag: Boolean OF true: ( r : real ); false:( lr : longreal ); end; VAR int : int_type; rec : rec_type; size : integer; BEGIN ... size := bitsizeof( int ); size := bitsizeof( int_type ); size := bitsizeof( rec, true ); ... END;
NOTE bitsizeof is allowed in CONST declarations except for ANYVAR, VAR string, and conformant array parameters.
Sizeof. The predefined function sizeof returns an integer representing the size of its argument in bytes. Usage sizeof(variable) sizeof(record_variable,tag_value ...) sizeof(type_name) sizeof(record_type_name,tag_value ...) sizeof(struct_constant) sizeof(string_literal) Parameters variable The name of a variable. record_variable The name of a record variable with variants. tag_value The name of a case constant in the variant part of a record declaration. Case constants for nested variants may appear separated by commas. type_name The name of a type. record_type_name The name of a record type with variants. struct_constant The name of an array, record, set, or string constructor. string_literal A string literal. The predefined function sizeof returns the number of bytes of storage required to represent the data value part of a data item of the given type, or the actual allocated size of a variable. If the first parameter is a record type or variable with variants, a variant may be selected by specifying a case constant with the subsequent parameters. sizeof(type) returns the minimum number of bytes for the type. sizeof(variable) returns the number of bytes of storage for the variable. Otherwise, the size of the largest variant is returned. For a variable of a simple data type, the number returned by sizeof is equivalent to the storage required for the variable in the unpacked context. For example, if the variable is type char or Boolean, sizeof returns 1. For an ANYVAR parameter, two cases exist: If an additional hidden size parameter is passed along with the ANYVAR parameter, sizeof gives the actual number of bytes allocated to represent the actual parameter. If the hidden length parameter is not passed, sizeof gives the number of bytes required to represent the formal parameter. For conformant array parameters, the function sizeof is the actual size of the parameter. Example TYPE byte = 0..255; big_record = RECORD CASE Boolean OF true: ( arr : array [ 1..200 ] of byte ): false: ( f1 : integer; ... f99 : char ); BEGIN ... IF (sizeof(big_record,true) <> sizeof(big_record,false)) THEN BEGIN writeln ( 'variant size mismatch by', abs(sizeof(big_record,true)-sizeof(big_record,false)):1, 'bytes' ); HALT (1); END; ... END.
NOTE sizeof is allowed in CONST sections except for ANYVAR, VAR s, and conformant array parameters.


MPE/iX 5.0 Documentation