VSI Fortran provides the following language features to facilitate compatibility with other versions of Fortran: o The DEFINE FILE, ENCODE, DECODE, and FIND statements o An alternative syntax for the PARAMETER statement o The VIRTUAL statement o The AND, OR, XOR, IMAG, LSHIFT, and RSHIFT intrinsic functions o An alternative syntax for octal and hexadecimal constants o An alternative syntax for a record specifier o An alternative syntax for the DELETE statement o An alternative form for namelist external records o Record structures o VSI Fortran pointers These language features are particularly useful in transporting older Fortran programs to systems on Alpha processors. However, you should avoid using them in new programs on these systems, and in new programs for which portability to other Fortran 95 or Fortran 90 implementations is important.
1 – DEFINE_FILE
The DEFINE FILE statement establishes the size and structure of files with relative organization and associates them with a logical unit number. The DEFINE FILE statement is comparable to the OPEN statement (in situations where you can use the OPEN statement, it is the preferable mechanism for creating and opening files). Statement format: DEFINE FILE u(m, n, U, asv) [,u(m, n, U, asv)]... u Is an integer constant or variable that specifies the logical unit number. m Is an integer constant or variable that specifies the number of records in the file. n Is an integer constant or variable that specifies the length of each record in 16-bit words (2 bytes). U Specifies that the file is unformatted (binary); this is the only acceptable entry in this position. asv Is an integer variable, called the associated variable of the file. At the end of each direct access I/O operation, the record number of the next higher numbered record in the file is assigned to "asv"; "asv" must not be a dummy argument. The DEFINE FILE statement specifies that a file containing "m" fixed-length records, each composed of n 16-bit words, exists (or is to exist) on the specified logical unit. The records in the file are numbered sequentially from 1 through "m". A DEFINE FILE statement must be executed before the first direct access I/O statement referring to the specified file, even though the DEFINE FILE statement does not itself open the file. The file is actually opened when the first direct access I/O statement for the unit is executed. If this I/O statement is a WRITE statement, a new relative organization file is created. If it is a READ or FIND statement, an existing file is opened, unless the specified file does not exist. If a file does not exist, an error occurs.
2 – DELETE
In VSI Fortran, you can specify the following form of the DELETE statement when deleting records from a relative file: DELETE (u'r [,ERR=s] [,IOSTAT=ios]) u Is the number of the logical unit containing the record to be deleted. r Is the positional number of the record to be deleted. s Is the label of an executable statement that receives control if an error condition occurs. ios Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs. This form deletes the direct access record specified by r.
3 – ENCODE and DECODE
The ENCODE and DECODE statements transfer data between variables or arrays in internal storage. The ENCODE statement translates data from internal (binary) form to character form. Inversely, the DECODE statement translates data from character to internal form. These statements are comparable to using internal files in formatted sequential WRITE and READ statements, respectively. Statement format: ENCODE (c,f,b [,IOSTAT=ios] [,ERR=s]) [list] DECODE (c,f,b [,IOSTAT=ios] [,ERR=s]) [list] c Is an integer expression. In the ENCODE statement, "c" is the number of characters (in bytes) to be translated to character form. In the DECODE statement, "c" is the number of characters to be translated to internal form. f Is a format identifier. An error occurs if more than one record is specified. b Is a scalar or array reference. If b is an array reference, its elements are processed in the order of subscript progression. The data type of "b" determines the number of characters that ENCODE or DECODE can process. In the ENCODE statement, "b" receives the characters after translation to external form. If less than "c" characters are received, the remaining character positions are filled with blank characters. In the DECODE statement, "b" contains the characters to be translated to internal form. ios Is a scalar integer variable that is defined as a positive integer if an error occurs, and zero if no error occurs. s Is the label of an executable statement. list Is an I/O list. In the ENCODE statement, the "list" contains the data to be translated to character form. In the DECODE statement, the "list" receives the data after translation to internal form. The interaction between the format specifier and the I/O list is the same as for a formatted I/O statement.
4 – FIND
The FIND statement positions a direct access file at a particular record and sets the associated variable of the file to that record number. It is comparable to a direct access READ statement with no I/O list, and can open an existing file. No data transfer takes place. Statement format: FIND (u'r [,ERR=s] [,IOSTAT=ios]) FIND ([UNIT=]u, REC=r [,ERR=s] [,IOSTAT=ios]) u Is a logical unit number. It must refer to a relative organization file. r Is the direct access record number. It cannot be less than one or greater than the number of records defined for the file. s Is the label of the executable statement that receives control if an error occurs. ios Is an integer variable or integer array element that is defined as a positive integer if an error occurs, and as a zero if no error occurs.
5 – Intrinsic Functions
VSI Fortran allows certain intrinsic functions for compatibility with FORTRAN for RISC. The following list shows these functions and their equivalents: Function Equivalent Function -------- ------------------- AND IAND OR IOR XOR IEOR LSHIFT ISHFT with a positive second argument RSHIFT ISHFT with a negative second argument
6 – Namelist Record
You can use the following form for an external record: $group-name object = value [object = value]...$[END] group-name Is the name of the group containing the objects to be given values. The name must have been previously defined in a NAMELIST statement in the scoping unit. object Is the name (or subobject designator) of an entity defined in the NAMELIST declaration of the group name. The object name must not contain embedded blanks, but it can be preceded or followed by blanks. value Is a null value, a constant (or list of constants), a repetition of constants in the form r*c, or a repetition of null values in the form r*. If more than one object=value or more than one value is specified, they must be separated by value separators. A value separator is any number of blanks, or a comma or slash, preceded or followed by any number of blanks. Comments (beginning with ! only) can appear anywhere in namelist input. The comment extends to the end of the source line.
7 – Octal Hex Syntax
In VSI Fortran, you can use the following alternative syntax for octal and hexadecimal constants: Alternative Syntax Equivalent ------------------ ---------- Octal '0..7'O O'0..7' Hexadecimal '0..F'X Z'0..F' In the above syntax forms, you can use a quotation mark(") in place of an apostrophe (').
8 – PARAMETER
This statement is similar to the one discussed in Help topic: Statements PARAMETER; they both assign a symbolic name to a constant. However, this PARAMETER statement differs from the other one in the following two ways: its list is not bounded with parentheses; and the form of the constant, rather than implicit or explicit typing of the symbolic name, determines the data type of the variable. Statement format: PARAMETER p=c [,p=c]... p Is a symbolic name. c Is a constant, the symbolic name of a constant, or a compile-time constant expression.
9 – Record Specifier Syntax
In VSI Fortran, you can specify the following form for a record specifier: 'r r Is a numeric expression with a value that represents the position of the record to be accessed using direct access I/O. The value must be greater than or equal to 1, and less than or equal to the maximum number of records allowed in the file. If necessary, a record number is converted to integer data type before being used.
10 – Record Structures
A record is a named data entity, consisting of one or more fields, which you can use when you need to declare and operate on multi-field data structures in your programs. To create a record, you must have a structure declaration (to describe the fields in the record) and a RECORD statement to establish the record in memory.
10.1 – Examples
Structure APPOINTMENT: Structure /APPOINTMENT/ RECORD /DATE/ APP_DATE STRUCTURE /TIME/ APP_TIME (2) LOGICAL*1 HOUR, MINUTE END STRUCTURE CHARACTER*20 APP_MEMO (4) LOGICAL*1 APP_FLAG END STRUCTURE The following statement results in the creation of both a variable named NEXT_APP and a 10-element array named APP_list. Both the variable and each element of the array have the form of the structure APPOINTMENT. RECORD /APPOINTMENT/ NEXT_APP,APP_list(10) The following examples illustrate aggregate and scalar field references. Aggregate: NEXT_APP ! the record NEXT_APP NEXT_APP.APP_TIME(1) ! an array field of the variable ! NEXT_APP APP_list(3).APP_DATE ! a /DATE/ record, part of the record ! APP_list(3) in the array APP_list Scalar: NEXT_APP.APP_FLAG ! a LOGICAL field of the record ! NEXT_APP NEXT_APP.APP_MEMO(1)(1:1) ! The first character of APP_MEMO(1), ! a character*20 field of the record ! NEXT_APP
10.2 – Field References
Fields within a record may be accessed collectively or individually. Record references are either qualified or unqualified. A qualified reference refers to a typed data item and can be used wherever an ordinary variable is allowed. Type conversion rules are the same as for variables. Its form is: rname[.cfname...cfname].afname Unqualified references refer to a record structure or substructure and can be used (in most cases) like arrays, for example: rname[.cfname...cfname] rname Is the name used in the RECORD statement to identify a record. cfname Is a substructure field name within the record identified by record-name. afname Is the name of a typed data item within a structure declaration.
10.3 – Aggregate Reference
An aggregate reference resolves into a reference to a structured data item (a record structure or substructure). For example: Data Declarations: STRUCTURE /STRA/ INTEGER INTFLD, INTFLDARY (10) END STRUCTURE . . . STRUCTURE /STRB/ CHARACTER*20 CHARFLD INTEGER INTFLD, INTFLDARY (10) STRUCTURE STRUCFLD COMPLEX CPXFLD, CPXFLDARY (10) END STRUCTURE RECORD /STRA/ RECFLD, RECFLDARY (10) END STRUCTURE . . . RECORD /STRB/ REC, RECARY (10) Reference Examples: REC --- A record name RECARY(1) --- A record array reference REC.RECFLD --- A reference to a substructure REC.RECFLDARY(1) --- A reference to a substructure array element RECARY(1).RECFLD --- A reference to a substructure in a record array element RECARY(1).RECFLDARY(1) --- A reference to a substructure array element in a record array
11 – VIRTUAL
The VIRTUAL statement is included for compatibility with PDP-11 FORTRAN. It has the same form and effect as the DIMENSION statement (see Help Topic: Statements DIMENSION).
12 – HP Fortran POINTER
This POINTER statement (formerly the Compaq Fortran POINTER statement) is different from the Fortran 95/90 POINTER statement. This POINTER statement establishes pairs of variables and pointers, in which each pointer contains the address of its paired variable. Statement format: POINTER ((pointer,pointee) [,(pointer,pointee)]... pointer Is a variable whose value is used as the address of the pointee. pointee Is a variable, array, array declarator, record structure, record array, or record array specification. The following are rules and behavior for the "pointer" argument: o Two pointers can have the same value, so pointer aliasing is allowed. o When used directly, a pointer is treated like an integer variable. A pointer occupies two numeric storage units, so it is a 64-bit quantity (INTEGER*8). o A pointer cannot be a pointee. o A pointer cannot appear in an ASSIGN statement and cannot have the following attributes: ALLOCATABLE PARAMETER EXTERNAL POINTER INTRINSIC TARGET A pointer can appear in a DATA statement with integer literals only. o Integers can be converted to pointers, so you can point to absolute memory locations. o A pointer variable cannot be declared to have any other data type. o A pointer cannot be a function return value. o You can give values to pointers by doing the following: - Retrieve addresses by using the LOC intrinsic function (or %LOC built-in function) - Allocate storage for an object by using the MALLOC intrinsic function or LIB$GET_VM For example: Using %LOC: Using MALLOC: integer i(10) integer i(10) integer i1 (10) /10*10/ pointer (p,i) pointer (p,i) p = malloc (40) p = %loc (i1) i(2) = i(2) + 1 i(2) = i(2) + 1 Using LIB$GET_VM: INTEGER I(10) INTEGER LIB$GET_VM, STATUS POINTER (P,I) STATUS = LIB$GET_VM(P,40) IF (.NOT. STATUS) CALL EXIT(STATUS) I(2) = I(2) + 1 The value in a pointer is used as the pointee's base address. The following are rules and behavior for the "pointee" argument: o A pointee is not allocated any storage. References to a pointee look to the current contents of its associated pointer to find the pointee's base address. o A pointee can appear in only one POINTER statement. o A pointee array can have fixed, adjustable, or assumed dimensions. o A pointee cannot appear in a COMMON, DATA, EQUIVALENCE, or NAMELIST statement and cannot have the following attributes: ALLOCATABLE POINTER AUTOMATIC SAVE INTENT STATIC OPTIONAL TARGET PARAMETER o A pointee cannot be a dummy argument. o A pointee cannot be a function return value. o A pointee cannot be a record field or an array element. o A pointee cannot be zero-sized. o A pointee cannot be an automatic object. o A pointee cannot be the name of a generic interface block. o If a pointee is of derived type, it must be of sequence type.