1 PASCAL The PASCAL command invokes the VSI Pascal compiler to compile one or more source programs. This command is described in detail in the "HP Pascal User Manual for OpenVMS Systems." Format of the PASCAL command line: PASCAL [[{/command-qualifier}...]] {file-spec[[/file-qualifier}...]]} {+ | ,}... The 'command-qualifier' is the name of a qualifier that indicates special processing to be performed by the compiler on all files listed. The 'file-spec' is the name of one of the following: o The input source file that contains the program or module to be compiled. If you separate multiple source file specifications with commas, the programs are compiled separately. If you separate the file specifications with plus signs, the files are concatenated and compiled as one program. The default file type for an input file is either .PAS (source file) or .TLB (text-library module). o The output file, used only with the /ANALYSIS_DATA, /ENVIRONMENT, /LIST, /OBJECT, or /DIAGNOSTICS qualifiers. The 'file-qualifier' is the name of a qualifier that indicates special processing to be performed by the compiler on the files to which the qualifier is attached. The default for compiler output files (object modules) is the .OBJ file type. 2 Parameters file-spec[,...] Specifies one or more VSI Pascal source files to be compiled. If you do not specify a file type for an input file, the default file type PAS is used. You can specify more than one input file. If you separate the file specifications with commas (,), each file is compiled separately. If you separate the file specifications with plus signs (+), the files are concatenated and compiled as a single input file, producing single object and listing files. If you specify SYS$INPUT as the file-spec parameter, the source program must follow the command in the input stream. 2 Qualifiers Indicate special actions to be performed by the compiler on the file(s) listed. Compiler qualifiers can apply to either the PASCAL command or to the specification of the file being compiled. When a qualifier follows the PASCAL command, it applies to all files listed. When a qualifier follows the file specification, it applies only to the file immediately preceding it. 2 /ALIGN=keyword D=platform-specific D=NATURAL (OpenVMS Alpha and OpenVMS I64) D=VAX (OpenVMS VAX) Controls the default alignment rules. Note that specifying the ALIGN attribute overrides any value that you previously specified for this qualifier. You can specify the following values for keyword: NATURAL Uses natural alignment when positioning record fields or array components. Natural alignment is when a record field or an array component is positioned on a boundary based on its size. For example, 32-bit integers are aligned on the nearest 32-bit boundary. Default on OpenVMS Alpha and OpenVMS I64 systems. In prior versions, the compiler spelled this keyword Alpha_AXP. It is still accepted for upward compatability. VAX Uses byte alignment when positioning record fields or array components. Record fields or array components larger than 32-bits are positioned on the nearest byte boundary. Default on OpenVMS VAX systems. On OpenVMS VAX systems, when you specify a value of NATURAL, automatic variables are aligned on longword boundaries instead of quadword boundaries. This occurs because the largest allowable alignment for the stack is longword alignment. 2 /ANALYSIS_DATA[=file-spec] D=/NOANALYSIS_DATA /NOANALYSIS_DATA Creates a file containing source code analysis information. If the file-spec is omitted, the default file name is the same as the source program; the default file type is ANA. The analysis file is reserved for use with VMS layered products, such as, but not limited to, the DEC Source Code Analyzer. 2 /ARCHITECTURE=keyword D=/ARCH=GENERIC OpenVMS Alpha only Specifies the lowest version of the Alpha architecture where this code will run, which can allow the compiler to generate more efficient code, with the tradeoff that code may not run on older systems, unlike the /OPTIMIZE=TUNE qualifier. All Alpha processors implement a core set of instructions and, in some cases, the following extensions: BWX (byte- and word- manipulation instructions), MAX (multimedia instructions), square root instruction, integer/floating-point register transfer instructions, additional instructions to identify extensions and processor groups, and bit count instructions. (The Alpha Architecture Reference Manual describes the extensions in detail.) The value specified on /ARCHITECTURE becomes the default value for the /OPTIMIZE=TUNE qualifier. The keyword specified with the /ARCHITECTURE qualifier determines which instructions the compiler can generate, and which coding rules it must follow: GENERIC Generate instructions that are appropriate for all Alpha processors. This option is the default, and is equivalent to /ARCH=EV4. HOST Generate instructions for the processor that the compiler is running on (for example, EV56 instructions on an EV56 processor, EV4 instructions on an EV4 processor, and so on). EV4 Generate instructions for the EV4 processor (21064, 20164A, 21066, and 21068 chips). Applications compiled with this option will not incur any emulation overhead on any Alpha processor. EV5 Generate instructions for the EV5 processor (some 21164 chips). (Note that the EV5 and EV56 processors both have the same chip number - 21164.) Applications compiled with this option will not incur any emulation overhead on any Alpha processor. EV56 Generate instructions for EV56 processors (some 21164 chips). This option permits the compiler to generate any EV4 instruction, plus any instructions contained in the BWX extension. Applications compiled with this option may incur emulation overhead on EV4 and EV5 processors. PCA56 Generate instructions for PCA56 processors (21164PC chips). This option permits the compiler to generate any EV4 instruction, plus any instructions contained in the BWX and MAX extensions. However, HP Pascal does not generate any of the instructions in the MAX (multimedia) extension to the Alpha architecture. Applications compiled with this option may incur emulation overhead on EV4 and EV5 processors. EV6 Generate instructions for EV6 processors (21264 chips). This option permits the compiler to generate any EV4 instruction, any instruction contained in the BWX and MAX extensions, plus any instructions added for the EV6 chip. These new instructions include a floating-point square root instruction (SQRT), integer/floating-point register transfer instructions, and additional instructions to identify extensions and processor groups. Applications compiled with this option may incur emulation overhead on EV4, EV5, EV56, and PCA56 processors. EV67 EV68 Generate instructions for EV67 and EV68 processors (21264A chips). This option permits the compiler to generate any EV6 instruction, plus the new bit count instructions (CTLZ, CTPOP, and CTTZ). However, HP Pascal does not currently generate any of the new bit count instructions and the EV67 and EV68 have identical instruction scheduling models so the EV67 and EV68 are essentially identical to the EV6. However, HP Pascal does not currently generate any of the new bit count instructions so EV67 is essentially identical to EV6. Applications compiled with this option may incur emulation overhead on EV4, EV5, EV56, and PCA56 processors. EV7 Generate instructions for the EV7 processor (21364 chip). This option permits the compiler to generate any EV67 instruction. There are no additional instructions available on the EV7 processor, but the compiler does have different instruction scheduling and prefetch rules for tuning code for the EV7. Applications compiled with this option may incur emulation overhead on EV4, EV5, EV56, and PCA56 processors. Beginning with OpenVMS Alpha V7.1 and continuing with subsequent versions, the operating system includes an instruction emulator. This capability allows any Alpha chip to execute and produce correct results from Alpha instructions - even if the some of the instructions are not implemented on the chip. Applications using emulated instructions will run correctly, but may incur significant emulation overhead at run time. Emulation for the BWX (byte and word) instructions was included in OpenVMS Alpha V7.1. Emulation for the floating-point square root, integer/floating-point register transfer, and bit count instructions will be included in a version of OpenVMS Alpha after V7.2. 2 /ASSUME=(option[,...]) D=/ASSUME=(ACCURACY,NOBYTE,NOLONG,NOREDUCED) OpenVMS Alpha and OpenVMS I64 only Directs the compiler to make additional assumptions about the behavior of the program. [NO]ACCURACY_SENSITIVE Specifies whether certain code transformations that affect floating-point operations are allowed. These changes may or may not affect the accuracy of the program's results. If you specify NOACCURACY_SENSITIVE, the compiler is free to reorder floating-point operations based on algebraic identities (inverses, associativity, and distribution). This allows the compiler to move additional floating-point operations outside of loops or reduce or remove floating-point operations totally, thereby improving performance. The default, ACCURACY_SENSITIVE, directs the compiler to avoid certain floating-point trasformations that might slighly affect the program's accuracy. [NO]BYTE_ALIGNED_POINTERS Specifies that the compiler should assume that all pointers point to memory that is only aligned on byte boundaries. Normally, the compiler assumes that pointer variables are initialized by a call to the NEW predeclared routine. The memory returned by NEW is at least quadword aligned. The compiler can take advantage of that alignment to generate better code. However, if the program initializes the pointers by some other means such as IADDRESS or typecasting with values that are not quadword aligned, then the generated code may produce alignment faults. While the alignment faults are silently handled by OpenVMS, the resulting performance loss might be significant. By specifying BYTE_ALIGNED_POINTERS, the compiler will generate slightly slower code to fetch the value. However, compared to the overhead of correcting the alignment faults, this additional overhead is very small. The preferred solution is to ensure that all pointers contain quadword aligned addresses and use the default of NOBYTE_ALIGNED_POINTERS. [NO]LONG_CALLS (OpenVMS I64 only) Specifies that the compiler should assume that calls to external routines require the Itanium 'brl.call' instruction instead of the shorter 'br.call' instruction. This option is only needed if the OpenVMS I64 linker cannot process a PCREL21B relocation for the default shorter instruction. [NO]REDUCED_RELOCATIONS (OpenVMS I64 only) Specifies that the compiler should generate additional instructions in order to minimize the number of address constants required. Normally, the compiler may ask the linker for many address constants. However, for large applications, the linker may not be able to produce all requested address constants. This option is only needed if the OpenVMS I64 linker overflows the limit of address constants for the image. /ASSUME=(ACCURACY_SENSITIVE, NOBYTE_ALIGNED_POINTERS, NOLONG_CALLS, NOREDUCED_RELOCATIONS) is enabled by default. You cannot specify /ASSUME without options. 2 /CDD_QUAD_TYPE=keyword D=/CDD_QUAD_TYPE=EMPTY_RECORD Controls the translation of quadword-sized and octaword-sized items when using the %DICTIONARY directive. You can specify the following values for keyword: EMPTY_RECORD Generates "[BYTE(8)] RECORD END" for signed and unsigned quadwords, and date/time values. Generates "[BYTE(16)] RECORD END" for signed and unsigned octawords. The empty record syntax is a method for leaving a hole in a data structure but not specify any datatype. Since empty records have no datatype, the compiler will fetch 0 bits when fetching from an empty record. Likewise, storing into an empty record will simply zero all the bytes. If you want to manipulate the actual memory contents, you must use an explicit typecast. INTEGER64 Generates INTEGER64 for signed quadwords and date/time values. Generates UNSIGNED64 for unsigned quadwords. Generates "[BYTE(16)] RECORD END" for signed and unsigned octawords. The INTEGER64 keyword is not allowed on OpenVMS VAX systems. RDML_QUAD_TYPE Generates "[BYTE(8),UNSAFE] RECORD L0:UNSIGNED; L1:INTEGER END" for quadwords. Generates "[BYTE(16),UNSAFE] RECORD L0,L1,L2:UNSIGNED; L3:INTEGER END" for octawords. These translations match the behavior of the RDML preprocessor. 2 /CHECK[=(option[,...])] D=/CHECK=(BOUNDS,DECLARATIONS) /NOCHECK Directs the compiler to generate code to perform run-time checks indicated by the following options: ALL Generates checking code for all options. NONE Suppresses all checking code. [NO]BOUNDS Verifies that an index expression is within the bounds of an array's index type, that character-string sizes are compatible, and that schemata are compatible. [NO]CASE_SELECTORS Verifies that the value of a case selector is contained in the corresponding case-label list. [NO]DECLARATIONS Verifies that schema definitions yield valid types and that uses of GOTO statements from one block to an enclosing block are correct. Also controls whether the ASSERT statement is processed. [NO]OVERFLOW Verifies that the result of an integer computation does not exceed machine representation. [NO]POINTERS Verifies that the value of a pointer variable is not NIL. [NO]SUBRANGE Verifies that values assigned to variables of subrange types are within the subrange; verifies that a set expression is assignment compatible with a set variable, and that MOD operates on positive numbers. The BOUNDS and DECLARATIONS are the only checking options enabled by default. The /CHECK qualifier without options is equivalent to /CHECK=ALL. The negation /NOCHECK is equivalent to /CHECK=NONE. The CHECK attribute in the source program or module overrides the /CHECK qualifier on the command line. 2 /CONSTANT=(name=value,...) D=none Creates a Pascal constant with the specified value. The name can be any legal VSI Pascal identifier. The value can be: an integer-literal; a negative-integer-literal; TRUE or FALSE; a double-quoted string literal, or a single-quoted string literal. For example, $ PASCAL/CONSTANT=(DEBUG=TRUE,MAXSIZE=10,OFFSET=-10,IDENT="V1.0") Inserting double-quote characters and inserting adjacent single-quote characters can be accomplished by using the \ escape character allowed in VSI Pascal double-quoted string constants. By using the \' single-quote escape character, you can insert adjacent single-quotes without DCL interpreting it as a symbol substition. $ PASCAL/CONSTANT=MSG="String with 2 \'\' single quote characters" Do not use \" to insert a double-quote character into the string literal as DCL will interpret the double-quote as the end of the string. Instead use the \x22 character literal (16#22 is the ASCII code for the double-quote character) to insert a double-quote character into the string literal without DCL interpreting it as the end of the string. $ PASCAL/CONSTANT=MSG="String with a \x22 double-quote character" The /CONSTANT qualifier is designed to be used with the VSI Pascal conditional compilation syntax, but the constants defined can be used in any Pascal expression just like normal constants defined in the CONST section. 2 /CROSS_REFERENCE D=/NOCROSS_REFERENCE /NOCROSS_REFERENCE Controls whether the compiler creates a cross-reference section within the listing file. Note that this qualifier is ignored if the /LIST qualifier is disabled. By default, /NOCROSS_REFERENCE is enabled. 2 /DEBUG[=(option[,...])] D=/DEBUG=TRACEBACK /NODEBUG Controls whether the compiler generates information for use by the VMS Debugger and the run-time error traceback mechanism. The available options are: ALL Specifies that the compiler should include symbol and traceback information in the object module. NONE Symbol and traceback information will not be included in the object module. [NO]SYMBOLS Specifies that the compiler should include in the object module symbol definitions for all identifiers in the compilation. [NO]TRACEBACK Specifies that the compiler should include in the object module traceback information permitting virtual addresses to be translated into source program routine names and compiler- generated line numbers. When you specify SYMBOLS without TRACEBACK, the table of compiler-generated line numbers is omitted from the debugger symbol file. You should consider using /NOOPTIMIZE when you are using /DEBUG. Allowing optimizations to occur might make debugging difficult and might obsucre some sections of the compilation unit that you want to debug. /DEBUG=TRACEBACK is enabled by default. The /DEBUG qualifier without options is equivalent to /DEBUG=ALL. The /NODEBUG qualifier is equivalent to /DEBUG=NONE. 2 /DESIGN[=(option[,...])] D=/NODESIGN /NODESIGN Directs the compiler to accept design phase placeholders and comments as valid program elements within a program. Placeholders are produced by you or the Language-Sensitive Editor (LSE); design comments are intended for use with the Source Code Analyzer (SCA). To use /DESIGN, you must be running LSE Version 3.0 or higher and SCA Version 2.0 or higher. The options are as follows: [NO]PLACEHOLDERS Directs the compiler to accept placeholders as valid program elements. [NO]COMMENTS Directs the compiler to recognize design comments (OpenVMS VAX). On OpenVMS VAX systems, the /DESIGN qualifier without options is equivalent to /DESIGN=(PLACEHOLDERS,COMMENTS). On OpenVMS Alpha and OpenVMS I64 systems, the /DESIGN qualifier without options is equivalent to /DESIGN=(PLACEHOLDERS). By default, /NODESIGN is enabled. 2 /DIAGNOSTICS[=file-spec] D=/NODIAGNOSTICS /NODIAGNOSTICS Creates a file containing compiler messages and diagnostic information. If the file-spec is omitted, the default file name is the same as the source program; the default file type is DIA. The diagnostics file is reserved for use with OpenVMS layered products, such as, but not limited to, the DEC Language-Sensitive Editor. 2 /ENUMERATION_SIZE=keyword D=platform-specific Controls the allocation of unpacked enumerated data types and Boolean data types, which are considered to be an enumerated type containing two elements. Note that specifying the ENUMERATION_SIZE attribute overrides any value you previously specified with this qulaifier. You can specify the following values for keyword: BYTE Allocates unpacked enumerated data types with fewer than 255 elements in a 8-bit byte. Otherwise, the enumerated type is allocated in a 16-bit word. Default on OpenVMS VAX systems. LONG Allocates all unpacked enumerated types in a 32-bit longword. Default on OpenVMS Alpha and OpenVMS I64 systems. 2 /ENVIRONMENT[=file-spec] D=Determined by attributes /NOENVIRONMENT Controls whether the compiler produces an environment file in which declarations and definitions made at the outermost level of a compilation unit are saved. If the file-spec is omitted, the default file name is the same as the source program; the default file type is .PEN, an abbreviation for "Pascal Environment." You can provide a different name for the environment file by including an OpenVMS file specification after the /ENVIRONMENT qualifier, as in /ENVIRONMENT=MASTER.PEN. The /ENVIRONMENT qualifier overrides the ENVIRONMENT attribute in the source program or module. You can use the /ENVIRONMENT qualifier to suppress the creation of an environment file dictated by an ENVIRONMENT attribute, or to change the name of an environment file specified by an ENVIRONMENT attribute. By default, the attributes in the source file or module determine whether an environment file is produced; however, if the /ENVIRONMENT qualifier is specified at compile time, an environment file will always be created. VSI Pascal accepts environment files that were created with previous versions of the compiler. However, programs compiled with previous versions of the compiler may not accept environment files created by the current version of VSI Pascal. 2 /ERROR_LIMIT[=n] D=/ERROR_LIMIT=30 /NOERROR_LIMIT Terminates compilation after the occurrence of a specified number of errors, excluding warnings and informational messages. If you specify /NOERROR_LIMIT, the compilation continues until 500 errors are detected. By default, /ERROR_LIMIT=30 is enabled. 2 /FLOAT=floattype D=platform-specific D=/FLOAT=D_FLOAT (OpenVMS VAX) D=/FLOAT=G_FLOAT (OpenVMS Alpha) D=/FLOAT=IEEE_FLOAT (OpenVMS I64) Selects the default format for REAL and DOUBLE data types. You must specify 'floattype' if you use the /FLOAT qualifier. You can specify the following float types: o D_FLOAT with corresponding [FLOAT(D_FLOAT)] attribute o G_FLOAT with corresponding [FLOAT(G_FLOAT)] attribute o IEEE_FLOAT with corresponding [FLOAT(IEEE_FLOAT)] attribute 2 /GRANULARITY=keyword D=/GRANULARITY=QUADWORD OpenVMS Alpha and OpenVMS I64 only Directs the compiler to generate additional code to preserve the indicated granularity. Granularity refers to the amount of storage that can be modified when updating a variable. You can specify the following values for keyword: o BYTE o LONGWORD o QUADWORD (default) To update a variable that is smaller than a longword, HP Pascal may issue multiple instructions to fetch the surrounding longword or quadword, update the memory inside to longword or quadword, and then write the longword or quadword back into memory. Using /GRANULARITY causes the compiler to avoid fetching surrounding memory at a potential increase in code size. If multiple processes are writing into memory that is contained in the same longword or quadword, you might incur inaccurate results unless /GRANULARITY=BYTE or some other synchronization mechanism is used. 2 /IDENT=ident_or_string D=none Specifies the module-ident to be used in object file or environment file as needed. This qualifier is equivalent to specifying an explicit [IDENT(quoted-string)] attribute in the source file. An explicit IDENT attribute in the source file will override this qualifier. /IDENT=ABC will yield an ident string of ABC. /IDENT="abc" will yield an ident string of abc. 2 /INCLUDE=(directory[,...]) D=none Specifies where to look for %INCLUDE files, environment files, or text libraries. The compiler applies the /INCLUDE information to the following Pascal constructs: %INCLUDE 'name' or %INCLUDE 'name.ext' [inherit('name')] or [inherit('name.ext')] %INCLUDE 'name(modname)' Directories are searched in the following order: 1. The current directory 2. The directories specified by /INCLUDE (if any) in the order in which they were specified 3. SYS$LIBRARY: 2 file-spec/LIBRARY D=none Specifies that a file is a text library file. The text library specification is required. The text library files in a list of source files must be concatenated by plus (+) signs. The default file type for a text library is .TLB. The %INCLUDE directive in a Pascal program allows you to extract modules from text libraries. 2 /LIST[=file-spec] D=/NOLIST (interactive) /NOLIST Controls whether the compiler creates a source listing file. If you omit the file specification, the compiler defaults to the name of the first source file, your default directory, and a file type of .LIS. The compiler does not produce a listing file in interactive mode unless you specify the /LIST qualifier. In batch mode, the compiler produces a listing file by default. To suppress the listing file, use the /NOLIST qualifier. In either mode, the listing file is not automatically printed. You must use the PRINT command to obtain a line printer copy of the listing file. 2 /MACHINE_CODE D=/NOMACHINE_CODE /NOMACHINE_CODE Produces a machine code section within the listing file. If you do not specify /LIST on the same command line, this qualifier is ignored. No machine code is generated if errors are detected in the source program or module. By default, MACHINE_CODE is disabled. 2 /MATH_LIBRARY=keyword D=/MATH_LIBRARY=ACCURATE OpenVMS Alpha only Determines whether the compiler uses alternate math library routines that boost performance, but sacrifice accuracy. You can specify the following values for keyword: o ACCURATE o FAST 2 /OBJECT[=file-spec] D=/OBJECT=input_file_name.OBJ /NOOBJECT Controls whether the compiler creates an object module. The compiler writes no representation of object code to the listing file, if it detects errors in the source code. The /NOOBJECT qualifier is useful when you want to test the source program for compilation errors. By default, /OBJECT is enabled; the compiler produces an object module with the same file name as the first source file and a file type of .OBJ. 2 /OPTIMIZE[=(option[,...])] D=platform-specific D=/OPTIMIZE=ALL (OpenVMS VAX) D=/OPT=(LEV=4,INLI=SPE,TUN=GEN,UNR=0) (OpenVMS Alpha) D=/OPT=(LEV=4,INLI=SPE,TUN=GEN,UNR=0) (OpenVMS I64) /NOOPTIMIZE Directs the compiler to optimize the code for the program or module being compiled. Optimization results in the production of more efficient object code. A single identifier or a list of identifiers may follow /OPTIMIZE; these identifiers are the names of options that tell the compiler which aspects of the compilation unit to optimize. The options are as follows: ALL (OpenVMS VAX only) Enables all /OPTIMIZE options. NONE Disables all /OPTIMIZE options. [NO]INLINE (OpenVMS VAX only) Enables inline expansion of user-defined routines. INLINE=keyword (OpenVMS Alpha and OpenVMS I64 only) Controls the inlining performed by the compiler. The keyword can be any of the following: ALL Inlines every call that it is possible to inline while still generating correct code. However, recursive routines will not cause an infinite loop at compile time. NONE Suppresses all inlining of routines. The is the default for optimization level 0. MANUAL Inlines only routines that specify the [OPTIMIZE(INLINE)] attribute. This is the default for optimization levels 1 through 3. SIZE Inlines all routines that specify the [OPTIMIZE(INLINE)] attribute plus any additional calls that the compiler determines will improve run-time performance without significantly increasing the size of the program. This option is only available with optimization levels 4 and 5. SPEED Inlines all routines that specify the [OPTIMIZE(INLINE)] attribute plus any additional calls that the compiler determines will improve run-time performance even where it may significantly increase the size of the program. This is the default for optimization levels 4 and 5 and is only available at those optimization levels. /OPTIMIZE=INLINE is equivalent to /OPTIMIZE=INLINE=SPEED. /OPTIMIZE=NOINLINE is equavalent to /OPTIMIZE=INLINE=NONE. LEVEL=n (OpenVMS Alpha and OpenVMS I64 only) Controls the level of optimization performed by the compiler. 0 Disable all optimizations. 1 Enable local optimizations and recognition of common subexpressions. 2 Enable all level 1 optimizations and some global optimizations that include code motion, strength reduction and test replacement, split lifetime analysis, and code scheduling. 3 Enable all level 2 optimizations and additional global optimizations that improve speed (at the cost of extra code size), such as integer multiplication and division expansion (using shifts), loop unrolling, and code replication to eliminate branches. 4 Enable all level 3 optimizations and, in addition, enable automatic inline expansion of procedures and functions. This is the default for /OPTIMIZE. 5 Enable all level 4 optimizations and, in addition, enables software pipelining using dependency analysis, vectorization of some loops on 8-bit and 16-bit data, and insertion of NOP instructions to improve scheduling. UNROLL=n (OpenVMS Alpha and OpenVMS I64 only) Controls loop unrolling done by the optimizer. UNROLL=n means to unroll loop bodies n times, where "n" is an integer in the range 0 through 16. The default of 0 means the optimizer will use its default unroll amount. TUNE=processor (OpenVMS Alpha only) Selects processor-specific instruction tuning for a specific implementation of the Alpha architecture. Tuning for a specific implementation can provide improvements in run-time performance. Regardless of the setting of the TUNE flag, the generated code will run correctly on all implementations of the Alpha architecture. Note that code tuned for a specific target may run more slowly on another target than generically-tuned code. The processor keyword can be one of the following: GENERIC Selects instruction tuning that is appropriate for all implementations of the Alpha architecture. This option is the default. HOST Selects instruction tuning that is appropriate for the machine on which the code is being compiled. EV4 Selects instruction tuning for the 21064, 21064A, 21066, and 21068 implementations of the Alpha architecture. EV5,EV56 Selects instruction tuning for the 21164 implementation of the Alpha architecture. EV6 Selects instruction tuning for the 21264 implementation of the Alpha architecture. EV67, EV68 Selects instruction tuning for the 21264A implementation of the Alpha architecture. The tuning for EV67 and EV68 is identical to the tuning for EV6. EV7 Selects instruction tuning for the 21364 implementation of the Alpha architecture. On OpenVMS VAX systems, the /OPTIMIZE qualifier without options is equivalent to /OPTIMIZE=ALL. The /NOOPTIMIZE qualifier is equivalent to /OPTIMIZE=NONE. On OpenVMS Alpha and OpenVMS I64 systems, the /OPTIMIZE qualifier is equivalent to /OPTIMIZE=(LEVEL=4, INLINE=SPEED, TUNE=GENERIC, UNROLL=0) and /NOOPTIMIZE is equivalent to /OPTIMIZE=(LEVEL=0, INLINE=NONE, TUNE=GENERIC, UNROLL=0). The OPTIMIZE and NOOPTIMIZE attributes in the source program override the /OPTIMIZE and /NOOPTIMIZE qualifiers on the command line. The /NOOPTIMIZE qualifier guarantees full evaluation of both operands of the AND and OR Boolean operators to aid in diagnosing all potential programming errors. If you wish to have short circuit evaluation even with the /NOOPTIMIZE qualifier, use the AND_THEN and OR_ELSE Boolean operators. 2 /PEN_CHECKING_STYLE=keyword D=/PEN_CHECKING_STYLE=COMPILATION_TIME Specifies the default checking style for the environment file created by this module if any. The following keywords are supported: COMPILATION_TIME Uses the compilation time of the environment file in all subsequent compile-time and link-time checking for users of this environment file. This is the default. IDENT_STRING Uses the [IDENT()] string of the environment file in all subsequent compile-time and link-time checking for users of this environment file. NONE Disables all compile-time and link-time checking for users of this environment file. 2 /PLATFORMS=(keyword[,...]) D=/NOPLATFORMS /NOPLATFORMS Displays informational messages about non-portable language features for the specified platform. The following platforms are supported: COMMON Displays informational messages for all platforms. OpenVMS_Alpha Displays informational messages for the OpenVMS Alpha platform. OpenVMS_VAX Displays informational messages for the OpenVMS VAX platform. OpenVMS_I64 Displays informational messages for the OpenVMS I64 platform. OSF1_AXP Displays informational messages for the Tru64 UNIX platform. 2 /PSECT_MODEL=[NO]MULTILANGUAGE D=/PSECT_MODEL=NOMULTILANGUAGE OpenVMS Alpha only Controls whether the compiler pads the size of overlaid PSECTs so as to ensure compatibility when the PSECT is shared by code created by other OpenVMS compilers. When a PSECT generated with a [COMMON] attribute is overlaid with a PSECT consisting of a C struct or a Fortran COMMON block, linker error messages may result due to the inconsistent sizes of the PSECTs, some languages pad the size of PSECTs while others do not. Compiling /PSECT_MODEL=MULTILANGUAGE ensures that VSI Pascal will follow a consistent PSECT size allocation scheme that works with C and Fortran PSECTs that are shared across multiple images. PSECTs shared in a single image do not have a problem. The corollary switch for the C compiler is /PSECT_MODEL=[NO]MULTILANGUAGE, the corollary switch for the Fortran compiler is /ALIGNMENT=COMMON=[NO]MULTILANGUAGE. The default behavior of VSI Pascal is /PSECT_MODEL=NOMULTILANGUAGE which is the behavior of previous releases of VSI Pascal and is sufficient for most applications. 2 /SHOW[=(option[,...])] D=platform-specific D=/SHOW=DICT,HEAD,INCL,INLI,SOUR,STAT,TABL (OpenVMS VAX) D=/SHOW=DICT,HEAD,INCL,SOUR,STAT (OpenVMS Alpha) D=/SHOW=DICT,HEAD,INCL,SOUR,STAT (OpenVMS I64) /NOSHOW Specifies a list of items to be included in the listing file. A single identifier or a list of identifiers enclosed in parentheses may follow /SHOW; these identifiers are the names of options that inform the compiler which type of information it should generate. The options are as follows: ALL Enables listing of all options. NONE Disables all /SHOW options. [NO]DICTIONARY Enables listing of %DICTIONARY records. [NO]HEADER Enables page headers. [NO]INCLUDE Enables listing of %INCLUDE files. [NO]INLINE Enables listing of inline summary (OpenVMS VAX) [NO]SOURCE Enables listing of VSI Pascal source code. [NO]STATISTICS Enables listing of compiler statistics. [NO]STRUCTURE_LAYOUT Enables listing of variable and type layout. [NO]TABLE_OF_CONTENTS Enables listing of table of contents only if the %TITLE or %SUBTITLE directive was specified in the source code (OpenVMS VAX) On OpenVMS VAX systems, the inline summary, enabled by /SHOW=INLINE, shows only the names of routines that were expanded inline in the compilation. If you want to know why routines were not expanded inline, you must specify an additional qualifier, either /OPTIMIZE=INLINE or /OPTIMIZE=ALL. Although /OPTIMIZE defaults to /OPTIMIZE=ALL, you must specify ALL to generate these reasons. The compiler ignores the /SHOW qualifier if you do not also specify the /LIST qualifier on the same command line. On OpenVMS VAX systems, the default for the /SHOW qualifier is /SHOW=(DICTIONARY, HEADER, INCLUDE, SOURCE, STATISTICS, TABLE_OF_CONTENTS). On OpenVMS Alpha and OpenVMS I64 systems, the default for the /SHOW qualifier is /SHOW=(DICTIONARY, HEADER, INCLUDE, SOURCE, STATISTICS). The negation /NOSHOW is equivalent to /SHOW=NONE. /SHOW is equivalent to /SHOW=ALL. 2 /STANDARD[=option] D=/NOSTANDARD /NOSTANDARD Causes the compiler to generate messages whenever the compilation unit uses VSI Pascal language extensions, which are nonstandard Pascal features. See the "HP Pascal Language Reference Manual" for more information on standard Pascal features and the Pascal standards (ANSI, ISO, and Extended). The options are as follows: NONE Disables standards checking. ANSI Uses the rules of the ANSI standard (ANSI/IEEE770X3.97-1989). ISO Uses the rules of the ISO standard (ISO 7185-1989). EXTENDED Uses the rules of the Extended standard (ISO 10206-1989). [NO]VALIDATION Performs validation for the given standard. The /STANDARD qualifier allows you to use only two options. The first option selects the standard to be used (ANSI, ISO, or EXTENDED). The second option determines whether the "strict" validation rules are to be enforced, [NO]VALIDATION. Therefore, /STANDARD=(ANSI, ISO, VALIDATION) is not allowed since both ANSI and ISO are specified. By default, these information-level messages are written to the error file SYS$ERROR. Note that using the VALIDATION option changes all nonstandard information-level messages to error-level messages. The /STANDARD qualifier without options is equivalent to /STANDARD=(ANSI, NOVALIDATION). /STANDARD=VALIDATION is equivalent to /STANDARD=(ANSI,VALIDATION). The negation /NOSTANDARD is equivalent to /STANDARD=NONE. 2 /SYNCHRONOUS_EXCEPTIONS D=/NOSYNCHRONOUS_EXCEPTIONS OpenVMS Alpha Only /NOSYNCHRONOUS_EXCEPTIONS Specifies that the compiler should generate code to insure that exceptions are reported as near as possible to the instruction that generated the exception. This can avoid confusion in tracing the source of an exception, however, there is a performance penalty for using this qualifier. 2 /TERMINAL[=(option[,...])] D=/NOTERMINAL /NOTERMINAL Specifies a list of items to be displayed on the terminal. A single identifier or a list of identifiers enclosed in parentheses may follow /TERMINAL. These identifiers are options that inform the compiler which type of information to display. The options are as follows: ALL Displays all options. NONE Disables all /TERMINAL options. [NO]FILE_NAME Displays file names on Pascal command line as they are being processed. [NO]ROUTINE_NAME Displays routine names as code is generated (OpenVMS VAX). [NO]STATISTICS Displays compiler statistics. By default, /NOTERMINAL is enabled. The /TERMINAL qualifier without options is equivalent to /TERMINAL=ALL. The negation /NOTERMINAL is equivalent to /TERMINAL=NONE. 2 /TIE D=/NOTIE OpenVMS Alpha and OpenVMS I64 only /NOTIE On OpenVMS Alpha, specifies that the generated code can call images translated by the VAX Environment Software Translator (VEST) utility, which translates OpenVMS VAX system images into functionally equivalent OpenVMS Alpha system images. The Translated Image Environment (TIE) allows translated images to execute as if on an OpenVMS VAX system. On OpenVMS I64, specifies that the generaated code can call images translated by the Alpha Environment Software Translated (AEST) utility, which translates OpenVMS Alpha images (which might have originally been OpenVMS VAX images that were subsequently translated to OpenVMS Alpha images) into functionally equivalent OpenVMS I64 system images. The Translated Image Environment (TIE) allows translated images to execute as if they were on their original OpenVMS system. 2 /USAGE[=(option[,...])] D=platform-specific D=/USAGE=(EMPTY,PACKED,UNSUP,UNINIT) (OpenVMS VAX) D=/USAGE=(EMPTY,PACKED,UNSUP,UNINIT,VOLATILE) (OpenVMS Alpha) D=/USAGE=(EMPTY,PACKED,UNSUP,UNINIT,VOLATILE) (OpenVMS I64) /NOUSAGE Directs the compiler to perform compile-time checks indicated by the chosen options. A single identifier or a list of identifiers enclosed in parentheses may follow /USAGE; these identifiers are options that tell the compiler which checks to perform. The options are as follows: ALL Enables checking of all options. NONE Disables all /USAGE options. [NO]EMPTY_RECORDS Checks for fetching records with no fields. Such fields are usually created by the %DICTIONARY directive for unsupported data types. [NO]NONGRNACC Detects code for which the compiler cannot generate requested granularity. [NO]PACKED_ACTUALS Checks for passing components of packed structures to VAR parameters. [NO]PERFORMANCE Checks for declarations and uses that will result in less than optimal performance. [NO]UNCERTAIN Checks for variables that may be uninitialized depending on program flow. [NO]UNINITIALIZED Checks for variables that are known to be uninitialized. [NO]UNSUPPORTED_CDD Checks for usage of CDD/Repository constructs that do not correspond to VSI Pascal data types. [NO]UNUSED Checks for variables that are declared but never referenced. [NO]UNCALLABLE Checks for routines that are declared but never referenced. (OpenVMS Alpha and OpenVMS I64 only) [NO]VOLATILE Checks for accesses to volatile data that cannot be protected as atomic operations. (OpenVMS Alpha and OpenVMS I64 only) See the "HP Pascal Language Reference Supplement for OpenVMS Systems" for a list of the types of variables that are not checked for uninitialization. By default on OpenVMS VAX systems, /USAGE=(EMPTY_RECORDS, PACKED_ACTUALS, UNSUPPORTED_CDD, UNINITIALIZED) is enabled. By default on OpenVMS Alpha and OpenVMS I64 systems, /USAGE=(EMPTY_RECORDS, NONGRNACC, PACKED_ACTUALS, UNSUPPORTED_CDD, UNINITIALIZED, VOLATILE) is enabled. /USAGE without options is equivalent to /USAGE =ALL. The negation /NOUSAGE is equivalent to /USAGE=NONE. 2 /VERSION D=/NOVERSION /NOVERSION Controls whether the compiler prints compiler and OpenVMS version information to SYS$OUTPUT and then returns to the operating system. No other command qualifiers or source files are processed when /VERSION is used. 2 /WARNINGS D=/WARNINGS /NOWARNINGS Controls whether the compiler generates diagnostic messages in response to warning-level or informational-level errors. A warning message indicates that the compiler has detected acceptable but unorthodox syntax or that it has performed some corrective action. In either case, unexpected results may occur. By default, /WARNING is enabled; use the /NOWARNINGS qualifier to suppress informational messages. 2 /ZERO_HEAP D=/ZERO_HEAP OpenVMS Alpha and OpenVMS I64 Only /NOZERO_HEAP Specifies that heap memory should be zeroed after allocation. By default, the Pascal RTL will return zero-filled memory for each call to the NEW builtin. Using the /NOZERO_HEAP qualifier can increase runtime performance. 2 Standards The VSI Pascal compiler accepts programs that conform to two standards and a subset of programs that comply with a third. Also, VSI Pascal provides features that are not part of any standard (called extensions). If you require portable code, do not use the VSI Pascal extensions. The unextended Pascal standards are as follows: o American National Standard ANSI/IEEE770X3.97-1989 (ANSI) o International Standard ISO 7185-1989 (ISO) VSI Pascal accepts programs that conform to either standard. The Extended Pascal standards are as follows: o American National Standard ANSI/IEEE 770X3.160-1989 (ANSI) o International Standard ISO 10206-1989 (ISO) The two Extended Pascal standards are identical in function. Extended Pascal is a superset of the unextended Pascal standards. Since VSI Pascal supports many -- but not all -- Extended Pascal standard features, it cannot compile all programs that comply with Extended Pascal. 2 Lexical_Elements A Pascal program is composed entirely of lexical elements. These elements are individual symbols, such as arithmetic operators, or they may be words that have special meanings in Pascal. The basic unit of any lexical element is a character, which must be a member of the ASCII character set. The words used in a Pascal program are combinations of alphabetic and numeric characters and occasionally a dollar sign ($), an underscore (_), or a percent sign (%). Some words are reserved for the names of executable statements, operations, and predefined data structures. Other words in a Pascal program are identifiers. Predeclared identifiers represent routines and data types provided by VSI Pascal. Other identifiers are created by the use to name programs, symbolic constants, variables, and any necessary program elements that have not already been named. 3 Character_Set VSI Pascal uses the extended American Standard Code for Information Interchange (ASCII) character set. The is extended ASCII character set contains 256 characters, which include the following: o Uppercase letters A through Z and lowercase letters a through z o Integers 0 through 9 o Special characters, such as the ampersand (&), question mark (?), and equal sign (=) o Nonprinting characters, such as the space, tab, line feed, carriage return, and form feed (use of these characters may improve the legibility of your programs) o Extended, unspecified characters with numeric codes from 128 to 255 The VSI Pascal compiler does not distinguish between uppercase and lowercase letters except when they appear inside apostrophes. For a complete listing of the ASCII character set, see the "HP Pascal Language Reference Manual." 3 Special_Symbols Special symbols represent delimiters, operators, and other syntactic elements. Some symbols are composed of more that one character; you cannot place a space between the characters of these special symbols. Examples of special symbols include the apostrophe ('), the assignment operator (:=) and the not equal sign (<>). 3 Reserved_Words Reserved words are words that are reserved for the names of statements, data types, directives, identifiers, specifiers, statements, and operators. You cannot redefine these identifiers. Examples of reserved words include AND, END, NOT, IF, and WHILE. Redefinable reserved words are used to name operators and identifiers. You can redeclare these words, but, if you do, the language feature becomes unavailable within the block in which you redeclare the word. The redefinable reserved words are AND_THEN, BREAK, CONTINUE, MODULE, OR_ELSE, OTHERWISE, REM, RETURN, VALUE, and VARYING. 3 Identifiers An identifier is a combination of letters, digits, dollar signs ($), and underscores (_) that conform to the following restrictions: o An identifier cannot start with a digit. o An identifier cannot contain any space or special symbols. o The first 31 characters must denote a unique name within the block in which the identifier is declared. An identifier longer than 31 characters generates a warning message; the compiler ignores characters beyond the thirty-first character. An identifier cannot start or end with an underscore, nor can two adjacent 4 Predeclared_Identifiers Predeclared identifiers name data types, symbolic constants and file variables, procedures, and functions. You can redefine a predeclared identifier, but, if you do, the original declaration becomes unavailable within the block in which you redeclared the word. Examples of predeclared identifiers include ADDRESS, COS, INTEGER, SQR and TRUE. 4 User_Defined_Identifiers User identifiers denote the names of programs, modules, symbolic constants, variables, procedures, functions, program sections, and user-defined types. They represent significant data structures, or values and actions that are not represented by reserved words, predeclared identifiers, or special symbols. 2 Data_Types Every piece of data that is created or manipulated by a VSI Pascal program has a data type. The data type determines the range of values, set of valid operations, and maximum storage allocation for each piece of data. 3 Ordinal The values in an ordinal type have a one-to-one correspondence with the set of positive integers. The values are ordered so that each has a unique ordinal value indicating its position in a list of values of that type. 4 INTEGER_Types VSI Pascal provides the INTEGER, INTEGER64 (not available on all systems) integer types. Also provided are the INTEGER8, INTEGER16, and INTEGER32 types, which are used as synonyms for subranges of the INTEGER type. The range of integer values consists of positive and negative integer values and of the value 0. The range boundaries depend on the architecture of the machine you are using. The largest possible value of the INTEGER type is represented by the predeclared constant MAXINT. The largest possible value of the INTEGER64 type is represented by the predeclared constant MAXINT64. 5 Standard_Int_Radix Extended digit notation allows you to express integer values in terms of a base number. VSI Pascal accepts numbers in bases 2 through 36. Syntax: [[ + | - ]] base-number#[[']]extended-digit[[']] The 'base-number' specifies the base of the number. The 'extended-digit' specifies the notation that is appropriate for the specified base. You can use extended-digit notation in the same way you use the conventional integer notation, with the following exceptions: o Extended-digit values cannot be used as labels. o Extended-digit notation for INTEGER objects cannot be used to express numbers outside the range of 0 to MAXINT. (To express signed numbers, place the unary plus operator (+) or the unary minus operator (-) in front of the notation; setting or clearing the high order bit does not set or clear the sign bit.) VSI Pascal allows the use of spaces and tabs to make the extended-digit notation easier to read. To use spaces and tabs, enclose the extended digit in single quotation marks (' '). The following are integer values in the extended-digit notation: 2#10000011 2#'1000 0011' 32#1J -16#'7FFF FFFF' 5 Nonstandard_Int_Radix VSI Pascal provides another extended integer convention for compatibility with previous versions of the language. This notation specifies an integer in either binary (base 2), octal (base 8), or hexadecimal (base 16) notation. Syntax: b [[ + | - ]] % o [[']]extended-digit[[']] x The 'b', 'o', or 'x' specifies binary, octal, or hexidecimal notation, respectively. The 'extended-digit' specifies the notation that is appropriate for the specified base. The following are extended integer values in the VSI Pascal specific notation: %b'1000 0011' %O'7712' -%x'DEC' 4 INTEGER_ADDRESS The INTEGER_ADDRESS predefined type is an integer that has the same underlying bit size as a pointer. On OpenVMS systems, INTEGER_ADDRESS is equivalent to INTEGER32. 4 INTEGER8 The INTEGER8 predefined type is equivalent to the following: Syntax: TYPE INTEGER8=[BYTE]-128..127;{ 16#80..16#7F} 4 INTEGER16 The INTEGER16 predefined type is equivalent to the following: Syntax: TYPE INTEGER16=[WORD]-32768..32767;{ 16#8000..16#7FFF } 4 INTEGER32 The INTEGER32 predefined type is equivalent to the following: Syntax: TYPE INTEGER32=[LONG]-2147483648..2147483647;{ 16#80000000..16#7FFFFFFF } 4 INTEGER64 The INTEGER64 predefined type is equivalent to the following: Syntax: INTEGER64=[QUAD]-9223372036854775808..9223372036854775807; { 16#8000000000000000..16#7FFFFFFFFFFFFFFF } The INTEGER64 predefined type is not available on OpenVMS VAX systems. 4 UNSIGNED_Types VSI Pascal provides the UNSIGNED and UNSIGNED64 types (not available on all systems). Also provided are the UNSIGNED8, UNSIGNED16, UNSIGNED32, CARDINAL, CARDINAL16, and CARDINAL32 types, which are used as synonyms for the UNSIGNED type. The range of unsigned values consists of nonnegative integer values. The largest possible value of the UNSIGNED data type is represented by the predefined constant MAXUNSIGNED. The largest value for the UNSIGNED64 data type is represented by the predefined constant MAXUNSIGNED64. The smallest possible value for the UNSIGNED data type is 0. 4 Standard_Uns_Radix Extended digit notation allows you to express unsigned integer values in terms of a base number. VSI Pascal accepts numbers in bases 2 through 36. Syntax: [[ + | - ]] base-number#[[']]extended-digit[[']] The 'base-number' specifies the base of the number. The 'extended-digit' specifies the notation that is appropriate for the specified base. You can use extended-digit notation in the same way you use the conventional unsigned integer notation, except that extended-digit values cannot be used as labels. VSI Pascal allows the use of spaces and tabs to make the extended-digit notation easier to read. To use spaces and tabs, enclose the extended digit in single quotation marks (' '). The following are unsigned integer values in the extended-digit notation: 16#80000000 16#'8000 0000' 16#'FFFF FFFF' 5 Nonstandard_Uns_Radix VSI Pascal provides another extended integer convention only for the sake of compatibility with previous versions of the language. This notation specifies an unsigned integer in either binary (base 2), octal (base 8), or hexadecimal (base 16) notation. Syntax: b [[ + | - ]] % o [[']]extended-digit[[']] x The 'b', 'o', or 'x' specifies binary, octal, or hexidecimal notation, respectively. The 'extended-digit' specifies the notation that is appropriate for the specified base. The following are unsigned integer values in the VSI Pascal specific notation: %x'8000 0000' %x'FFFF FFFF' 4 UNSIGNED8 The UNSIGNED8 data type is equivalent to the following: Syntax: TYPE UNSIGNED8 = [BYTE]UINT(0)..UINT(255); {0..16#FF} 4 UNSIGNED16 The UNSIGNED16 data type is equivalent to the following: Syntax: TYPE UNSIGNED16 = [WORD]UINT(0)..UINT(65535); {0..16#FFFF} 4 UNSIGNED32 The UNSIGNED32 data type is equivalent to the following: Syntax: TYPE UNSIGNED32 = [LONG]UINT(0)..UINT(4294967295); {0..16#FFFFFFFF} 4 UNSIGNED64 The UNSIGNED64 data type is equivalent to the following (OpenVMS Alpha and OpenVMS I64 systems only): Syntax: TYPE UNSIGNED64 = [QUAD]UINT(0)..UINT(18446744073709551615); {0..16#FFFFFFFFFFFFFFFF} 4 CHAR The CHAR data type consists of single character values from the ASCII character set. The largest possible value of the CHAR data type is the predefined constant MAXCHAR. To specify a character constant, enclose a printable ASCII character in single quotation marks. To specify the single-quote character, enclose two single quotation marks in single quotation marks. Each of the following is a valid character constant: 'A' '0' {This is character 0, not the integer value 0} '''' {The apostrophe character} '?' You can specify nonprinting characters, such as a control-character, by writing an empty string followed immediately by the ordinal value of the character in the ASCII character set, or by using the CHR function followed by the ordinal value of the character in the ASCII character set. For example, both of the following specify the bell control character: ''(7) CHR(7) 4 Boolean Boolean values are the result of testing relationships for truth or validity. The Boolean data type consists of the two predeclared identifiers FALSE and TRUE. The expression ORD(FALSE) results in the value 0; ORD(TRUE) returns the integer 1. 4 Enumerated An enumerated type is a user-defined ordered set of constant values specified by identifiers. Syntax: ({enumerated-identifier},...) The 'enumerated-identifier' is an identifier of the enumerated type being defined. VSI Pascal allows a maximum of 65,535 identifiers in an enumerated type. The values of an enumerated type begin with the value 0 and follow a left-to-right order. Subsequent identifiers have a value one greater than the identifier preceding it. Example: X : ( Spring, Summer, Fall, Winter ) In this enumerated type, Spring (value 0) and Summer (value 1) are less than Fall (value 2) because they precede Fall in the list of constant values. Winter (value 3) is greater than Fall because it follows Fall. An identifier in an enumerated type cannot be defined for any other purpose in the same block. 4 Subrange A subrange type is user-defined and specifies a limited portion of another ordinal type (called the base type). The subrange syntax indicates the lower and upper limits of the type. Syntax: lower-bound..upper-bound The 'lower-bound' is a constant expression or a formal discriminant identifier that establishes the lower limit of the subrange. The 'upper-bound' is a constant expression or a formal discriminant identifier that establishes the upper limit of the subrange. The value of the upper bound must be greater than or equal to the value of the lower bound. The base type can be any enumerated or predefined ordinal type. The values in the subrange type appear in the same order as they are in the base type. For instance, the result of the ORD function applied to a value of a subrange type is the ordinal value that is associated with the relative position of the value in the base type, not in the subrange type. You can use a subrange type anywhere in a program that its base type is legal. A value of a subrange type is converted to a value of its base type before it is used in an operation. All rules that govern the operations performed on an ordinal type pertain to subranges of that type. Example: TYPE Day = ( Mon, Tues, Wed, Thurs, Fri, Sat, Sun ); Weekday = Mon..Fri; {subrange of base type Day} Digit = '0'..'9'; {subrange of base type CHAR} Month = 1 .. 31; {subrange of base type INTEGER} On OpenVMS Alpha and OpenVMS I64 systems, you cannot specify the size of INTEGER and UNSIGNED subranges to be larger than 32-bits eventhough such values would be legal in executable statements. For example: TYPE S = 0..8796093022208; is not supported, while VAR S : INTEGER64; BEGIN S := 8796093022208 END is legal. 3 Real Real types specify real number values with different degrees of precision. 4 REAL The REAL type denotes single-precision real values. The REAL type is synonymous with the SINGLE type. The largest REAL value is denoted by MAXREAL. The smallest REAL value is denoted by MINREAL. EPSREAL denotes the result of subtracting 1.0 from the smallest REAL value that is greater than 1.0. Example: 2.4 2.3e2 {exponential notation} On OpenVMS VAX systems, REAL uses the F_Floating format. On OpenVMS Alpha systems, REAL can take one of two formats: F_Floating and IEEE S_Floating. To specify a format, use either the FLOAT attribute or the /FLOAT command line qualifier. The default format on OpenVMS VAX and OpenVMS Alpha systems is F_Floating. The default format on OpenVMS I64 systems is IEEE S_Floating. On OpenVMS I64 systems, F_Floating is supported by converting to/from IEEE S_Floating for all floating point operations. 4 SINGLE The SINGLE type denotes single-precision real values. The SINGLE type is synonymous with the REAL type. 4 F_FLOAT The F_FLOAT type denotes a F_Floating single-precision real value regardless of the setting of the FLOAT attribute or /FLOAT command line qualifier. 4 S_FLOAT The S_FLOAT type denotes a IEEE S_Floating single-precision real value regardless of the setting of the FLOAT attribute or /FLOAT command line qualifier. S_FLOAT is supported on OpenVMS Alpha and OpenVMS I64 systems only. 4 DOUBLE The DOUBLE type denotes double-precision real values. To indicate a double-precision real number, you must include a real number or an integer, the letter D (or d), and an integer exponent with its minus sign or optional plus sign. The largest DOUBLE value is denoted by MAXDOUBLE. The smallest DOUBLE value is denoted by MINDOUBLE. EPSDOUBLE denotes the result of subtracting 1.0d0 from the smallest DOUBLE value that is greater than 1.0d0. Example: 0D0 4.371528665D-3 On OpenVMS VAX systems, DOUBLE exists in two formats: D_Floating and G_Floating. On OpenVMS Alpha and OpenVMS I64 systems, DOUBLE exists in three formats: D_Floating, G_Floating, and IEEE T_Floating. To specify a format, you can use either the FLOAT attribute or the /FLOAT command line qualifier. On OpenVMS VAX systems, the default format is D_Floating. On OpenVMS Alpha systems, the default format is G_Floating. On OpenVMS I64, the default format is IEEE T_Floating. 4 D_FLOAT The D_FLOAT type denotes a D_Floating double-precision real value regardless of the setting of the FLOAT attribute or /FLOAT command line qualifier. 4 G_FLOAT The G_FLOAT type denotes a G_Floating double-precision real value regardless of the setting of the FLOAT attribute or /FLOAT command line qualifier. 4 T_FLOAT The T_FLOAT type denotes an IEEE T_Floating double-precision real value regardless of the setting of the FLOAT attribute or /FLOAT command line qualifier. T_FLOAT is supported only on OpenVMS Alpha and OpenVMS I64 Systems. 4 QUADRUPLE The QUADRUPLE type denotes quadruple-precision real values. To indicate a quadruple-precision real number, you must include a real number or an integer, the letter Q (or q), and an integer exponent with its minus sign or optional plus sign. The largest QUADRUPLE value is denoted by MAXQUADRUPLE. The smallest QUADRUPLE value is denoted by MINQUADRUPLE. EPSQUADRUPLE denotes the result of subtracting 1.0q0 from the smallest QUADRUPLE value that is greater than 1.0q0. Example: 0.11435Q3 3362Q2 0.11825q-4 On OpenVMS VAX systems, QUADRUPLE uses the H_Floating format. On OpenVMS Alpha and OpenVMS I64 systems, QUADRUPLE uses the X_Floating format. 4 H_FLOAT The H_FLOAT type denotes quadruple-precision real values. The H_FLOAT type is synonymous with the QUADRUPLE type on OpenVMS VAX systems. H_FLOAT is supported only on OpenVMS VAX Systems. 4 X_FLOAT The X_FLOAT type denotes quadruple-precision real values. The X_FLOAT type is synonymous with the QUADRUPLE type on OpenVMS Alpha and OpenVMS I64 systems. X_FLOAT is supported only on OpenVMS Alpha and OpenVMS I64 systems. 3 Pointer_Types A pointer type allows you to refer to a dynamic variable. Dynamic variables do not have lifetimes that are strictly related to the scope of a routine, module, or program; you can create and eliminate them at various times during program execution. Also, pointer types clearly define the type of an object, but you can create or eliminate objects during program execution. A pointer type has the following syntax: [[attribute-list]] ^ [[attribute-list]] base-type-identifier The 'attribute-list' is one or more optional identifiers that provide additional information about the base type. The 'base-type-identifier' is the type identifier of the dynamic variable to which the pointer type refers. (If the base type is an undiscriminated schema type, you need to supply actual discriminants when you call the NEW function.) Unlike other variables, dynamic variables do not have identifiers. Instead, you access them indirectly with pointers. Call the NEW procedure to allocate storage for dynamic variables. Call the DISPOSE procedure to deallocate this storage. Example: TYPE Reservation = RECORD Name : VARYING[30] OF CHAR; Class : ( standby, coach, first ); Flight_number : INTEGER; Next_passenger : ^Reservation; END; VAR Ticket : Reservation; In this example, 'Next_passenger' is a pointer to the record type 'Reservation'. The variable 'Ticket' is declared as type 'Reservation'. By manipulating the pointer variable, 'Ticket.Next_passenger', a linked list of records can be created using these definitions. By default, all pointer types are 32-bits wide. The NEW procedure uses LIB$GET_VM to allocate memory and LIB$FREE_VM to dispose of memory. On OpenVMS Alpha and OpenVMS I64, the [QUAD] attribute may be specified before the "^" character resulting in a 64-bit pointer. Using 64-bit pointers causes the NEW and DISPOSE procedures to LIB$GET_VM_64 to allocate memory and LIB$FREE_VM_64 to dispose of memory, respectively. 4 C_STR_T The C_STR_T predefined type is provided to interface with routines written in the C language using null-terminated strings. C_STR_T behaves like a normal pointer type in that you can assign NIL into it and the optional pointer checking code will check for dereferencing of a NIL pointer. The individual characters can be used by dereferencing the pointer and using an array index. No bounds checking will be performed even if array bounds checking is enabled. You cannot dereference a C_STR_T pointer without also indexing a single character. If you want to access an entire null-terminated string, see the PAS_STR function. 4 POINTER The POINTER predefined type is compatible with all pointer types. Variables or functions of type POINTER cannot be dereferenced or used with the NEW and DISPOSE procedures. In order to access the data, you must assign the pointer value into a variable of a particular pointer type or typecast the pointer to a particular pointer type. For example, you can use the POINTER type in the following ways: o To assign to or from any other type of pointer, including function result variables o To compare equality with any other type of pointer o To pass actual parameters of type POINTER to VAR and value parameters of any other type of pointer o To accept parameters of any other type of pointer with formal parameters of type POINTER 4 UNIV_PTR The predefined UNIV_PTR type is equivalent to: TYPE UNIV_PTR = POINTER; 3 Structured_Types The structured data types are user-defined and consist of components. Each component of a structured data type has its own data type; components can be any type. To express values of structured objects (arrays, records, and sets), you can use a list of values called constructors. Constructors are valid in the TYPE, CONST, VAR, and executable sections of your program. See the "HP Pascal Language Reference Manual" for examples of valid constructors and examples that show how to assign values to individual components of structured objects. 4 RECORD A record is a group of components (called fields) that can be of various data types. Each record component may contain one or more data items. Syntax: [[PACKED]] RECORD [[field-list]] END END If field-list is not specified, an empty record is created. The following is an example of a record type: RECORD Part : INTEGER; Received : RECORD Month : ( Jan, Feb, Mar, Apr, May, June, Jul, Aug, Sep, Oct, Nov, Dec ); Day : 1..31; Year : INTEGER; END; END; 5 Field_list The syntax for a field-list is as follows: { {{field-identifier},... : [[attribute-list]] type};... [[; variant-clause]] [[;]] variant-clause [[;]] } The 'field-identifier' is the name of a field. The 'attribute-list' is one or more optional identifiers that provide additional information about the field. The 'type' is the type of the corresponding field. A field can be of any type. The 'variant-clause' is the variant part of a record. A variant can contain different types or amounts of data at different times during program execution. The syntax for a variant clause is as follows: CASE { [[tag-identifier : ]] [[attribute-list]] tag-type-identifier}| discriminant-identifier } OF {{case-label-list} : (field-list)};... [[ [[;]] OTHERWISE (field-list)]] The 'tag-identifier' is the name of the tag field. The tag field is all of the elements between the reserved words CASE and OF. The 'attribute-list' is one or more optional identifiers that provide additional information about the variant. The 'tag-type-identifier' is the type identifier for the tag field. The 'discriminant-identifier' is the name of the formal discriminant of a schema type. The value of the corresponding actual discriminant selects the active variant. Once you select the variant by discrimination, you cannot change it again. The 'case-label-list' consists of one or more constant values of the tag field type either separated by commas. A case constant is either a single constant value (for example, 1) or a range of values (for example, 5..10). The 'field-list' consists of the names, types, and attributes of one or more fields. At the end of a field list, you can specify another variant clause. The field-list can be empty. 'OTHERWISE' is equivalent to a case label list that contains tag values (if any) not previously used in the record. The variant labeled with OTHERWISE is the current variant when the tag-identifier has a value that does not occur in any of the case label lists. The following is an example of a variant record: RECORD Part : 1..9999; CASE On_Order : Boolean OF TRUE : ( Order_Quantity : INTEGER; Price : REAL ); FALSE : ( Rec_Quantity : INTEGER; Cost : REAL ); END; In this example, the last two fields in the record vary depending on whether the part is on order. Records for which the value of the tag-identifier On_Order is TRUE will contain information about the current order; those for which it is FALSE, about the previous shipment. 5 Standard_record_constructor Record constructors are lists of values that you can use to initialize a record. Syntax: [[data-type]] [ [[{{component},... : component-value};... ]] [[{CASE [[tag-identifier :]] tag-value OF [{{component},... : component-value};... ] OTHERWISE ZERO [[;]] }]] ] The 'data_type' specifies the constructor's data type. If you use the constructor in the executable section or in the CONST section, a data-type identifier is required. Do not use a type identifier in initial-state specifiers elsewhere in the declaration section or in nested constructors. The 'component' specifies a field in the fixed-part of the record. Fields in the constructor do not have to appear in the same order as they do in the type definition. (If you choose, you can specify fields from the variant-part as long as the fields do not overlap.) The 'component-value' specifies a value same data type as the component. These values are compile-time values; if you use the constructor in the executable section, you can also use run-time values. 'CASE' provides a constructor for the variant portion of a record. If the record contains a variant, its constructor must be the last component in the constructor list. The 'tag-identifier' specifies the tag-identifier of the variant portion of the record. This is only required if the variant part contained a tag-identifier. The 'tag-value' determines which component list is applicable according to the variant portion of the record. 'OTHERWISE ZERO' sets all remaining components to their binary zero value. If you use OTHERWISE ZERO, it must be the last component in the constructor. When you specify constructors for a record that contains nested records, specify the type of the outermost record, but do not specify the type of the constructors for any nested records. The following are examples of record variables and possible standard record constructors: Example: TYPE Player_Rec = RECORD Wins : INTEGER; Losses : INTEGER; Percentage : REAL; END; VAR Player1 : Player_Rec VALUE [Wins: 18; Losses: 3; Percentage: 21/18] This record constructor appears in the variable declaration section, so the constructor type is optional, and compile-time values are required. Example: TYPE Player_Rec = RECORD Wins : INTEGER; Losses : INTEGER; Percentage : REAL; END; VAR Player1, Player2 : Player_Rec; {In the executable section} Player1 := Player_Rec[Wins:18; Losses: y; Percentage: Y+18/18]; This record constructor appears in the executable section, so the constructor type is required and run-time expressions are legal. 5 Nonstandard_record_constructor Syntax: [[data-type]] ([[{component-value},...]] [[tag-value, {component-value},...]]) The 'data_type' specifies the constructor's data type. If you use the constructor in the executable section, a data-type identifier is required. Do not use a type identifier in the VAR or VALUE sections, or for a nested constructor. The 'component-value' specifies a compile-time value of the same data type as the component. The compiler assigns the first value to the first record component, the second value to the second component, and so forth. The 'tag-value' specifies a value for the tag-identifier of a variant record component. The value that you specify as this component of the constructor determines the types and positions of the remaining component values (according to the variant portion of the type definition). The following is an example of a record variable and a possible nonstandard record constructor: Rec : RECORD Person : VARYING [30] OF CHAR; Address : RECORD Number : INTEGER; Street : VARYING [30] OF CHAR; Zip : 0..9999; END; Age : 0..150: END; ('Blaise Pascal', (1623, 'Pensees Street', 91662), 39) 4 ARRAY An array is a group of components (called elements) that all have the same data type and share a common identifier. An individual element of an array is referred to by an ordinal index (or subscript) that designates the element's position (or order) in the array. Syntax: [[PACKED]] ARRAY [ {[[attribute-list]] index-type},... ] OF [[attribute-list]] component-type The 'attribute-list' is one or more optional identifiers that provide information about the component type. The 'index-type' is the type of the index, which can be any ordinal type or discriminated ordinal schema type. The 'component-type' is the type of the array components, which can be any type. The components of an array can be another array. Example: ARRAY [0..4] OF INTEGER An array, whose components are themselves arrays, is called a multidimensional array. An array can have any number of dimensions, and each dimension can have a different index type. Example: ARRAY [0..4, 'A'..'D'] OF INTEGER This array is declared as two-dimensional. To refer to a component of this two-dimensional array, specify the variable name followed by the two bracketed index values. For example X[0,'A'] or X[0]['A'] specify the component in 'X' at position '0', 'A'. 5 Standard_array_constructor Array constructors are lists of values that you can use to specify an array value. Syntax: [[data-type]] [ [[{{{component | component-subrange}},... : component-value};... ]] [[OTHERWISE component-value [[;]] ]] ] The 'data-type' specifies the constructor's data type. If you use the constructor in the executable section or in the CONST section, a data-type identifier is required. Do not use a type identifier in initial-state specifiers elsewhere in the declaration section or in nested constructors. The 'component' or a 'component-subrange' specifies an element number to which the component-value applies. You can specify a subrange of components. Array elements do not have to be specified in order. The component must be a compile-time value or constant. The 'component-value' specifies the value to be assigned to the array elements in the component-list; the value must be of the same data type as the array-component type. This value is a compile-time value; if you use the constructor in the executable section, you can also use a run-time value. 'OTHERWISE' specifies a value to be assigned to all array elements that have not already been assigned values. When using array constructors, you must initialize all elements of the array; you cannot partially initialize the array. When you specify constructors for multidimensional arrays in the executable section, only specify the type of the outermost array. 6 Examples The following examples show possible constructors for the array Numbers: VAR Numbers : Count VALUE [1..3,5 : 1; 4,6 : 2; 7..9 : 3; 10 : 6]; {or, in the executable section} Numbers := Count[1..3,5 : 1; 4,6 : 2; 7..9 : 3; 10 : x+3]; These constructors give the first, second, third, and fifth component the value 1; the fourth and sixth component the value 2; and the seventh, eighth, and ninth components the value 3. The first constructor gives the tenth component the value 6; the second constructor, since it is in the executable section, can assign the run-time value x+3 to the tenth component. Numbers := Count[4,6 : 2; 7..9 : 3; 10 : x+3; OTHERWISE 1]; To specify constructor values for all remaining elements, you can use the OTHERWISE clause. 5 Nonstandard_array_constructor Syntax: [[data-type]] ([[{component-value},...]] [[REPEAT component-value]]) The 'data-type' specifies the constructor's data type. If you use the constructor in the executable section, a data-type identifier is required. Do not use a type identifier in the VAR or VALUE sections, or for a nested constructor. The 'component-value' specifies the compile-time value to be assigned to the corresponding array element. The compiler assigns the first value to the first element, the second value to the second element, and so forth. If you want to assign more than one value to more than one consecutive element, you can use the following syntax for a component-value: n OF value For instance, the following component value assigns the value of 15 to the first three components of an array: VAR Array1 : ARRAY [1..4] OF INTEGER; VALUE Array1 := ( 3 OF 15, 78 ); You cannot use the OF reserved word in a REPEAT clause. 'REPEAT' specifies a value to be assigned to all array elements that have not already been assigned values. The following is an example of an array variable and a possible array constructor: Result : ARRAY [1..2, 0..4] OF INTEGER; ((0,1,2,3,4),(5,6,7,8,9)) 4 SET A set is a collection of data items of the same ordinal type (called the base type). The SET type definition specifies the values that can be elements of a variable of that type. Syntax: [[PACKED]] SET OF [[attribute-list]] base-type The 'attribute-list' is one or more optional identifiers that provide additional information about the base type. The 'base-type' is the ordinal type identifier or type definition, or discriminated schema type, from which the set elements are selected. Note that real numbers cannot be elements of a set type. Example: SET OF CHAR Some possible set constructors for this set type are: ['A, 'E', 'I', 'O', 'U'] ['B'..'D', 'F'..'H', 'J'..'N', 'P'..'T', 'V'..'Z'] 5 Set_constructor Set constructors are lists of values that you can use to initialize a set. The syntax for set constructors is as follows: [[data-type]] [ [[{component-value},...]] ] The 'data-type' is the data type of the constructor. This identifier is optional when used in the CONST and executable sections; do not use this identifier in the TYPE and VAR sections or in nested constructors. The 'component-value' specifies values within the range of the defined data type. Component values can be subranges (..) to indicate consecutive values that appear in the set definition. These values are compile-time values; if you use the constructor in the executable section, you can also use run-time values. A set having no elements is called an empty set and is written as empty brackets ([]). A possible constructor for a variable of type SET OF 35..115 is the following: VAR Numbers : SET OF 35..115 VALUE [39, 67, 110..115]; {In the executable section, run-time expressions are legal:} Numbers := [39, 67, x+95, 110..115] The set constructors contain up to nine values: 39, 67, 95 or x+95, and integers between 110 and 115, inclusive. If the expression x+95 evaluates to an integer outside the range 35..115, then VSI Pascal includes no set element for that expression. 4 File A file is a sequence of components of the same type. The number of components is not fixed, so a file can be any length. The FILE type definition identifies the component type. Syntax: [[PACKED]] FILE OF [[attribute-list]] component-type The 'attribute-list' is one or more optional identifiers that provide additional information about the file components. The 'component-type' is the type of the file components which can be any ordinal, real, pointer, or structured type, except for the following: o A nonstatic type o A structured type with a nonstatic component o A file type o A structured type with a file component The arithmetic, relational, Boolean, and assignment operators cannot be used with file variables or structures containing file components. You cannot form constructors of file types. Example: FILE OF Boolean This example shows a file of Boolean values. If a variable, 'TRUTHS', is declared of this type, the file buffer is denoted by TRUTHS^. 5 Text_file VSI Pascal supplies a predefined file type called TEXT. Files of type TEXT are sequences of characters with special markers (end-of-line and end-of-file) added to the file. Although each character of a TEXT file is one file component, the end-of-line marker allows you to process the file line-by-line (using READLN, WRITELN, or EOLN), if you choose. The predeclared file variables INPUT and OUTPUT are files of type TEXT. They refer to the standard input and output files. The file type FILE OF CHAR differs from TEXT files in that FILE OF CHAR allows a single character to be the unit of transfer between a program and its associated I/O devices and that FILE OF CHAR files do not include special markers. FILE OF CHAR components are always read with the READ procedure, and must be read exclusively into variables of type CHAR, including CHAR components of structured variables. You cannot use the EOLN, READLN, and WRITELN routines on FILE OF CHAR files. 5 External_and_internal_files VSI Pascal makes distinctions between external and internal files. An internal file has a name in a directory and exists outside the context of a VSI Pascal program. An internal file has no name and is not retained after the program finishes execution. A file declared in the program heading is external by default. A file declared in a nested block is internal by default. To change the default for internal files, call the OPEN procedure or specify a filename on the EXTEND, RESET, or REWRITE procedures. The file is then considered external and is retained with the specified name after the program has finished execution. If you open an internal file with the EXTEND, RESET, or REWRITE procedure, the file remains an internal file. 3 Schema_Types A schema type is a user-defined construct that provides a template for a family of distinct data types. A schema type definition contains one or more formal discriminants that take the place of specific boundary values or variant-record selectors. By specifying boundary or selector values to a schema type, you form a valid data type; the provided boundary or selector values are called actual discriminants. Syntax: schema-identifier ({discriminant-identifier},... : [[attribute-list]] ordinal-type-name};...) = [[attribute-list]] type-denoter; The 'schema-identifier' is the name of the schema. The 'discriminant-identifier' is the name of a formal discriminant. The 'ordinal-type-name' is the type of the formal discriminant, which must be an ordinal type. The 'attribute-list' is one or more identifiers that provide additional information about the type-denoter. The 'type-denoter' is the type definition of the components of the schema. This must define a new record, array, set, or subrange type. Each schema type definition requires at least one discriminant identifier. A discriminant identifier does not have to be used in the type-denoter definition, but it is used to determine type compatibility. Discriminant identifiers can appear anywhere a value is required in this definition. TYPE Array_Template( Upper_Bound : INTEGER ) = ARRAY [1..Upper_Bound] OF INTEGER; The identifier Upper_Bound is the formal discriminant of the Array_Template schema. The Array_Template schema is not a complete description of data. It is not a valid data type until you provide an actual discriminant that designates the upper boundary of the array template. Actual discriminants can be compile-time or run-time expressions. This expression must be assignment compatible with the ordinal type specified for the formal discriminant. Also, the actual discriminant value must be inside the range specified for the formal discriminant; in the case of subranges, the upper value must be greater than or equal to the lower value. 4 Discriminated_Schema A discriminated schema is a schema type that has been provided actual discriminants. Discriminated schema can appear in either the TYPE or the VAR sections. For example: TYPE Array_Template( Upper_Bound : INTEGER ) = ARRAY [1..Upper_Bound] OF INTEGER; VAR Array_Type1 : Array_Template( 10 ); {ARRAY [1..10] OF INTEGER;} Array_Type2 : Array_Template( x ); {Upper boundary determined at run-time by variable or function call} In this example, the actual discriminants 10 and x complete the boundaries for Array_Template, forming two complete data types within the same schema type family. The type specifiers Array_Template( 10 ) and Array_Template( x ) are examples of discriminated schema. 4 Undiscriminated_Schema An undiscriminated schema is a schema type that has not been provided actual discriminants. You can use an undiscriminated schema as the domain type of a pointer or as the type of a formal parameter. For example: TYPE Ptr_to_Array_Template = ^Array_Template; Array_Template( Upper_Bound : INTEGER ) = ARRAY [1..Upper_Bound] OF INTEGER; The Array_Template schema is not a complete description of data. It is not a valid data type until you provide an actual discriminant that designates the upper boundary of the array template. 3 String_Types You can use schema and data types to store and to manipulate character strings. These types have the following order of complexity: 1. CHAR type 2. PACKED ARRAY OF CHAR user-defined types 3. VARYING OF CHAR user-defined types 4. STRING predefined schema Objects of the CHAR data type are character strings with a length of 1 and are lowest in the order of character string complexity. You can assign CHAR data to variables of the other string types. The PACKED ARRAY OF CHAR types allow you to specify fixed-length character strings. The VARYING OF CHAR types are a VSI Pascal extension that allows you to specify varying-length character strings with a constant maximum length. The STRING types provide a standard way for you to specify storage for varying-length character strings with a maximum length that can be specified at run time. To provide values for variables of these types, you should use a character-string constant (or an expression that evaluates to a character string) instead of an array constructor. Using array constructors with STRING and VARYING OF CHAR types generates an error; to use array constructors with PACKED ARRAY OF CHAR types, you must specify component values for every element in the array (otherwise, you generate an error). Example: VAR String1 : VARYING[10] OF CHAR VALUE 'abc'; 4 String The STRING predefined schema provides a way of declaring variable-length character strings. The compiler stores STRING data as though it were stored in the following schema definition: TYPE STRING ( Capacity : INTEGER ) = VARYING[Capacity] OF CHAR; The syntax of the discriminated schema is as follows: STRING ( Capacity ) The 'Capacity' is an integer in the range 1..65,535 that indicates the length of the longest possible string. To use the predefined STRING schema, you provide an upper bound as the actual discriminant. Consider the following example: VAR Short_String : STRING( 5 ); {Maximum length of 5 characters} Long_String : STRING( 100 ); {Maximum length of 100 characters} You can assign string constants to STRING variables from length 0 to the specified upper bound. The compiler allocates enough storage space to hold a string of the maximum length. A STRING variable with length 0 is the empty string (''). You can only use character-string constants (or expressions that evaluate to character strings) to assign values to variables of these types; you cannot use standard array constructors. You can access the CAPACITY predeclared identifier as you would a schema discriminant, and you can access the LENGTH and BODY predeclared identifiers as you would access fields of a record. The CAPACITY identifier allows you to access the actual discriminant of the STRING schema; the LENGTH identifier allows you to access the current length of the string object; and the BODY identifier contains the current string object, including whatever is in memory up to the capacity of the discriminated schema. 4 PACKED User-defined packed arrays of characters with specific lower and upper bounds provide a method of specifying fixed-length character strings. The string's lower bound must equal 1. The upper bound establishes the fixed length of the string. 5 Examples The following example shows a declaration of a character string variable of twenty characters: VAR My_String : PACKED ARRAY[1..20] OF CHAR; Note that if the upper bound of the array exceeds 65,535, if the PACKED reserved word is not used, or if the array's components are not byte-sized characters, the compiler does not treat the array as a character string. 4 Varying_of_char The VARYING OF CHAR user-defined types are a VSI Pascal extension that provides a way of declaring variable-length character strings with a compile-time maximum length. If you require portable code, use the STRING predefined schema types to specify variable-length character strings. Syntax: VARYING [upper-bound] OF [[attribute-list]] CHAR The 'upper-bound' is an integer in the range from 1 through 65,535 that indicates the length of the longest possible string. The 'attribute-list' is one or more optional identifiers that provide additional information about the VARYING OF CHAR string components. To assign values to fixed-length character strings, you can use a character-string constant (or an expression that evaluates to a character string). When assigning into fixed-length strings, the compiler adds blanks to extend a string shorter than the maximum characters declared. If you specify a string longer than the maximum characters declared, an error occurs. You can also use an array constructor as long as you specify characters for every component of the array as specified in the declaration. Although a VARYING OF CHAR is a distinct type, it possesses some of the properties of both record and array types. A VARYING string is actually stored as though it were a record with two fields, LENGTH and BODY (which are predeclared identifiers in VSI Pascal). The LENGTH field contains the length of the current character string; the BODY field contains the string. Either field can be accessed in the same way record fields are accessed (VARY.LENGTH, VARY.BODY). Example: VARYING [25] OF CHAR This VARYING OF CHAR type could have the following values: 'Wolfgang Amadeus Mozart' 'Bach' 3 Misc_Types VSI Pascal provides a predefined data types that can be used with specific routines. 4 TIMESTAMP The TIMESTAMP predefined type is used in conjunction with the GETTIMESTAMP procedure or with the DATE or TIME functions. GETTIMESTAMP initializes a variable of type TIMESTAMP; DATE and TIME function results are of type TIMESTAMP. 2 Expressions VSI Pascal expressions consist of one or more operands that result in a single value. If the expression contains more than one operand, the operands are separated by operators. Operands include numbers, strings, constants, variables, and function designators. Operators include arithmetic, relational, logical, string, set, and typecase operators. VSI Pascal recognizes two forms of expressions: constant expressions and run-time expressions. Constant expressions result in a value at the time you compile your program. These expressions can include constants, constant identifiers, operators, and some predeclared functions. Run-time expressions can only result in a value at the time you execute your program. These expressions can include variables, predeclared functions, user-declared functions, and everything that a constant expression cannot contain. See the "HP Pascal Language Reference Manual" for restrictions on constant expressions and information on evaluation of expressions in statements. Syntax: simple-expression [[ {<> | < | <= | = | > | >= | IN} simple-expression ]] 3 simple_expression The syntax for a simple expression is: {+ | -} term [[ {{+ | - | OR | OR_ELSE} term}...]] 3 term The syntax for a term is: primary [[ {{* | / | DIV | REM | MOD | AND | AND_THEN} primary}... ]] 3 primary The syntax for a primary is: factor [[ {** factor}... ]] 3 factor A factor in a run-time expression can be any of the following: array-type-identifier array-constructor constant-identifier constructor of schema type or of types containing schema components (expression) [[ :: type-identifier ]] function-identifier [[ actual-parameter-list ]] NOT factor numeric-constant real-constant record-type-identifier record-constructor schema discriminant [[ set-type-identifier ]] set-constructor string-constant variable A factor in a compile-time expression cannot include the following: call to user-defined functions call to EOF and EOLN predeclared functions constructor of schema type or of types containing schema components schema discriminant variable 3 Examples 1. VARIABLES A variable can be in an expression: foo -'foo' is a predefined variable of some type new[1] -the first position of array 'new' rec.field -a field of record 'rec' pointer^ -the pointer variable of the pointer type 'pointer' cast::INTEGER -the variable 'cast' type cast as an integer 2. STRING CONSTANTS A string constant can have the following forms: name-string or {name-string ({constant-expression},...)}... [[name-string]] The 'name-string' is a quoted sequence of spaces, tabs, and any other printing characters. An apostrophe is expressed as ''. For example, 'hello there' is a name-string. The '{name-string ({constant-expressions},...)}... [[name-string]]' is a sequence that makes up a name-string. For example, when the list ('bell ' (7) 'character') is output to the terminal, you will see the string 'bell character' and the bell will ring (as indicated by the constant expression '(7)'). Additionally, VSI Pascal allows string constants to be formed with double quotes. Inside of these double-quoted string constants, VSI Pascal is able to recognize special characters that are specified with a backslash, as follows: o "\a" (Alert (bell) character) o "\b" (Backspace character) o "\f" (Forfeed character) o "\n" (New line or line feed character) o "\r" (Carriage return character) o "\t" (Horizontal tab character) o "\v" (Vertical tab character) o "\\" (Backslash character) o "\"" (Double quotation mark character) o "\'" (Single quotation mark character) o "\nnn (Character whose value is nnn, where nn is an octal number from 00 to 377.) o "\xnn" (Character whose value if nn, where nn is a hexadecimal number from 00 to FF.) 3. CONSTANT IDENTIFIER A constant identifier is an identifier of a type that can be determined at compile time. The following are examples of constant identifiers: CONST Foo = 3; Exp = 8 * 9; Func = MAX( 3, 2, 4 ); 4. EXPRESSION IDENTIFIER An expression identifier is an expression in parentheses optionally followed by a type cast structure. Examples are: ( a + b ) - 'a' and 'b' are predeclared variable identifiers ( Foo ) :: INTEGER - expression 'Foo' type cast as an integer 5. FUNCTION IDENTIFIER A function identifier is the name of a predeclared function. If the function has formal parameters, the function identifier must be followed by one actual parameter for each formal parameter listed. For example: FUNCTION Foo ( VAR n : INTEGER; start : Boolean ) : REAL; A call to function 'Foo' could look like the following: Foo( bar, TRUE ) Function 'Foo' returns a REAL value. 3 Operators Pascal provides several classes of operators. You can form complex expressions by using operators to combine constants, constant identifiers, variables, and function designators. 4 Arithmetic_Operators An arithmetic operator usually provides a formula for calculating a value. To perform arithmetic operations, numeric operands are combined with one or more of the arithmetic operators. Arithmetic Operators: operator | example | result -------------------------------------------- + A + B Sum of A and B - A - B B subtracted from A * A * B Product of A and B ** A ** B A raised to the power of B / A / B A divided by B DIV A DIV B Result of A divided by B, truncated toward zero REM A REM B Remainder of A divided by B MOD A MOD B Modulus of A with respect to B 4 Relational_Operators A relational operator tests the relationship between two ordinal, real, DOUBLE, or QUADRUPLE expressions and returns a Boolean value. If the relationship holds, the result is TRUE; otherwise the result is FALSE. You can also apply some of the relational operators to string operands and to set operators. Relational Operators: operator | example | result -------------------------------------------- = A = B TRUE if A is equal to B <> A <> B TRUE if A is not equal to B < A < B TRUE if A is less than B <= A <= B TRUE if A is less than or equal to B > A > B TRUE if A is greater than B >= A >= B TRUE if A is greater than or equal to B 4 Logical_Operators A logical operator evaluates one or more Boolean expressions and returns a Boolean value. Logical Operators: operator | example | result ------------------------------------------------- AND A AND B TRUE if both A and B are TRUE OR A OR B TRUE if either A or B is TRUE, or if both are TRUE NOT NOT A TRUE if A is FALSE, and FALSE if A is TRUE AND_THEN A AND_THEN B TRUE if both A and B are TRUE (forces left-to-right evaluation order with short-circuiting) OR_ELSE A OR_ELSE B TRUE if either A or B is TRUE, or if both are TRUE (forces left-to-right evaluation order with short-circuiting) 4 String_Operators A string operator concatenates, compares character-string expressions, or tests string inclusion in another string. The result is either a string or a Boolean value. String Operators: operator | example | result -------------------------------------------- + A + B String that is the concatenation of strings = A = B TRUE if strings A and B have equal ASCII values <> A <> B TRUE if strings A and B have unequal ASCII values < A < B TRUE if the ASCII value of string A is less than that of string B <= A <= B TRUE if the ASCII value of string A is less than or equal to that of string B > A > B TRUE if the ASCII value of string A is greater than that of string B >= A >= B TRUE if the ASCII value of string A is greater than or equal to that of string B IN A IN B TRUE if the string A is contained in string B (This is identical to INDEX(B,A) <> 0) NOT IN A NOT IN B TRUE if the string A is not contained in string B (This is identical to INDEX(B,A) = 0) 4 Set_Operators 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. 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 in 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 4 Type_Cast_Operator The type cast operator changes the context in which a variable or an expression of a certain data type can be used. The actual representation of the object being cast is not altered by the type cast operator. VSI Pascal overrides the type only for the duration of one operation. It has one of the following forms: variable-identifier :: type-identifier (expression) :: type-identifier The type cast operator (::) separates the name of the variable or an expression in parentheses from its target type, the type to which it is being cast. 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; The record type 'F_Float' illustrates the layout of an F_floating real number. The real variable 'A' is cast as a record of this type, allowing access to the fields containing the mantissa, exponent, sign, and fraction of 'A'. Adding 1 to the field containing the exponent would give the same result as multiplying 'A' by 2.0. 2 Declaration_Section The declaration section contains declarations or definitions of constants, labels, user-defined data types, variables, and user-defined functions and procedures. In addition, only modules can contain initialization and finalization sections. Each appears in a subsection introduced by a VSI Pascal reserved word. These sections appear after the header and before the executable section (if any). The TO BEGIN DO and TO END DO sections can appear only in modules and can appear only once within a module. The remaining sections can appear in programs, modules, functions, or procedures; they can appear more than once and in any order in a single declaration section. If you use one kind of section more than once in a declaration section, be sure to declare types, variables, and constants before you use them in subsequent sections. If you want to apply the HIDDEN attribute to all of the data in a declaration section, place the HIDDEN attribute immediately preceding the section header, as follows: [HIDDEN] CONST Pi = 3.14 . . . 3 Label_Declaration A label is a tag that makes an executable statement accessible to a GOTO statement. Syntax: LABEL {label},...; The 'label' is a decimal integer between 0 and MAXINT or a symbolic name. When declaring several labels, you can specify them in any order. Example: LABEL 0, 6656, 778, 4352; 3 Const_Declaration A CONST section defines symbolic constants by associating identifiers with compile-time expressions. Syntax: CONST {constant-identifier = constant-expression};... The 'constant-identifier' is the identifier of the symbolic constant being defined. The 'constant-expression' is any legal compile-time expression. The VSI Pascal compiler must be able to evaluate all of the components of a compile-time expression when it compiles the program. Example: CONST Year = 1981; Month = 'January' Almost_Pi = 22.0/7.0; Lie = FALSE; Untruth = Lie; This CONST section defines five symbolic constants. 'Year' is declared to be the numeric value '1981'; 'Month' is declared to be the string constant 'January'; 'Almost_Pi' is declared to be the result of '22.0' divided by '7.0'; 'Lie' is declared to be the Boolean value 'FALSE'; and 'Untruth' is declared to be of type 'Lie.' 3 Module_Initialization The TO BEGIN DO section allows you to specify a statement, in a module, that is to be executed before the executable section of the main program. Syntax: TO BEGIN DO statement; The 'statement' is a VSI Pascal statement. The TO BEGIN DO section can only appear in modules, can only appear once in a module, and must appear as the last section in the declaration section. (If appearing together, the TO BEGIN DO section must precede the TO END DO section at the end of the declaration section.) As a general rule, if a program or module inherits an environment file, the initialization section in the inherited module must be executed before the initialization section in the program or module that inherited it. If a module or program inherits more than one module that contains an initialization section, the order of execution of the inherited modules cannot be determined. Example: MODULE X( INPUT, OUTPUT ); VAR Debug : Boolean; PROCEDURE Test(...); {Executable section...} TO BEGIN DO BEGIN WRITE( 'Debug Module x? ' ); READLN( Debug ); END; END. This TO BEGIN DO section contains statements that write a string and test the validity of the Debug variable. 3 Module_Finalization The TO END DO section allows you to specify a statement, in a module, to be executed after the executable section of the main program. Syntax: TO END DO statement; The 'statement' is a VSI Pascal statement. The TO END DO section can only appear in modules, can only appear once in a module, and must appear as the last section in the declaration section (if appearing together, the TO BEGIN DO section must precede the TO END DO section at the end of the declaration section). Example: MODULE File_Output; VAR Out_File : TEXT; t : TIMESTAMP; PROCEDURE Test(...); {Executable section...} TO BEGIN DO OPEN( Out_File, 'foo.dat' ); END; TO END DO BEGIN GETTIMESTAMP( t ); WRITELN( 'foo.dat closed at', TIME( t ) ); CLOSE( Out_File ); END; END. This TO END DO section contains statements that print the file name and closing time. 3 Type_Declaration A TYPE section introduces the name and set of values for a user-defined type or schema definition and has one of the following forms: Syntax: TYPE {type-identifier = [[attribute-list]] type-denoter} [[VALUE initial-state-specifier]];... TYPE {schema-declaration} [[VALUE initial-state-specifier]] The 'type-identifier' is the identifier of the type being defined. The 'attribute-list' is one or more optional identifiers that provide additional information about the type-denoter. The 'type-denoter' is any legal Pascal type syntax. The 'schema-declaration' is the declaration of a schema type. The 'initial-state-specifier' is a compile-time expression that is assignment compatible with a variable of the TYPE identifier being defined. VSI Pascal initializes all variables declared to be of this type with the constant value or values provided (unless there is an overriding initial-state specifier in the variable declaration). Pascal requires that all user-defined type identifiers (except base types of pointers) be defined before they are used in the definitions of other types. A base type must be defined before the end of the TYPE section in which it is first mentioned. Example: TYPE Entertainment = ( dinner, movie, theater, concert ); Week_end = ( sat, sun ) VALUE sat; Hours_worked = ARRAY[mon .. fri] OF INTEGER; Salary = ARRAY[1 .. 50] OF REAL; Salary_template( upper_bound : integer ) = ARRAY [1..upper_bound] of REAL; Pay = salary; Ptr_to_hits = ^Hits; Hits = RECORD Title, Artist, Composer : VARYING[30] OF CHAR; Weeks_on_chart : INTEGER; First_version : Boolean; END; VAR Week1, Week2 : Week_end; Week3 : Week_end VALUE sun; Salary_type2 : Salary_template( x ); In this example, 'Week1' and 'Week2' have initial values of sat, as specified in the TYPE definition of 'Week_end'. 'Week3' has an initial value of sun, because an initial value specified in the variable declaration overrides any initial value specified in the type definition. The 'Salary_template' schema has actual discriminants of x, which indicates that the upper boundary of 'Salary_type2' will be determined at run time by a variable or function call. 3 Variable_Declaration A VAR section declares variables and associates each variable with an identifier, a type, and optionally an initial value. Syntax: VAR {{variable-identifier},... : [[attribute-list]] type-denoter [[ {:= | VALUE} initial-state-specifier]]};... The 'variable-identifier' is the identifier of the variable being declared. The 'attribute-list' is one or more optional identifiers that provide additional information about the variable. The 'type-denoter' is any legal Pascal type syntax. The 'initial-state-specifier' is any constant expression that is assignment compatible with the variable identifier. The variable is initialized to this expression. See the "HP Pascal Language Reference Manual" for the rules that apply to the use of initial-state specifiers on variables. You can use either the assignment operator (:=) or the reserved word VALUE. However, if you require portable code, you should use VALUE. Example: TYPE Hours_worked = ARRAY [1..10] OF INTEGER; VAR Answer, Rumor : Boolean; Temp : INTEGER VALUE 60; Grade : 'A'..'D'; Weekly_hours : Hours_worked VALUE [1..3 : 7; OTHERWISE 5]; This VAR section declares five variables. The variables 'Answer' and 'Rumor' are both Boolean variables; 'Temp' is an integer variable initialized with the value 60; 'Grade' is of a character subrange type consisting of the characters 'A','B','C', and 'D'; 'Weekly_hours' is declared to be of the user-defined array type 'Hours_worked' and is initialized with a constructor of integers. 3 Value_Declaration If you choose, you can use the VALUE section as a VSI Pascal extension that initializes ordinal, real, array, record, set, and string variables. (If you require portable code, use the VALUE reserved word in either TYPE definitions or VAR declarations.) The exact form of an initialization depends on the type of the variable being initialized. Syntax: VALUE {variable-identifier := constant-expression};... The 'variable-identifier' is the name of the variable to be initialized. You can initialize a variable or variable component only once in the VALUE section. Any variables appearing in the VALUE section must appear in a previous VAR section. The 'constant-expression' is any constant expression that is assignment compatible with the variable identifier. Unlike other declaration sections, the VALUE section can appear only in a program or module declaration section. You cannot use the VALUE declaration section in procedures or functions. If you wish to initialize variables in procedures and functions, use an initial-state specifier (by using the VALUE reserved word in either the TYPE or VAR section). You can assign values to complete structured variables or to a single component of that variable. Example: VAR School : Record Class : Record Grades : Char; Order : Integer; End; Passed : Boolean; End; VALUE School := (('B', 14), TRUE); The constructor of School specifies a constant value of the correct type for each field in the record. 3 Routine_Declaration The basic algorithm for a program can usually be divided into relatively simple, repetitive tasks. In Pascal, you can code each task separately as a routine; that is, as either a procedure or a function. A procedure contains one or more statements to be executed once the procedure is called. A function contains one or more statements to be executed once the function is called; in addition, functions return a single value. A routine call executes all statements in the body of the declared routine. You must declare a routine before you can call it. In addition, function calls return a single value. Syntactically, procedure calls are statements, and function calls are expressions. You can call routines in the executable section of a program or in the body of another routine. Syntax: [[attribute-list]] PROCEDURE routine-identifier [[formal-parameter-list]]; { [[declaration-section]] BEGIN {statement};... END | {EXTERN EXTERNAL FORTRAN FORWARD} } Syntax: [[attribute-list]] FUNCTION routine-identifier [[formal-parameter-list]] : [[attribute-list]] result-type-id; { [[declaration-section]] BEGIN {statement};... END | {EXTERN EXTERNAL FORTRAN FORWARD} } The 'attribute-list' is one or more optional identifiers that provide additional information about the type-denoter. The 'routine-identifier' is the name of the routine. If you use the routine-identifier within the routine body (with the exception of assigning a value to the routine-identifier of a function), the result is a recursive call to the routine. The routine-identifier of a procedure can be redeclared in the procedure's declaration-section. The routine-identifier of a function cannot be redeclared in the function's declaration-section; however, it can be redeclared in any nested routines within the function's declaration-section. The 'formal-parameter-list' is a comma list of the routine's formal parameters. A procedure can have as many as 255 formal parameters; depending on the function return value, some functions are limited to 254 formal parameters. Optionally, you can specify a mechanism specifier and an attribute list for each parameter. The 'declaration-section' can include all sections except TO BEGIN DO, TO END DO, and VALUE sections. Data specified in this declaration section is local to the routine and to any nested routines; you can redeclare identifiers that are declared in an outer block. You cannot redeclare a formal parameter identifier to be a local variable in the routine. The 'statement' is any VSI Pascal statement. In a function executable section, there must be at least one statement of the following form: routine-identifier := result The 'routine-identifier' is the name of the function. The 'result' is a value of either an ordinal, real, structured, or pointer type that VAX Pascal returns when function is called. This value must be of the same type as the result-type-id, and cannot be a file type or a structured type with a file component. 'EXTERN', 'EXTERNAL', 'FORTRAN', and 'FORWARD' are predeclared identifiers that direct VSI Pascal to find the body of the routine elsewhere. The EXTERN, EXTERNAL, and FORTRAN identifiers declare routines that are independently compiled by VSI Pascal or that are written in other languages. In VSI Pascal, these identifiers are equivalent. Although not part of the Pascal standard, many Pascal compilers only accept the FORTRAN identifier for external routines actually written in FORTRAN; if portability is a concern, you may wish to use FORTRAN only for external FORTRAN routines. The 'result-type-id' is the type specification of the function return value. The function's result must be of this data type. This type cannot be a file type or a structured type with a file component. Example: PROCEDURE Read_Write( VAR A : INTEGER ); This declares a procedure, 'Read_Write', which takes one variable parameter, 'A'. Example: FUNCTION Counter( VAR Instring, Outstring : VARYING[10] OF CHAR; VAR Valid : Boolean ) : INTEGER; This declares a function, 'Counter', which takes three variable parameters, 'Instring', 'Outstring', and 'Valid' and returns an INTEGER value. 4 formal_parameter_list A formal parameter is located in the header of the routine declaration, and consists of input parameters, output parameters, and routine parameters. A routine uses input parameters to obtain values; it uses output parameters to return values; and it uses routine parameters to call another routine named by a formal parameter. The formal parameter establishes the semantics, the data type, and the required passing mechanism of the parameter. See the "HP Pascal Language Reference Manual" for more information on parameter passing mechanisms. Syntax: [[({ {value-parameter-spec | variable-parameter-spec | routine-parameter-spec | foreign parameter-spec} };...)]] The specific format depends on the semantics (value, variable, routine, or foreign) of the formal parameter you are declaring. A formal value parameter represents a local variable within the called routine. When you specify value semantics, the address of the actual parameter is passed to the called routine, which then copies the value from the specified address to its own local storage. The routine then uses this copy. The copy is not retained when control returns to the calling block. Therefore, if the called routine assigns a new value to the formal parameter, the change is not reflected in the value of the actual parameter. Syntax: {identifier},... : [[attribute-list]] {type-id | conformant-parameter-syntax | undiscriminated-schema-name} [[:= [[mechanism-specifier]] default-value]] A formal variable parameter represents another name for a variable in the calling block. It is preceded by the reserved word VAR. When you specify variable semantics, the address of the actual parameter is passed to the called routine. In contrast to value semantics, the called routine directly accesses the actual parameter. Thus, the routine can assign a new value to the formal parameter during execution and the changed value is reflected immediately in the calling block (the value of the actual parameter changes). Syntax: VAR {identifier},... : [[attribute-list]] {type-id | conformant-parameter-syntax | undiscriminated-schema-name} [[:= [[mechanism-specifier]] default-value]] To write a routine that invokes another routine whose effect is not determined until the program is executed, use routine parameters. To declare a procedure or a function as a formal parameter to another routine, you must include a complete routine heading in the formal parameter list. You can also associate a foreign mechanism specifier and a default value with a formal procedure or function parameter. Syntax: [[attribute-list]] PROCEDURE procedure-id [[formal-parameter-list]] [[ := [[mechanism-specifier]] default-value ]] or [[attribute-list]] FUNCTION function-id [[formal-parameter-list]] : [[attribute-list]] result-type-id [[ := [[mechanism-specifier]] default-value ]] When declaring an external routine (one written in a language other than Pascal) that is called by a VSI Pascal routine, you must specify not only the correct semantics but the correct mechanism as well. To allow you to obtain these passing mechanisms, VSI Pascal provides foreign mechanism specifiers and the passing mechanism attributes. See the "HP Pascal Language Reference Manual" for complete details on formal parameter semantics. 5 identifier The 'identifier' is the name of the formal parameter. Multiple identifiers must be separated with commas. 5 attribute_list The 'attribute-list' is one or more optional identifiers which provide information about the formal parameter. 5 mechanism_specifier VSI Pascal provides the foreign mechanism specifiers %IMMED, %REF, %DESCR, and %STDESCR, which precede a formal parameter in the declaration of an external routine. If the formal parameter does not represent a routine, the mechanism specifier must precede the parameter name. If the formal parameter represents a routine, the specifier must precede the reserved word PROCEDURE or FUNCTION in the parameter declaration. In addition, it is possible to use the passing mechanism attributes [IMMEDIATE] and [REFERENCE] in a formal parameter's attribute list to obtain the same behavior as %IMMED or %REF, respectively. A %REF or [REFERENCE] formal parameter requires actual parameters to be passed by reference. %REF or [REFERENCE] implies variable semantics unless the actual parameter is an expression; in that case, it implies foreign value semantics. An %IMMED or [IMMEDIATE] formal parameter requires actual parameters to be passed with the by immediate value mechanism and always implies value semantics. %IMMED or [IMMEDIATE] cannot be used on formal parameters of type VARYING, or on conformant array and conformant VARYING parameters. A %DESCR formal parameter requires actual parameters to be passed with the by descriptor mechanism and interprets the semantics as %REF or [REFERENCE] does. A %STDESCR formal parameter requires actual parameters to be passed with the by string descriptor mechanism. An actual parameter variable of type PACKED ARRAY OF CHAR implies variable semantics. An actual parameter expression of either type PACKED ARRAY OF CHAR or type VARYING OF CHAR implies foreign value semantics. You cannot use %STDESCR on formal procedure and function parameters. 5 type_id A type identifier is the type identifier of the parameters in this parameter section. 5 undiscriminated_schema_name The name of an undiscriminated schema type. If you have a user-defined, formal parameter of an undiscriminated schema type, the corresponding actual parameter must be discriminated from the same schema type as that of the formal parameter. When you pass a string expression to a formal, value parameter of type STRING, the actual parameter's current length (not its declared maximum length) becomes both the maximum length and the current length of the formal parameter. 5 conformant_parameter A conformant parameter is a syntax of a conformant array or a conformant VARYING parameter that represents a set of types that are identical except for their bounds. The bounds of a conformant parameter are determined each time a corresponding actual parameter is passed. The bounds of an actual parameter are available within the routine through identifiers declared in the schema. A conformant parameter can only appear within a formal parameter list. The form of a conformant array parameter is as follows: ARRAY [{lower-bound-id .. upper-bound-id : [[attribute-list]] index-type-id};...] OF [[attribute-list]] {type-id | conformant-parameter-syntax} PACKED ARRAY [lower-bound-id .. upper-bound-id : [[attribute-list]] index-type-id] OF [[attribute-list]] type-id The form of a conformant VARYING parameter is as follows: VARYING [upper-bound-id] OF [[attribute-list]] CHAR The 'lower-bound-id' is an identifier that represents the lower bound of the conformant array's index. The 'upper-bound-id' is an identifier that represents the upper bound of the conformant array's index. The 'attribute-list' is one or more optional identifiers that provide additional information about the conformant array. The 'index-type-id' is the type identifier of the index, which must denote an ordinal type. The 'type-id' is the type identifier of the array components, which can denote any type. 5 default_value VSI Pascal allows you to supply default values for formal parameters. Using default parameter values, you do not need to pass actual parameters. Also, you can specify an actual parameter in the position of a formal parameter whose default value you want to override. This value can be any constant value of the type. It must be a legal actual parameter for the kind of formal parameter with which the default is associated. The default-value is evaluated when the routine is declared. 4 block A block is a declaration section and an executable section. Programs, modules, and routines are structured in blocks. A declaration section can contain routine blocks nested within the outer program or module block; routine blocks can also be nested within other routines. Syntax: [[declaration-section]] BEGIN {statement};... END The declaration section contains data definitions and declarations, and nested routine declarations that are local to the enclosing block. The executable section contains the statements that specify the block's actions. You can exit from a block with the last executable statement of the block, which causes normal termination, or with a GOTO statement, which transfers control to an outer block. 4 directive A directive is the alternative to a block in a routine declaration. A directive provides the compiler with information about either a routine whose heading is declared separately from its body (indicated by the FORWARD directive) or a routine that is external to the Pascal program (indicated by the EXTERNAL, EXTERN or FORTRAN directives). To specify a directive, include it immediately after the routine heading and follow it with a semicolon. The following describes the two classes of directives. o The FORWARD directive indicates a routine whose block is specified in a subsequent part of the same procedure and function section, allowing you to call a routine before you specify its routine body. As an extension, VSI Pascal will allow the body to be in a different declaration part. If the body and heading are specified in different procedure and function sections, a FORWARD declared function should not be used as an actual discriminant to a schema type. When you specify the body of the routine in subsequent code, include only the FUNCTION or PROCEDURE predeclared identifier, the routine-identifier, and the body of the routine. Do not repeat the formal-parameter, the attribute-list, or the result-type-id. o The EXTERNAL, EXTERN and FORTRAN directives indicate that a routine is external to a Pascal program. They are used to declare independently compiled Pascal routines written in other languages. For portability reasons, the FORTRAN directive should only be used for external routines written in FORTRAN. 2 Statements VSI Pascal statements specify actions to be performed and appear in executable sections. They are classified as either simple or structured. The simple statements are the assignment, empty, BREAK, CONTINUE, EXIT, GOTO, NEXT, RETURN, and routine call. The structured statements are the compound, conditional (CASE, IF-THEN[-ELSE], SELECT[ONE]), repetitive (FOR[-IN], REPEAT, WHILE), and WITH statements. 3 Assignment An assignment statement uses an assignment operator (:=) to assign a value to a variable or function identifier. Syntax: variable-access := expression The 'variable-access' is an identifier, array component, record component, pointer dereference, or file buffer. The 'expression' is 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. 4 Examples X := 1; {variable 'X' is assigned the value 1} T := A < B; {value of Boolean expression 'A < B' is assigned to 'T'} Vowels := ['A', 'E', 'I', 'O', 'U']; {set variable 'Vowels' is assigned the set constructor ['A', 'E', 'I', 'O', 'U']} 3 BREAK 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 is equivalent to a GOTO to a label placed just past the end of the closest FOR, WHILE, or REPEAT statement. Use caution when using the BREAK statement because future additions to the code may result in the BREAK statement leaving a different loop than was originally intended. The following example shows the usage of the BREAK statement. 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. 3 CASE The CASE statement causes one of several statements to be executed. The execution depends on the value of an ordinal expression called the case selector. Syntax: CASE case-selector OF [[{{case-label-list},... : statement};...]] [[ [[;]] OTHERWISE {statement};...]] [[;]] END The 'case-selector' is an expression of an ordinal type. The 'case-label-list' is 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. The 'statement' is any statement to be executed depending on the values of both the case-selector and the case-label. The 'OTHERWISE' clause is executed if the value of the case selector does not appear in the case label list. This is an optional clause, but if you omit it, the value of the case selector must be equal to one of the case labels. 4 Examples CASE CH OF ' ',TAB : WRITELN( 'Found a space' ); '0'..'9': WRITELN( 'Found a digit' ); 'A'..'Z': WRITELN( 'Found a capital letter' ); OTHERWISE WRITELN( 'Illegal character' ); END; At run time, the system evaluates the case selector 'CH' and executes the corresponding statement. If the value of 'CH' is not equal to ' ', '0'..'9' or 'A'..'Z', the statement in the 'OTHERWISE' clause is executed. 3 Compound A compound statement groups a series of statements so that they can appear anywhere that language syntax calls for a single statement. Syntax: BEGIN {statement};... END The 'statement' is any VSI Pascal statement, including other compound statements. 3 CONTINUE 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 may result in the CONTINUE statement continuing with a different loop than was originally intended. 3 Empty_Stmt The empty statement causes no action to occur other than the advancement of program flow to the next statement. To use the empty statement, place a semicolon where the language syntax calls for a statement. 3 EXIT The EXIT statement is identical to the BREAK statement 3 FOR The FOR statement is a looping statement that repeats execution of a statement according to the value of a control variable. The control variable assumes a value within a specified range or set. A FOR statement has one of the following forms: FOR control-variable := initial {TO | DOWNTO} final-value DO statement FOR control-variable IN set-expression DO statement The 'control-variable' is the name of a previously declared variable of an ordinal type. The 'initial-value' and 'final-value' are expressions that form a range and whose type is assignment compatible with the type of the control variable. The 'set-expression' is an expression resulting in a value of SET type. The base type of the set must be assignment compatible with the control variable. The 'statement' is any VSI Pascal statement that does not change the value of the control variable. At run time, the initial and final values or the set expression is evaluated before the loop body is executed. The 'TO | DOWNTO' directives determine whether loop iteration will be incremental or decremental, respectively. In the TO form, VSI Pascal checks to see if the value of the control variable is less than or equal to the final value. If this condition is met, the control variable takes on the value of the initial value for the first loop iteration. During iterations, the control variable increments according to its data type. Looping ceases when the control variable is greater than the final value. In the DOWNTO form, VSI Pascal checks to see if the value of the control variable is greater than or equal to the final value. If this condition is met, the control variable takes on the value of the initial value for the first loop iteration. During iterations, the control variable decrements according to its data type. Looping ceases when the control variable is less than the final value. In the set expression form, VSI Pascal checks to see if the set expression is not the empty set. If this condition is met, the control variable takes on the value of one of the members of the set. Iterations occur for each member of the set; the selection order of members of the set is undefined. Looping stops after the loop body executes for each member of the set. In both the TO and the DOWNTO forms, incrementation of the control variable depends on its type. For example, values expressed in type INTEGER increment or decrement in units of 1. Values expressed in type CHAR increment or decrement in accordance with the ASCII collating sequence. After normal termination of the FOR statement, the control variable does not retain a value. You must assign a new value to this variable before you use it elsewhere in the program. If the FOR loop terminates with a GOTO statement, the control variable retains the last assigned value. In this case, you can use the variable again without assigning a new value. 4 Examples Example: FOR I := 1 TO 10 DO FOR J := 1 TO 10 DO A[I,J] := 0; This example shows how you can nest FOR loops. For each value of I, the executing program steps through all 10 values of the array J and assigns the value 0 to each component. Example: FOR I IN Set 1 DO Set2 := Set2 + [I + 1]; This example shows a FOR-IN statement. Set2 is assigned the successor of each value in Set1. 3 GOTO The GOTO statement causes an unconditional branch to a statement prefixed by a label. Syntax: GOTO label The 'label' is an unsigned decimal integer or symbolic name that represents a statement label. The GOTO statement must be within the scope of the label declaration. A GOTO statement that is outside a structured statement cannot jump to a label within that structured statement. A GOTO statement within a routine can branch to a labeled statement in an enclosing block only if the labeled statement appears in the block's outermost level. 4 Examples FOR i := 1 TO 10 DO BEGIN IF Real_Array[i] = 0.0 THEN BEGIN Result := 0.0; GOTO 10; END; Result := Result + 1.0/Real_Array[i]; END; 10: Invertsum := Result; This example shows how to use a GOTO statement to exit from a loop. The loop computes the sum of the inverses of the components of the variable 'Real_Array'. If the value of one of the components is 0.0, the sum is set to 0.0 and the GOTO statement forces an exit from the loop. 3 IF_THEN_ELSE The IF statement tests a Boolean expression and performs a specified action if the result of the test is TRUE. The ELSE clause, when it appears, executes only if the test condition results to FALSE. Syntax: IF boolean-expression THEN statement1 [[ELSE statement2]] The 'boolean-expression' is any Boolean expression. The 'statement1' is the statement to be executed if the value of the Boolean expression is TRUE. The 'statement2' is the statement to be executed if the value of the Boolean expression is FALSE. VSI Pascal may not always evalutate all the terms of a Boolean expression if it can evaluate the entire expression based on the value of one term. Either do not write code that depends on actual evalution (or evaluation order) of Boolean expressions, or use the AND_THEN and OR_ELSE operators for a predictable order of evaluation. 4 Examples IF x > 10 THEN y := 4 IF x > 10 THEN BEGIN y := 4; ELSE y := 5; z := 5; END ELSE y := 5; The ELSE clause always modifies the closest IF-THEN statement. Use caution to avoid logic errors in nested IF statements, as in the following: IF A = 1 THEN {First IF} IF B<>1 THEN {Second IF} C := 1 ELSE {Appears to modify first IF} C := 0; {Actually modifies second IF} 3 NEXT The NEXT statement is identical to the CONTINUE statement. 3 REPEAT The REPEAT statement is a looping statement and executes one or more statements until a specified condition is true. Syntax: REPEAT {statement};... UNTIL expression The 'statement' is any VSI Pascal statement. The 'expression' is any Boolean expression. VSI Pascal always executes a REPEAT statement for one iteration; iterations continue as long as the Boolean expression is FALSE. When specifying more than one statement as the loop body to a REPEAT statement, do not enclose the statements with the BEGIN and END reserved words; multiple statements are legal in the REPEAT loop body. 4 Examples REPEAT READ (x); IF (x IN ['0'..'9']) THEN BEGIN Digit_count := Digit_count + 1; Digit_sum := Digit_sum + ORD (x) - ORD ('0'); END ELSE Char_count := Char_count + 1; UNTIL EOLN (INPUT); Assume that the variable 'x' is of type CHAR and the variables 'Digit_count', 'Digit_sum', and 'Char_count' denote integers. The example reads a character (x). If the value of 'x' is a digit, the count of digits is incremented by one and the sum of digits is increased by the value of 'x', as computed by the ORD function. If the value of 'x' is not a digit, the variable 'Char_count' is incremented by one. The REPEAT loop continues processing characters until it reaches an end-of-line condition. 3 RETURN The RETURN statement passes control back to the caller of a PROCEDURE, FUNCTION, PROGRAM, or module initialization or finalization section. A RETURN statement is equivalent to a GOTO to a label placed just before the END of the body, and in a PROGRAM, has the effect of stopping the program Syntax: RETURN [ return-value ] Inside a FUNCTION, return-value specifies an ending value for the FUNCTION. If no return-value is provided, the last value assigned to the function identifier is used as the function result. The return-value type and function type must be the same. Inside a PROGRAM, the return-value specifies an ending value for the PROGRAM. If you do not provide a return-value, VSI Pascal uses the value 1 on OpenVMS systems. Inside a PROCEDURE, module initialization section, or module finalization section, VSI Pascal generates an error. 4 Example FUNCTION FindFirst(StartingPoint: INTEGER) : INTEGER; VAR i: INTEGER; BEGIN FOR i := StartingPoint TO MaximumNumber DO BEGIN IF Data[i] = Suitable THEN BEGIN AttributesOfDesiredData = Attributes[i]; Subscript := i; RETURN i; END; END; END; The example shows the usage of RETURN ststement. In the example, a function searches through the array called "Data" for an element that matches "Suitable". When it finds one, it assigns values to two global variables and executes a RETURN. Omitting the RETURN statement would make the function continue processing; it would assign values for the last suitable element instead of the first. 3 Routine_Call A routine call executes all statements in the body of the declared routine. You must declare a routine before you can call it. You can call routines in the executable section of a program or in the body of another routine. When the routine finishes executing, control returns to the next executable statement in the calling block that follows the routine call. Syntax: routine-identifier [[ ({actual-parameter-list},...) ]] The 'routine-identifier' is the name of a procedure or function. The 'actual-parameter-list' is one or more run-time expressions of an appropriate type, or the name of a procedure or function. The appropriate type is determined by the corresponding formal parameter. Actual parameters have the following syntax: ({ [[mechanism-specifier]] procedure-identifier [[mechanism-specifier]] function-identifier [[mechanism-specifier]] expression type-identifier write-list-element },...) The 'mechanism-specifier' is any one of the foreign specifiers. The 'procedure-identifier' is the name of a predeclared procedure. The 'function-identifier' is the name of a predeclared function. The 'expression' is any compile-time or run-time expression. The 'type-identifier' is a predeclared identifier of any type. The 'write-list-element' has the format: expression[[:expression[[:expression]]]] Example: Tollbooth (Change, 0.25, Lane[1]); This statement calls the procedure 'Tollbooth', and passes the variable 'Change', the real constant '0.25', and the first component of the array 'Lane' as actual parameters. Example: Taxes (Rate*Income, 'Pay'); This statement calls the procedure 'Taxes', with the expression 'Rate*Income' and the string constant 'Pay' as actual parameters. 3 SELECT[ONE] The SELECT statement causes zero, one, or more of several statements to be executed. The SELECTONE statement causes zero or one statements to be executed. The execution depends on the value of an ordinal expression called the select selector. The SELECT and SELECTONE statements look much like the CASE statement except for one very powerful feature. Namely, the labels of a SELECT or SELECTONE statement can be run-time expressions as opposed to the CASE statement which only allows constant expressions. Syntax: SELECT select-selector OF [[{{select-label-list},...: statement};...]] [[ [[OTHERWISE {statement};...]] [[ALWAYS {statement};...]] ]] [[;]] END SELECTONE select-selector OF [[{{select-label-list},...: statement};...]] [[ OTHERWISE {statement};... ]] [[;]] END The 'select-selector' is an expression of an ordinal type. The 'select-label-list' is one or more select labels of the same ordinal type as the select selector, separated by commas. A select label can be a single expression, such as 1, or a range of expressions, such as 5..10. The expressions in a 'select-label-list' can be full run-time expressions. When two expressions are provided as a lower and upper bound, they must be of the same ordinal type. There is no check to ensure that the lower bound expression is less than or equal to the upper bound expression. If that occurs then there are no values of the select-selector that can be in the range. The 'statement' is any statement to be executed depending on the values of both the select-selector and the select-label. The SELECT statement checks to see if the value of the select-selector is contained in the select-label-list. If so, then the corresponding statement is executed. The select-label-lists are checked in the same lexical order that they appear in the source file. The same value can appear in more than one select-label-list. All corresponding statements to select-label-lists are executed if the value is contained in the select-label-list. By contrast, the SELECTONE statement stops processing after it executes the first statement that corresponds to a select-label-list that contains the select-selector value. The optional OTHERWISE and ALWAYS clauses can appear in either order. The ALWAYS clause is always executed. The OTHERWISE clause is executed only if none of the prior statements (except for an optional ALWAYS statement) have been executed. The syntax for the SELECTONE statement is almost identical but does not provide for an ALWAYS clause. 4 Examples While the SELECT/SELECTONE statements can be used similar to the CASE statement. For example, SELECT expression OF 1: WRITELN('ONE'); 2: WRITELN('TWO'); OTHERWISE WRITELN('not ONE or TWO') END a more subtle (and powerful) form uses the Boolean constant 'TRUE' as the select-selector. For example, SELECTONE True OF expression < 10: WRITELN('Value is small'); expression < 100: WRITELN('Value is medium'); expression < 1000: WRITELN('Value is big'); OTHERWISE WRITELN('Value is too big'); END SELECTONE True OF expression = "AAA": writeln('String is AAA'); expression = "BBB": writeln('String is BBB'); expression = "CCC": writeln('String is CCC'); OTHERWISE writeln('unknown string'); END FOR i := 1 TO 10 DO SELECT True OF ODD(i): WRITELN('value ',i:1,' is odd'); (i MOD 3) = 0: WRITELN('value ',i:1,' is also a multiple of 3'); END; 3 WHILE The WHILE statement is a loop that executes a statement while a specified condition is true. Syntax: WHILE expression DO statement The 'expression' is any Boolean expression. The 'statement' is any VSI Pascal statement. VSI Pascal checks the value of the Boolean expression before executing the loop body for the first time; if the expression is FALSE, the loop body is not executed. If the initial value is TRUE, loop iterations continue until the condition is FALSE. When specifying more than one statement as the loop body to a WHILE statement, enclose the statements with the BEGIN and END reserved words, since the syntax calls for a single statement to follow the DO reserved word. If you do not use a compound statement for the loop body, VSI Pascal executes the first statement following the DO reserved word as the loop body. 4 Examples WHILE NOT EOLN (INPUT) DO BEGIN READ (x); IF NOT (x IN ['A'..'Z', 'a'..'z', '0'..'9']) THEN Err := Err + 1; END; This example reads an input character (x) from the current line. If the character is not a digit or letter, the error count, 'Err', is incremented by one. The loop terminates when an end-of-line on the INPUT is reached. 3 WITH The WITH statement provides an abbreviated notation for references to the fields of a record variable or to the formal discriminants of a discriminated schema type. Syntax: WITH {record-variable | schema-variable},... DO statement The 'record-variable' is the name of the record variable being referenced. The 'schema-variable' is the name of the schema variable being referenced whose type is a discriminated schema type. This underlying type of the schema can be a record. The 'statement' is any VSI Pascal statement. The WITH statement allows you to refer to the fields of a record or to an formal discriminant of a schema by their names alone, rather than by the record.field-identifier or schema-variable.formal-discriminant syntax. In effect, the WITH statement opens the scope so that references to field identifiers or to formal discriminants alone are unambiguous. When you access a variable using a WITH statement, the reference syntax lasts only throughout the execution of the statement. If you are specifying nested records, their variable names must appear in the order in which they were nested in the record type definition. If you are working with record and schema variables that are not nested, you can specify variable names in any order. If you specify record or schema variables whose field names or formal discriminants conflict with one another, VSI Pascal uses the last record or schema in the comma list. 4 Examples Example: WITH Cat, Dog DO Bills := Bills + Cat_vet + Dog_vet; where 'Cat' and 'Dog' are records and 'Cat_vet' is a field of 'Cat' and 'Dog_vet' is a field of 'Dog'. Example: VAR x : STRING( 10 ); y : STRING( 15 ); WITH x, y DO WRITELN( CAPACITY ); VSI Pascal uses the last schema variable specified, y. The WRITELN statement prints y.CAPACITY. 2 Predeclared_Routines VSI Pascal supplies predeclared procedures and functions that perform various commonly used operations. You do not have to declare these routines in order to call them from your code. 3 Allocation The allocation size routines provide information about the amount of storage allocated for variables and components of various types. The parameters may be in the form of variable or type identifiers. Each routine returns an integer value that represents the allocation size of the given parameter. 4 BITNEXT The BITNEXT function returns an integer value that indicates the number of bits that would be allocated for one component of the specified type in a packed array or if the specified variable appeared as a cell in a packed array. Syntax: BITNEXT( x ) The parameter 'x' can be a variable or any type identifier. 4 BITSIZE The BITSIZE function returns an integer value that indicates the number of bits that would be allocated for one field of the specified type in a packed record or if the specified variable appeared as a field in a packed record. Syntax: BITSIZE( x ) The parameter 'x' can be a variable or any type identifier. 4 BIT_OFFSET The BIT_OFFSET function returns an integer value that represents the bit position of a field in a record. Syntax: BIT_OFFSET( t,f ) The parameter 't' can be of any record type or variable, and the parameter 'f' can be any field contained in that record. 4 BYTE_OFFSET The BYTE_OFFSET function returns an integer value that represents the byte position of a field in a record. Syntax: BYTE_OFFSET( t,f ) The parameter 't' can be of any record type or variable, and the parameter 'f' can be any field contained in that record. 4 NEXT The NEXT function returns an integer value that indicates the number of bytes that would be allocated for one component of the specified type in an unpacked array or if the specified variable appeared as the cell in an unpacked array. Syntax: NEXT( x ) The parameter 'x' can be a type identifier or variable. Cells in an unpacked array are affected by alignment attributes and, by default, are byte or naturally aligned. Therefore, the size returned includes the actual size of the type or variable, in addition to trailing space required to ensure proper alignment. 4 SIZE The SIZE function returns an integer value that indicates the possible or actual number of bytes that are allocated for a specified data type or variable. Syntax: SIZE( x[[,t1,...,tn]] ) The parameter 'x' can be a type identifier or a variable. If 'x' is a type identifier, then SIZE returns an integer value which indicates the number of bytes that would be allocated for a variable or record field of type 'x'. If 'x' is a variable, then SIZE returns an integer value that indicates the number of bytes that are allocated for that variable. In the case where the parameter 'x' is a variant record variable or variant type identifier, SIZE returns an integer value that indicates the number of bytes that are allocated (for a variant record variable) or would be allocated (for a variant type identifier) for both the fixed portion of the record and the largest variant. In addition you can supply additional parameters t1 through tn that correspond to the case labels of the record. The SIZE routine returns an integer value that indicates the number of bytes that would be allocated by the NEW procedure for a dynamic variable of the specified variant. 3 Arithmetic Arithmetic routines perform mathematical computations. Actual parameters to the arithmetic functions can be of any arithmetic type. 4 ABS The ABS function returns a value (of the same data type as the specified parameter) that is the absolute value of the parameter. Syntax: ABS( x ) The parameter 'x' can be of any arithmetic type. 4 ARCTAN The ARCTAN function returns a real value that expresses in radians the arctangent of the specified parameter. Syntax: ARCTAN( x ) The parameter 'x' can be an integer or REAL type. 4 COS The COS function returns a real value that represents the cosine of the specified parameter. Syntax: COS( x ) The parameter 'x' can be an integer or REAL type, and is expressed in radians. 4 EXP The EXP function returns a real value that represents the exponent of the specified parameter (it represents e**x). Syntax: EXP( x ) The parameter 'x' can be an integer or REAL type. 4 LN The LN function returns a real value that represents the natural logarithm of the specified parameter. Syntax: LN( x ) The parameter 'x' can be an integer or REAL type. The value of 'x' must be greater than zero. 4 LSHIFT_LSHFT The LSHIFT and LSHFT predeclared functions return a value of the same type as its first parameter. The return value represents the value of the first parameter after the bits have been shifted to the left. Syntax: LSHIFT(expression,expression) LSHFT(expression,expression) The parameters are two integer or unsigned values. The first parameter represents a value to shift. The second parameter represents the number of bits to shift the first value to the left. LSHIFT and LSHFT insert zero bits on the right as the bits shift left. Note that shifting integers is not equivalent to multiplying or dividing by a power of two when the value of the integer is negative. If the number of bits shifted is larger than the natural integer size of the target platform, the result is undefined. 4 MAX The MAX function returns a value (the same type as that of the parameters) that is the maximum value of a specified list of parameters. Syntax: MAX( x1,...,xn ) The parameters can be any arithmetic type, but must all be of the same type. 4 MIN The MIN function returns a value (of the same type as that of the parameters) that is the minimum value of a specified list of parameters. Syntax: MIN( x1,...,xn ) The parameters can be any arithmetic type, but must all be of the same type. 4 RSHIFT_RSHFT The RSHIFT and RSHFT predeclared functions return a value of the same type as its first parameter. The value represents the value of the first parameter after the bits have been shifted to the right. Syntax: RSHIFT(expression,expression) RSHFT(expression,expression) The parameters are two integer or unsigned values. The first parameter represents a value to shift; the second represents the number of bits to shift the first value. The RSHIFT and RSHFT functions insert zero bits on the left as the bits shift right. Note that shifting integers is not equivalent to multiplying or dividing by a power of two when the value of the integer is negative. If the number of bits shifted is larger than the natural integer size of the target platform, the result is undefined. 4 SIN The SIN function returns a real value that represents the sine of the specified parameter. Syntax: SIN( x ) The parameter 'x' can be an integer or REAL type, and is expressed in radians. 4 SQR The SQR function returns a value (of the same type of the parameter) that represents the square of the specified parameter. Syntax: SQR( x ) The parameter 'x' can be of any arithmetic type. 4 SQRT The SQRT function returns a real value that represents the square root of the specified parameter. Syntax: SQRT( x ) The parameter 'x' can be of an integer, unsigned, or REAL type. If the value of 'x' is less than zero, an error occurs. 4 UAND The UAND function returns an unsigned value that represents a binary logical AND operation on each corresponding pair of bits of the specified parameters. Syntax: UAND( u1,u2 ) The parameters 'u1' and 'u2' must be unsigned. 4 UNOT The UNOT function returns an unsigned value that represents a binary logical NOT operation on each bit of the specified parameter. Syntax: UNOT( u1 ) The parameter 'u' must be unsigned. 4 UOR The UOR function returns an unsigned value of a binary logical OR operation on the corresponding pair of bits of two specified parameters. Syntax: UOR( u1,u2 ) The parameters 'u1' and 'u2' must be unsigned. 4 UXOR The UXOR function returns an unsigned value of a binary logical exclusive-OR operation on the corresponding pair of bits of two specified parameters. Syntax: UXOR( u1,u2 ) The parameters 'u1' and 'u2' must be unsigned. 4 XOR The XOR function returns a value (of the same type as the parameters) of a binary logical exclusive-OR operation on two specified parameters. Syntax: XOR( p1,p2 ) The 'p1' and 'p2' parameters must be of the same type and must be of either the BOOLEAN or SET types. 3 Char_Strng VSI Pascal supplies predeclared routines that manipulate character strings. 4 BIN The BIN function returns a character-string value that is the binary equivalent of the specified parameter. The return value is compatible with all other string types. Syntax: BIN( x [[, length[[, digits]]]] ) The parameter 'x' is the expression to be converted. This parameter must have a size that is known at compile time; it cannot be VARYING OF CHAR, a conformant parameter, or a schema type. Two optional integer parameters specify the length of the resulting string and the minimum number of significant digits to be returned. If you specify a length that is too short to hold the converted value, the resulting string is truncated on the left. If you omit the optional parameters, the bit width of the converted parameter value determines the string length and the number of significant digits. By default, the number of significant digits is the minimum number of characters necessary to express all the bits of the converted parameter. This default length is one character more than the default number of digits, which causes a leading blank to be included in the resulting string when both parameters are omitted. 4 DEC The DEC function returns character-string value that is the decimal equivalent of the specified parameter. The return value is compatible with all other string types. Syntax: DEC( x [[, length[[, digits]]]] ) The parameter 'x' is the expression to be converted. The DEC function can take a parameter of any type except VARYING OF CHAR, conformant parameters, or schema types. The DEC function requires the size of 'x' to be less than or equal to the size of INTEGER64 (if supported), or less than or equal to the size of INTEGER32. Two optional integer parameters specify the length of the resulting string and the minimum number of significant digits to be returned. If you specify a length that is too short to hold the converted value, the resulting string is truncated on the left. If you do not specify values for the optional parameters, a default length and a default minimum number of significant digits is used. If the size of 'x' is greater than 32, the defaults are 20 characters for the length and 19 characters for the minimum number of digits. Otherwise, the defaults are 11 characters for the length and 10 characters for the minimum number of digits. Because the default length is 1 greater than the number of significant digits, positive numbers will be preceded by a blank and negative numbers will be preceded by a minus sign. 4 EQ The EQ function returns a Boolean value that specifies if the parameters are equal according to the ASCII values of the strings' characters. Syntax: EQ( str1,str2 ) The parameters 'str1' and 'str2' must be character-string expressions. If the EQ function detects unequal string lengths, it stops comparison and returns FALSE. 4 FIND_MEMBER The FIND_MEMBER function locates the first character in a string that is a member of a specified set and returns an integer value indicating the position of the character in the string; the function returns 0 if the characters in the string were not members of the set. Syntax: FIND_MEMBER( string, char-set ) The 'string' parameter is a string value, and the 'char-set' is a value of type SET OF CHAR. 4 FIND_NONMEMBER The FIND_NONMEMBER function locates the first character in a string that is not a member of a specified set and returns an integer value indicating the position of the character in the string; the function returns 0 if the characters in the string were all members of the set. Syntax: FIND_NONMEMBER( string, char-set ) The 'string' parameter is a string value, and the 'char-set' is a value of type SET OF CHAR. 4 GE The GE function returns a Boolean value that specifies if the first parameter is greater than or equal to the second parameter, according to the ASCII values of the strings' characters. Syntax: GE( str1,str2 ) The parameters 'str1' and 'str2' must be character-string expressions. VSI Pascal does not pad shorter strings with blanks. 4 GT The GT function returns a BOOLEAN value that specifies if the first parameter is greater than the second parameter, according to the ASCII values of the strings' characters. Syntax: GT( str1,str2 ) The parameters 'str1' and 'str2' must be character-string expressions. VSI Pascal does not pad shorter strings with blanks. 4 HEX The HEX function returns a character-string value that is the hexadecimal equivalent of the specified parameter. The return value is compatible with all other string types. Syntax: HEX( x [[, length[[, digits]]]] ) The parameter 'x' is the expression to be converted. This parameter must have a size that is known at compile time; it cannot be VARYING OF CHAR, a conformant parameter, or a schema type. Two optional integer parameters specify the length of the resulting string and the minimum number of significant digits to be returned. If you specify a length that is too short to hold the converted value, the resulting string is truncated on the left. If you do not specify values for the optional parameters, a default length and a default number of significant digits is used. By default, the number of significant digits is the minimum number of characters necessary to express all the bits of the converted parameter. This default length is one character more than the default number of digits, which causes a leading blank to be included in the resulting string when both parameters are omitted. 4 INDEX The INDEX function searches a string for a specified substring and returns an integer value that either indicates the location of the substring or the status of the search. Syntax: INDEX( string, substring ) INDEX requires two character-string expressions as parameters: a string to be searched and a substring to be found. The search ends as soon as the first occurrence of the substring is located. If the substring is found, INDEX returns the string component that contains the first letter of the substring. If the substring is not found, INDEX returns the value 0. If the substring is an empty string, INDEX returns the value 1. If the string to be searched is an empty string, INDEX returns the value 0 unless the substring is also empty; in which case, INDEX returns the value 1. 4 LE The LE function returns a Boolean value that specifies if the first parameter is less than or equal to the second parameter, according to the ASCII values of the strings' characters. Syntax: LE( str1,str2 ) The parameters 'str1' and 'str2' must be character-string expressions. VSI Pascal does not pad shorter strings with blanks. 4 LENGTH The LENGTH function returns an integer value that is the length of a specified string expression. Syntax: LENGTH( str ) The parameter 'str' must be a character-string expression. 4 LT This function returns a Boolean value that specifies if the first parameter is less than the second parameter, according to the ASCII values of the strings' characters. Syntax: LT( str1,str2 ) The parameters 'str1' and 'str2' must be character-string expressions. VSI Pascal does not pad shorter strings with blanks. 4 NE The NE function returns a Boolean value that specifies if the parameters are not equal according to the ASCII values of the strings' characters. Syntax: NE( str1,str2 ) The parameters 'str1' and 'str2' must be character-string expressions. VSI Pascal does not pad shorter strings with blanks. 4 OCT The OCT function returns character-string value that is the octal equivalent of the specified parameter. The return value is compatible with all other string types. Syntax: OCT( x [[, length[[, digits]]]] ) The parameter 'x' is the expression to be converted. This parameter must have a size that is known at compile time; it cannot be VARYING OF CHAR, a conformant parameter, or a schema type. Two optional integer parameters specify the length of the resulting string and the minimum number of significant digits to be returned. If you specify a length that is too short to hold the converted value, the resulting string is truncated on the left. By default, the number of significant digits is the minimum number of characters necessary to express all the bits of the converted parameter. This default length is one character more than the default number of digits, which causes a leading blank to be included in the resulting string when both parameters are omitted. 4 PAD The PAD function returns a character-string value, of the specified size, that contains padded fill characters. The return value is compatible with all other string types. Syntax: PAD( str,fill,size ) The parameter 'str' is a character-string value to be padded; the parameter fill is a value of type CHAR to be used as the fill character; and, the parameter 'size' is an integer value indicating the size of the final string. This string is composed of the original string followed by the fill character, which is repeated as many times as is necessary to extend the string to its specified size. The final size must be greater than or equal to the length of the string to be padded. 4 READV The READV procedure reads characters from a character-string expression and assigns them to parameters in the READV call. The behavior of READV is analogous to that of READLN; the character string is analogous to a one-line file. Syntax: READV( str, {variable-id[[ : radix-specifier ]]},... [[, ERROR := error-recovery ]]) The parameter 'str' is the string to be read. The variable-identifier is the variable to be assigned a value from 'str'. The parameter 'radix-specifier' can be BIN, OCT, or HEX. You can read a variable of any type by using a radix specifier except a type that contains a file component. The 'error-recovery' indicates the action to be taken in case of an error. An error occurs at run time if values have not been assigned to all the parameters listed in the READV procedure call before the end of the character string is reached. 4 STATUSV The STATUSV function returns an integer value that specifies the status of the last READV or WRITEV completed. It does not have any parameters. Note that if you have an asynchronous trap (AST) routine condition handler written in your program that uses READV and WRITEV, the call of STATUSV in your main program may not return the results you expected if an AST occurred between the READV/WRITEV and STATUS. 4 SUBSTR The SUBSTR function returns a substring (from a string specified as a parameter) that is of the specified starting point and length. The return value is compatible with all other string types. Syntax: SUBSTR( str,start [,length] ) The parameter 'str' is a character string value; the parameter 'start' is an integer value that indicates the starting position of the substring. The parameter 'length' is an integer value that indicates the length of the substring. If the 'length' argument is omitted, the length is computed to be the remainder of the string value beginning at the starting position. The 'length' argument cannot be omitted on OpenVMS VAX systems. For example, SUBSTR(string,start_index) is identical to SUBSTR(string,start_index,length(string)-string_index+1) When you use the SUBSTR function, the value of the starting position must be greater than 0, the value of the length must be greater than or equal to 0, and there must be enough characters following the starting position to construct a substring of the specified length. 4 UDEC The UDEC function returns a character-string value that is the unsigned decimal equivalent of the specified parameter. The return value is compatible with all other string types. Syntax: UDEC(x [[,length[[,digits]]]]) The parameter 'x' is the expression to be converted. The UDEC function can take a parameter of any type except VARYING OF CHAR, conformant parameters, or schema types. This function requires the size of 'x' to be less than or equal to the size of INTEGER64 (if supported) on your system. If your system does not support INTEGER64, then the UDEC function requires that 'x' be less than or equal to the size of INTEGER32. Two optional integer parameters specify the length of the resulting string and the minimum number of significant digits to be returned. If you specify a length that is too short to hold the converted value, the resulting string is truncated on the left. If you do not specify values for the optional parameters, a default length and a default minimum number of significant digits is used. If the size of 'x' is greater than 32, the defaults are 21 characters for the length and 20 characters for the minimum number of digits. Otherwise, the defaults are 11 characters for the length and 10 characters for the minimum number of digits. 4 WRITEV The WRITEV procedure writes characters to a character-string variable of type VARYING OF CHAR or discriminated STRING, by converting the values of the parameters in the procedure call to textual representations. The behavior of WRITEV is analogous to that of the WRITELN function; the character-string parameter is analogous to a one-line file. Syntax: WRITEV( str, parameter-list [[,ERROR := error-recovery]] ) The parameter 'str' cannot appear within the parameter-list; if you attempt to do this, unexpected results may occur. An error occurs if WRITEV reaches the maximum length of the character string before the values of all the parameters in the procedure call have been written into the string. The parameter 'error-recovery' indicates the action to be taken if an error occurs while the WRITEV procedure is executing. 3 Dyn_Alloc VSI Pascal provides dynamic allocation routines for the creation and use of pointer variables. Use pointer variables and dynamic allocation routines to create linked data structures. 4 ADDRESS The ADDRESS function returns a pointer value that is the address of the parameter. Syntax: ADDRESS( x ) The parameter 'x' can be a variable of any type except a component of a packed structured type. A compile-time warning results if 'x' is a formal VAR parameter, a component of a formal VAR parameter, or a variable that does not have the READONLY or VOLATILE attribute. A pointer can only refer to a VOLATILE variable or a variable allocated by the NEW procedure. 4 DISPOSE The DISPOSE procedure deallocates memory for a dynamic variable. Syntax: DISPOSE( p ) The parameter 'p' is a pointer variable. The 't' parameters are constant expressions that match the corresponding 't' parameter used in the call to the NEW procedure that allocated the memory. If you use 't' parameters in a call to NEW, you must specify the same 't' parameters in the call to DISPOSE. If you allocated memory using d parameters, just specify the pointer variable to the corresponding DISPOSE call. The DISPOSE procedure deallocates the object to which the pointer variable points. You cannot call DISPOSE more than once for the same dynamic variable. 4 IADDRESS The IADDRESS function returns an INTEGER_ADDRESS value that refers to a the address of either a VOLATILE parameter or a routine, and does not generate compile-time warnings (as does the ADDRESS function). The IADDRESS function is commonly used for constructing arguments for system services of the OpenVMS operating system. Syntax: IADDRESS( x ) The parameter 'x' can be of any type except a component of a packed structured type or a routine name. The parameter 'x' can be a variable, parameter, routine, or constant-expression. When IADDRESS is used on constant-expressions, the returned address is valid for the remainder of the program. Two calls to IADDRESS with the same constant may not return the same address. Note that the VSI Pascal compiler automatically assumes that all pointers refer either to dynamic variables allocated by the NEW procedure or to variables that have the VOLATILE attribute; therefore, you should use utmost caution when using the IADDRESS function. This function does not generate compile-time warnings. 4 IADDRESS64 The IADDRESS64 function is essentially identical to the IADDRESS function with the exception that IADDRESS64 returns an INTEGER64 result. This does not force the parameter of IADDRESS64 into 64-bit address space but simply returns the address of the parameter as an INTEGER64 value. Syntax: IADDRESS64( x ) The parameter 'x' can be of any type except a component of a packed structured type or a routine name. The parameter 'x' can be a variable, parameter, routine, or constant-expression. When IADDRESS is used on constant-expressions, the returned address is valid for the remainder of the program. Two calls to IADDRESS64 with the same constant may not return the same address. Note that the VSI Pascal compiler automatically assumes that all pointers refer either to dynamic variables allocated by the NEW procedure or to variables that have the VOLATILE attribute; therefore, you should use utmost caution when using the IADDRESS function. This function does not generate compile-time warnings. 4 NEW The NEW procedure allocates memory for the dynamic variable to which a pointer variable refers. The value of the newly allocated variable is set to the initial value of the base type if defined; otherwise, the value of the variable is undefined. Syntax: NEW( p [[, {t1,...,tn | d1,...,dn} ]] ) The parameter 'p' is a 32-bit pointer variable. On OpenVMS Alpha and OpenVMS I64, the parameter 'p' may also be a 64-bit pointer variable. The parameters 't1,...,tn' are constant expressions of an ordinal type that represent nested tag-field values, where 't1' is the outermost variant. If the object of the pointer is a non-schema record type with variants, then you have two ways of allocating memory. If you do not specify 't' parameters, VSI Pascal allocates enough memory to hold any of the variants of the record. If you do specify 't' parameters, then VSI Pascal allocates enough memory to hold only the variant or variants that you specify. Since the 't' parameters cause VSI Pascal to allocate memory for the variant alone and not for the whole record, you cannot assign or evaluate the record as a whole; you can assign and evaluate only the individual fields. Also, a call to NEW does not set the tag fields of a variant record. The paramters 'd1,...,dn' are compile-time or run-time ordinal values that must be the same type as the formal discriminants of the object. If the object of the pointer is of an undiscriminated schema type, you must specify a 'd' parameter for each of the formal discriminants of the schema type. The 'd' parameters discriminate the schema type in much the same way as actual discriminants in a discriminated schema. HP Pascal bases the size of the allocation on the value of the 'd' parameters. If the object is a schema record type, then you must use 'd' parameters; you cannot use 't' parameters or a combination of the syntaxes. If the schema record type contains a variant (which depends on one of the formal discriminants) then the 'd' parameter discriminates the schema, determines the variant, and allows VSI Pascal to compute the necessary size of the allocation. Note that if you specify 't' parameters to the NEW procedure, you must specify the same 't' parameters to the DISPOSE procedure that deallocates memory for the corresponding variable. If the parameter 'p' is a 64-bit pointer variable, the NEW procedure will call LIB$GET_VM_64 to allocate memory from "P2" space. Likewise, DISPOSE of a 64-bit pointer expression will call LIB$FREE_VM_64 to return the memory. 3 Low_Level The low-level routines allow for parallel processes and asynchronous routines to operate in a real-time or multi-tasking environment. 4 ADD_ATOMIC The ADD_ATOMIC function adds the value of an expression to the value of a variable, stores the newly computed value, and returns the previous value. Syntax: ADD_ATOMIC(e,v) The type of the expression 'e' must be assignment compatbile with that of the variable 'v'. The variable 'v' must be an INTEGER, UNSIGNED, INTEGER64, or UNSIGNED64 variable and must be allocated on a natural boundary (ie, longword for INTEGER and UNSIGNED and quadword for INTEGER64 and UNSIGNED64). The result of ADD_ATOMIC is the same type as the variable 'v'. Overflow and subrange checking are never performed on the ADD_ATOMIC operation, even if these options are in effect for the rest of the function or compilation unit. 4 ADD_INTERLOCKED The ADD_INTERLOCKED function adds the value of an expression to the value of a variable, stores the newly computed value in the variable, and returns an integer value: -1 if the new value is negative, 0 if it is zero, and 1 if it is positive. Syntax: ADD_INTERLOCKED( e, v ) The type of the expression 'e' must be assignment compatible with that of the variable 'v'. The variable 'v' must be an integer or an unsigned subrange; 'v' must have an allocation size of two bytes and must be aligned on a word boundary. The type of 'e' must be assignment compatible with that of 'v'. 4 AND_ATOMIC The AND_ATOMIC function logically ANDs the value of an expression to the value of a variable, stores the newly computed value, and returns the previous value. Syntax: AND_ATOMIC(e,v) The type of the expression 'e' must be assignment compatbile with that of the variable 'v'. The variable v must be an INTEGER, UNSIGNED, INTEGER64, or UNSIGNED64 variable and must be allocated on a natural boundary (ie, longword for INTEGER and UNSIGNED and quadword for INTEGER64 and UNSIGNED64). The result of AND_ATOMIC is the same type as the variable 'v'. 4 BARRIER The BARRIER procedure causes a memory barrier instruction to be emitted to synchronize pending memory updates in a multi-processor environment. Syntax: BARRIER The BARRIER procedure has no parameters. 4 CLEAR_INTERLOCKED The CLEAR_INTERLOCKED function assigns the value FALSE to the parameter and returns the original Boolean value of the parameter. Syntax: CLEAR_INTERLOCKED( b ) The variable 'b' must be a variable of type Boolean. The variable does not have to be aligned; therefore, it can be a field of a packed record. 4 OR_ATOMIC The OR_ATOMIC function logically ORs the value of an expression to the value of a variable, stores the newly computed value, and returns the previous value. Syntax: OR_ATOMIC(e,v) The type of the expression 'e' must be assignment compatbile with that of the variable 'v'. The variable v must be an INTEGER, UNSIGNED, INTEGER64, or UNSIGNED64 variable and must be allocated on a natural boundary (ie, longword for INTEGER and UNSIGNED and quadword for INTEGER64 and UNSIGNED64). The result of OR_ATOMIC is the same type as the variable 'v'. 4 SET_INTERLOCKED The SET_INTERLOCKED function assigns the value TRUE to the parameter and returns its original Boolean value. Syntax: SET_INTERLOCKED( b ) The variable 'b' must be a variable of type Boolean. The variable does not have to be aligned; therefore, it can be a field of a packed record. 3 Ordinal Ordinal routines provide information on the ordered sequence of values. 4 LOWER This function returns the lower bound for ordinal types, SET base types, and array indexes. Syntax: LOWER( x [[, n]] ) The parameter 'x' is a type identifier or variable of an ordinal, SET, or ARRAY type. The parameter 'n' is an integer constant that denotes a dimension of 'x', if 'x' is an array. If 'x' is an array and if you omit the 'n', VSI Pascal uses the default value 1. If 'x' is an array, LOWER returns the lower bound of the nth dimension of 'x'. If 'x' is an ordinal type, LOWER returns the lower bound or smallest value. If 'x' is a SET, LOWER returns the lower bound of the SET base type. 4 PRED The PRED function returns the value preceding the parameter according to the parameter's data type. Syntax: PRED( x ) The parameter 'x' can be of any ordinal type; however, there must be a predecessor value for 'x' in the type. 4 SUCC The SUCC function returns the value that succeeds the parameter according to the parameter's data type. Syntax: SUCC( x ) The parameter 'x' can be of any ordinal type; however, there must be a successor value for 'x' in the type. 4 UPPER The UPPER function returns the upper bound for ordinal types, SET base types, and array indexes. Syntax: UPPER( x [[, n]] ) The parameter 'x' is a type identifier or variable of an ordinal, SET, or ARRAY type. The parameter 'n' is an integer constant that denotes a dimension of 'x', if 'x' is an array. If 'x' is an array and if you omit the 'n', VSI Pascal uses the default value 1. If 'x' is an array, UPPER returns the upper bound of the nth dimension of 'x'. If 'x' is an ordinal type, UPPER returns the upper bound or largest value. If 'x' is a SET, UPPER returns the upper bound of the SET base type. 3 Null_String VSI Pascal provides routines for manipulating null-terminated strings. These routines use the predeclared type C_STR_T as a pointer to a null-terminated character string. The compiler assumes that buffers are large enough to hold their values and null-terminated strings are actually terminated by a null character. 4 C_STR The C_STR function takes a compile-time string expression and returns a C_STR_T pointer to a static string literal with a terminating null character. Syntax: C_STR(e) The C_STR function can also accept a Pascal variable of either PACKED ARRAY OF CHAR, VARYING OF CHAR, or STRING. Syntax: C_STR(v) In this form, it will return a C_STR_T value that represents the first character in the string variable. It does not ensure a terminating null byte. The programmer must handle the null-termination to treat a Pascal string variable as a null-terminated string. 4 MALLOC_C_STR The MALLOC_C_STR function takes a Pascal string expression, calls the C routine malloc() to allocate memory, initializes the memory with the string expression, and then terminates the string with a null-charcter. Syntax: MALLOC_C_STR(e) The type of the expression e must be a Pascal string expression. The function result is a C_STR_T pointer to the null-terminted string. The amount of memory allocated with malloc() is equal to the length of the string expression plus one. The memory allocated with MALLOC_C_STR must be deallocated with the C free() routine. The compiler will not allow C_STR_T parameters with the NEW and DISPOSE routines. 4 PAS_STR The PAS_STR function returns a Pascal string value from a C_STR_T value. Syntax: PAS_STR(e) The type of the expression e must be C_STR_T. It is an error if the expression is NIL. 4 PAS_STRCPY The PAS_STRCPY function copies a Pascal string expression into memory pointed to by C_STR_T. Syntax: PAS_STRCPY(v, e) The type of the variable v must be C_STR_T. The type of the expression e must be a Pascal string expression. The Pascal string is copied into the memory pointed to by the variable v. The memory is then terminated with a null character. The function returns a C_STR_T value representing the destination (such as, the same value as contained by the variable v). The behavior of PAS_STRCPY is undefined if the length of the Pascal string expression is greater than or equal to the amount of memory pointed to by the variable v. It is an error if the variable v is NIL. 3 Parameter VSI Pascal provides routines that give information about variable-length parameter lists. 4 ARGUMENT The ARGUMENT function specifies an argument in a variable-length parameter list that was created using the LIST attribute. Syntax: ARGUMENT( parameter-name, n ) The 'parameter-name' argument specifies the name of a parameter declared with the LIST attribute. The 'n' specifies a positive integer value that identifies the argument. The first argument in a list is always 1. An error occurs if the value supplied for 'n' is less than 1, or exceeds the ARGUMENT_LIST_LENGTH parameter (which indicates the total number of arguments). If the LIST parameter is a value parameter, ARGUMENT indicates the corresponding value in the argument list. If the LIST parameter is a VAR parameter, ARGUMENT is a reference to the corresponding variable in the argument list. 4 ARGUMENT_LIST_LENGTH The ARGUMENT_LIST_LENGTH function returns an integer value representing the number of arguments in a variable-length parameter list that was created using the LIST attribute. Syntax: ARGUMENT_LIST_LENGTH( parameter-name ) The 'parameter-name' argument specifies the name of the parameter declared with the LIST attribute. When creating a variable-length parameter list, you can place the LIST attribute on only the last formal parameter. When you call the routine, you can specify any number of actual parameters, or arguments, that correspond to the last formal parameter declared with LIST. 4 PRESENT The PRESENT function returns a Boolean value that indicates whether the actual argument list of a routine contains an argument that corresponds to a formal parameter. (The PRESENT function is usually used to supply a default value or to take a default action when the argument for a parameter is omitted.) Syntax: PRESENT (parameter-name) The 'parameter-name' parameter is the name of a formal parameter with the TRUNCATE attribute. The 'parameter-name' must be the name of a formal parameter of the function from which PRESENT is called, or from a subroutine of that function. The function result indicates whether the argument list of the containing routine specifies an actual argument corresponding to an optional parameter. Parameters that do not have the TRUNCATE attribute and also do not follow a parameter with the TRUNCATE attribute in the formal parameter list, are allowed; in their case, the PRESENT function always returns TRUE. Default parameters are considered to be present in the argument list, and the PRESENT function returns TRUE when passed the name of a parameter with a default value. 3 Transfer Transfer routines convert an actual parameter to data of another type. 4 CHR The CHR function returns a char value whose ordinal value in the ASCII character set is the parameter, provided such a character exists. Syntax: CHR( x ) The parameter 'x' must be integer or unsigned and have a value from 0 to 255. 4 DBLE The DBLE function converts the parameter and returns its DOUBLE equivalent. Syntax: DBLE( x ) The parameter 'x' must be of an arithmetic type. The value of 'x' must not be too large to be represented by a double-precision number. 4 INT64 The INT64 function converts the parameter and returns its INTEGER64 equivalent. Syntax: INT64(x) Overflow can occur and is detected at runtime if overflow checking is enabled and the value of 'x' is outside the range of INTEGER64. 4 INT The INT function converts the parameter and returns its INTEGER equivalent. Syntax: INT(x) Overflow can occur and is detected at runtime if overflow checking is enabled and the value of 'x' is outside the range of INTEGER. 4 ORD The ORD function returns an integer value that is the position of the parameter in the ordered sequence of values of the parameter's type. Syntax: ORD( x ) The parameter 'x' must be of an ordinal type. Note that the ordinal value of an INTEGER object is the integer itself. If 'x' is of type UNSIGNED, its value must not be greater than MAXINT. 4 PACK The PACK procedure copies components of an unpacked array variable to a packed array variable. Syntax: PACK( a,i,z ) The parameter 'a' is an unpacked array. The parameter 'i' is a value to indicate the starting value of the index of 'a'. The parameter 'z' is a packed array of the same component type as 'a'. The number of components in parameter a must be greater than or equal to the number of components in 'z'. The PACK procedure assigns the components of 'a', starting with a[i], to the array 'z', starting with z[lower bound], until all the components in 'z' are filled. In general, when specifying 'i', keep in mind that the upper bound of a (that is, n) must be greater than or equal to i + v - u, where 'v' is the upper bound of 'z' and 'u' is the lower bound of 'z'. That is, ORD(n) must be greater than or equal to ORD(i) + ORD(v) - ORD(u). 4 QUAD The QUAD function converts the parameter and returns its QUADRUPLE equivalent. Syntax: QUAD( x ) The parameter 'x' must be of an arithmetic type. 4 ROUND The ROUND function converts the value of the parameter by rounding the fractional part of the value, and returns its integer equivalent. Syntax: ROUND( x ) The parameter 'x' must be of type REAL, SINGLE, DOUBLE, or QUADRUPLE. The value of 'x' must not be too large to be represented by an integer. 4 SNGL The SNGL function converts the parameter and returns its real equivalent. Syntax: SNGL( x ) The parameter 'x' must be of an arithmetic type. The value of 'x' must not be too large to be represented by a single-precision number. 4 TRUNC The TRUNC function converts the value of the parameter by truncating the fractional part of the value and returns its integer equivalent. Syntax: TRUNC( x ) The parameter 'x' must be of type REAL, SINGLE, DOUBLE, or QUADRUPLE. The value of 'x' must not be too large to be represented by an integer. 4 UINT The UINT function converts the value of the parameter and returns its unsigned equivalent. Syntax: UINT( x ) The parameter 'x' must be of an ordinal type. No error results if 'x' is an integer and has a negative value. The value returned is x MOD 2**32. 4 UINT64 The UINT64 function converts the value of the parameter and return its UNSIGNED64 equivalent. Syntax: UINT64(x) The parameter 'x' must be of an ordinal type. No error results if 'x' is an integer and has a negative value. The value returned is x MOD 2**64. 4 UNPACK The UNPACK procedure copies components of a packed array to an unpacked array variable. Syntax: UNPACK( z,a,i ) The parameter 'z' is a packed array. The parameter 'a' is an unpacked array variable. The parameter 'i' is the starting value of the index of 'a'. The number of components in 'a' must be greater than or equal to the number of components in 'z'. The UNPACK procedure assigns the components of 'z', starting with z[lower bound], to the array 'a', starting with a[i], until all the components in 'z' are used. In general, when specifying 'i', keep in mind that the upper bound of 'a' (that is, n) must be greater than or equal to i + v - u, where 'v' is the upper bound of 'a' and 'u' is the lower bound of 'a'. That is, ORD(n) must be greater than or equal to ORD(i) + ORD(v) - ORD(u). Normally, you cannot pass the individual components of a packed array to formal VAR parameters; you must unpack the array first. 4 UROUND The UROUND function converts the value of the parameter and returns its unsigned equivalent by rounding the fractional part of the value. Syntax: UROUND( x ) The parameter 'x' must be of type REAL, SINGLE, DOUBLE, or QUADRUPLE. No error results if the value of 'x' is negative or greater than 4,294,967,295. In that case, the unsigned result is the rounded parameter value MOD 4,294,967,296. 4 UTRUNC The UTRUNC function converts the parameter and returns its unsigned equivalent by truncating the fractional part of the value. Syntax: UTRUNC( x ) The parameter 'x' must be of type REAL, SINGLE, DOUBLE, or QUADRUPLE. No error results if the value of 'x' is negative or greater than 4,294,967,295. In that case, the unsigned result is the truncated parameter value MOD 4,294,967,296. 3 Privileged Privileged routines manipulate privileged hardware registers. 4 MFPR The MFPR function returns an unsigned value that is the value of a VAX internal processor register. Syntax: MFPR( ipr_register_expression ) The 'ipr_register_expression' parameter is an expression compatible with the UNSIGNED type. The HP Pascal compiler generates user-mode code. HP Pascal does not explicitly support the running of VSI Pascal generated code in kernel mode. However, if the following rules are observed, then the generated code has a good chance of working as expected in elevated access modes: o All code must be compiled with the /NOCHECK qualifier or [CHECK(NONE)] attribute. The HP Pascal on OpenVMS VAX run-time signaling method relies on trying to execute the HALT instruction. In user-mode, this causes an exception that is a signal to the HP Pascal run-time library. In kernel-mode on an OpenVMS VAX system, this simply HALTs the machine. o Avoid all routine calls which translate into Run-Time Library calls. These include all I/O routines, several arithmetic routines, several string routines, etc. 4 MTPR The MTPR procedure assigns a value into a VAX internal processor register. Syntax: MTPR( ipr_register_expression, source_expression ); The 'ipr_register_expression' and 'source_expression' parameters are expressions compatible with the unsigned type. HP Pascal stores the value specified by 'source-expression' into the internal processor register specified by 'ipr-register-expression'. The HP Pascal compiler generates user-mode code. HP Pascal does not explicitly support the running of HP Pascal generated code in kernel mode. However, if the following rules are observed, then the generated code has a good chance of working as expected in elevated access modes: o All code must be compiled with the /NOCHECK qualifier or [CHECK(NONE)] attribute. The HP Pascal for OpenVMS VAX systems run-time signaling method relies on trying to execute the HALT instruction. In user-mode, this causes an exception which is a signal to the HP Pascal run-time library. In kernel-mode on an OpenVMS VAX system, this simply HALTs the machine. o Avoid all routine calls which translate into Run-Time Library calls. These include all I/O routines, several arithmetic routines, several string routines, etc. 3 Misc The miscellaneous routines include routines that determine the amount of time a process uses, routines that record the system date and time, routines that control error handling of a program, and routines that perform miscellaneous calculations. 4 ASSERT The ASSERT procedure signals a run-time error if the value of its parameter is FALSE. Syntax: ASSERT(expression [[, string]]) The 'expression' is a Boolean expression that is normally true. If ASSERT evaluates the expression as false, it signals a run-time error, indicating that the assertion failed. The optional string parameter is output as part of the error message. 4 CARD The CARD function returns an integer value indicating the number of components that are currently elements of the set expression. Syntax: CARD( s ) The parameter 's' must be a set expression. 4 CLOCK The CLOCK function returns an integer value indicating the amount of central processor time, in milliseconds, used by the current process. This function does not have a parameter list. The result of CLOCK includes the amount of central processor time allocated to all previously executed images. 4 CREATE_DIRECTORY The CREATE_DIRECTORY procedure creates a new directory or subdirectory. Syntax: CREATE_DIRECTORY( file_name [, error_return] ) The 'file_name' parameter must be a directory name and optionally can contain a device name. The 'error_return' parameter is optional, and will return an error recovery code if specified. 4 STANDARD_DATE_AND_TIME These functions provide a standard way of returning a character-string value that indicates the calender date and time. The return value is compatible with all string types. Syntax: DATE( t ) TIME( t ) The parameter 't' is a variable of the predeclared type TIMESTAMP. You can either call the GETTIMESTAMP procedure to initialize 't' before you pass 't' to either DATE or TIME, or you can construct your own TIMESTAMP object. The size of the function's return value depends on the string length that is normally returned by your system for either date or time data. Example: VAR Time_Var : TIMESTAMP; The_Time, The_Date : STRING(23); {In the executable section:} GETTIMESTAMP( Time_Var ); The_Date := DATE( Time_Var ); The_Time := TIME( Time_Var ); WRITELN( The_Date, The_Time ); {Writes: 1-FEB-1989 14:20:25.98 } 4 NONSTANDARD_DATE_AND_TIME These procedures write the date and the time to their parameters. These procedures are VSI Pascal extensions, and have the forms: DATE( str ) TIME( str ) The parameter 'str' must be of type PACKED ARRAY[1..11] OF CHAR. After execution of the procedure, the 'str' contains either the date or the time. If the day of the month is a 1-digit number, the leading zero does not appear in the result; that is, a space appears before the date string. The time is returned in 24-hour format. 4 DELETE_FILE The DELETE_FILE procedure deletes one or more files. Syntax: DELETE_FILE( file_name [, error_return] ) The 'file-name' specification can contain an explicit device and directory name, plus it must contain a file name, a file type or extension, and a version number. If you omit either the directory or device name, VSI Pascal uses the directory you are working in at the time of program execution. The 'error_return' parameter returns an error recovery code if specified. 4 ESTABLISH The ESTABLISH procedure specifies a condition handler that executes if your program generates operating-system events. Syntax: ESTABLISH( function-identifier ) The 'function-identifier' parameter must be the name of a function that has the ASYNCHRONOUS attribute. The function passed to ESTABLISH must have two formal array parameters. 4 EXPO The EXPO function returns the integer exponent of the floating-point representation of its parameter. Syntax: EXPO( x ) The parameter 'x' can be of any real type. 4 FIND_FIRST_BIT_CLEAR The FIND_FIRST_BIT_CLEAR function locates the first bit in a Boolean array whose value is 0 and returns an integer value that specifies the index into the array. Syntax: FIND_FIRST_BIT_CLEAR( vector [[, start_index]] ) The 'vector' parameter is a variable of type PACKED ARRAY OF BOOLEAN with an INTEGER index type. The optional 'start-index' parameter must be an INTEGER expression that indexes the element at the point at which the search starts. The 'starting index' must be greater than or equal to the vector's lower bound, and less than or equal to 1 plus the vector's upper bound; otherwise, a range violation occurs. If omitted, the starting index defaults to the vector's first element. The FIND_FIRST_BIT_CLEAR function returns a value indexing the first element containing the value 0. If no bit is 0, the result is 1 plus the vector's upper bound. If the vector or the indexed part of the vector has a size of 0, the result is start-index. 4 FIND_FIRST_BIT_SET The FIND_FIRST_BIT_SET function locates the first bit in a Boolean array whose value is 1 and returns an integer value that specifies the index into the array. Syntax: FIND_FIRST_BIT_SET( vector [[, start_index]] ) The 'vector' parameter is a variable of type PACKED ARRAY OF BOOLEAN with an INTEGER index type. The optional 'start-index' parameter must be an expression of an integer type that indexes the element at the point at which the search starts. The 'starting index' must be greater than or equal to the vector's lower bound, and less than or equal to 1 plus the vector's upper bound; otherwise, a range violation occurs. If omitted, the starting index defaults to the vector's first element. The FIND_FIRST_BIT_SET function returns an integer value indexing the first element containing the value 1. If no bit is 1, the result is 1 plus the vector's upper bound. If the vector or the indexed part of the vector has a size of 0, the result is start-index. 4 GETTIMESTAMP The GETTIMESTAMP procedure initializes its parameter for use with the DATE and TIME functions. Syntax: GETTIMESTAMP( t [[, str]] ) The parameter 't' is a variable of the TIMESTAMP type, which is a predeclared record type. The TIMESTAMP data type is as follows: TIMESTAMP = PACKED RECORD Datevalid, Timevalid : BOOLEAN; Year : INTEGER; Month : 1..12; Day : 1..31; Hour : 0..23; Minute : 0..59; Second : 0..59; Hundredth : 0..99; {64-bit OpenVMS binary time:} BINARY_TIME : [QUAD] RECORD L1,L2 : INTEGER END; DAY_OF_WEEK : 1..7; {1 is Monday, 7 is Sunday} END; The parameter 'str' is a string type that represents a date or both a date and time. The following rules apply to the specification of the 'str' parameter: o If you do not specify the 'str', the GETTIMESTAMP procedure initializes the variable to be the date and time at execution of your program. o If you specify an invalid date, the GETTIMESTAMP procedure sets the date to be January 1, 1; if you specify an invalid time, it sets the time to be midnight. 4 HALT The HALT procedure uses operating system resources to stop execution of your program unless you have written a condition handler (using the ESTABLISH procedure) that enables continued execution. 4 IN_RANGE The IN_RANGE function determines whether a value is in the defined subrange. Syntax: IN_RANGE(expression,lower-expression,upper-expression) This function returns TRUE if the contents of the variable is in the range specified by the lower-expression and upper-expression values. 4 ODD The ODD function returns a Boolean value that indicates if the parameter is odd. Syntax: ODD( x ) The parameter 'x' must be of type INTEGER or UNSIGNED. The function returns TRUE if the value of 'x' is odd and FALSE if the value of 'x' is even. 4 RANDOM The RANDOM function returns a randomly computed real value in the range [0.0,1.0). RANDOM[[(expression)]] If present, the optional integer parameter is ignored. 4 RENAME_FILE The RENAME_FILE procedure renames a file. Syntax: RENAME_FILE( old-file-name, new-file-name [, error-return] ) The parameter 'old-file-name' specifies the names of one or more files whose specifications are to be changed. The parameter 'new-file-name' provides the new file specification to be applied. The 'error-return' parameter contains an error recovery code if specified. 4 REVERT The REVERT procedure cancels a condition handler activated by the ESTABLISH procedure. This procedure does not have a parameter list. 4 SEED The SEED function has a single integer parameter that sets the random number generator seed for the RANDOM function. The function returns an integer that represents the previous seed value. SEED(expression) The parameter is of type integer. 4 SYSCLOCK The SYSCLOCK function returns an integer value for the number of milliseconds of system time used by the current process. On OpenVMS systems, the result is the same as that returned by the CLOCK function. Syntax: SYSCLOCK 4 UNDEFINED The UNDEFINED function returns a Boolean value that specifies whether the parameter contains a reserved operand. Syntax: UNDEFINED( x ) The parameter 'x' must be a variable of type REAL, SINGLE, DOUBLE, or QUADRUPLE. The function returns TRUE if 'x' contains a value that has been reserved by the system or machine architecture. If 'x' does not contain a reserved value, the function returns FALSE. If 'x' contains a reserved operand and if you attempt to use 'x' in arithmetic computations, an error occurs. 4 WALLCLOCK On OpenVMS systems, the WALLCLOCK function returns an integer value representing the number of seconds since the boot time for the system. Syntax: WALLCLOCK 4 ZERO The ZERO function returns data, whose type depends on the context of the function call, that sets any variable (except a file variable) to its binary zero. If you attempt to use the ZERO function to initialize a file variable, an error occurs. Do not specify a parameter list when you call the ZERO function. 2 Input_Output The VSI Pascal I/O model provides an extensive set of predeclared routines. These routines allow you to establish files with sequential, relative, or indexed organization and process them by sequential, direct, or keyed access. 3 General 4 OPEN The OPEN procedure opens a file and allows you to specify file characteristics. Syntax: OPEN( file_variable ,[[file_name]] ,[[history]] ,[[record_length]] ,[[access_method]] ,[[record_type]] ,[[carriage_control]] ,[[organization]] ,[[disposition]] ,[[file_sharing]] ,[[user_action]] ,[[default_file_name]] ,[[ERROR := error_recovery]] ) OPEN( FILE_VARIABLE := file_variable [[,FILE_NAME := file_name]] [[,HISTORY := history]] [[,RECORD_LENGTH := record_length]] [[,ACCESS_METHOD := access_method]] [[,RECORD_TYPE := record_type]] [[,CARRIAGE_CONTROL := carriage_control]] [[,ORGANIZATION := organization]] [[,DISPOSITION := disposition]] [[,SHARING := file_sharing]] [[,USER_ACTION := user_action]] [[,DEFAULT := default_file_name]] [[,ERROR := error_recovery]] ) Before the OPEN procedure is called, the file is in undefined mode; its mode does not change after OPEN has been executed. You cannot use OPEN on a file variable that is already open. If you use INPUT or OUTPUT, VSI Pascal implicitly opens them just before their first use. VSI Pascal implicitly opens INPUT with a history of READONLY. If you choose, you can explicitly open INPUT or OUTPUT; to do this, call the OPEN procedure at any point in your compilation unit before you use the first I/O routine on that file. Because the RESET, REWRITE, and EXTEND procedures implicitly open files, you need not always use the OPEN procedure. RESET, REWRITE, and EXTEND impose the same defaults as OPEN, except where noted (in the HISTORY parameter). You must use the OPEN procedure to create a TEXT file with fixed-length components, to create a file with relative or indexed organization, to open a file for direct or keyed access, or to specify a line length other than the default for a line in a TEXT file. See the "HP Pascal Language Reference Manual" for the complete description of the OPEN procedure. 5 File_Variable The 'file_variable' is the only required parameter. It is the name of the file variable associated with the file that HP Pascal is to open. 5 File_Name The 'file_name' is a character-string expression containing the external file name. VSI Pascal determines the default file name according to the environment in which you are programming. 5 History The 'history' is a value that indicates whether the file exists or if VSI Pascal must create the file. If you specify OLD and if VSI Pascal cannot find the file, an error occurs. If you specify READONLY, you can only read from the file; if you attempt to write to the file, an error occurs. If you specify UNKNOWN, VSI Pascal looks for an existing file but creates a new file if there is no existing file. If you specify OLD or UNKNOWN and if the attempt to open the file generates a file protection error, VSI Pascal tries again using READONLY. NEW is the default for OPEN/REWRITE openings, while OLD is the default for EXTEND/RESET openings. 5 Record_Length The 'record-length' is a positive integer that specifies the maximum size in bytes for a line in a TEXT file or a file of type FILE OF VARYING. ("Record" length is equivalent to "component" length.) The default is 255 bytes. For all other types of files, VSI Pascal ignores this parameter. If you do not specify a length for an existing file, VSI Pascal uses the length specified at the file's creation. If you use OPEN to create a sequentially organized file with variable-length components, VSI Pascal records the maximum length of each component in the file only if you specify a value for the record_type field. 5 Access_Method The 'access_method' is a value that specifies the component access method to use. The possible values include SEQUENTIAL, DIRECT, and KEYED. The DIRECT access method is equivalent to random access by relative component number. The KEYED access method is equivalent to random access by key. The default is SEQUENTIAL. 5 Record_Type The 'record_type' is a value that indicates the component format. ("Record" format and "component" format are equivalent.) The available values are FIXED (fixed-length components), VARIABLE (variable-length components), STREAM (stream component format with either carriage return, combination carriage return and line feed, or form feed delimiters), STREAM_CR (stream component format with carriage return delimiters), and STREAM_LF (stream component format with line feed delimiters). VARIABLE is the default for new TEXT and VARYING OF CHAR, while FIXED is the default for other new files. 5 Carriage_Control The 'carriage_control' is a value that indicates the carriage control format for the file. The value LIST indicates single spacing between components. The values CARRIAGE and FORTRAN are equivalent and indicate that the first character of every output line is a carriage control character. The values NONE and NOCARRIAGE indicate that the file has no carriage control. LIST id the default for TEXT and VARYING OF CHAR files, while NONE is the default for all other file types. 5 Organization The 'organization' is a value that specifies the file organization. If you are accessing an existing file, the specified organization must match the organization of the existing file; if it does not, an error occurs. The choices for this parameter are SEQUENTIAL, RELATIVE, and INDEXED. The default is SEQUENTIAL. The parameter choices are as follows: o SEQUENTIAL file organization specifies that file components are stored one after the other, in the order in which they were entered into the file. VSI Pascal supports this organization for files on disk. This is the only organization supported for files on magnetic tape, on terminals, on card readers, and on line printers. o RELATIVE file organization consists of a series of fixed-length component positions (cells) numbered consecutively from 1 to n. The numbered, fixed-length cells enable VSI Pascal to calculate the component's physical position in the file. The cell numbers are called relative component numbers. VSI Pascal supports this organization on disk files only. o INDEXED file organization specifies that, in addition to the stored components, there exists at least a primary key and possibly alternate keys (first alternate key, second alternate key, and so forth). VSI Pascal uses the primary key to store components and uses a program-specified key or keys to retrieve data. VSI Pascal supports this organization on disk files only. 5 Disposition The 'disposition' is a value that indicates what VSI Pascal should do with the file after you close the file. If SAVE is specified, the file is retained. If DELETE is specified, the file is deleted. If PRINT is specified, the file is printed on a line printer and is retained. If PRINT_DELETE is specified, the file is deleted after it is printed. If SUBMIT is specified, the file is submitted to a queue or placed in a background process and is retained. If SUBMIT_DELETE is specified, the file is deleted after being processed. SAVE is the default for external files. DELETE is the default for internal files. 5 Sharing The 'sharing' is a value that specifies whether other programs can access the file while it is open. A value of READONLY indicates that other programs can read but not write to the file. This is the default value for files with HISTORY := READONLY. READWRITE indicates that other programs can read and write to the file when it is open. A value of NONE denies any access to the file while it is open. This is the default value for all other histories. 5 User_Action The 'user_action' is the name of a user-written routine that VSI Pascal calls to open the file (instead of allowing VSI Pascal to open the file with the OPEN procedure). You can use a user-action routine to open the file using environment-specific capabilities of the I/O system underlying HP Pascal. 5 Default The 'default' is a string expression containing default file specification information. For instance, you can use this value to set a default directory specification. 5 Error_Recovery The 'error_recovery' specifies the action the program should take if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. 4 CLOSE The CLOSE procedure closes an open file. Syntax: CLOSE( file_variable ,[[disposition]] ,[[user_action]] ,[[ERROR := error_recovery]] ) CLOSE( FILE_VARIABLE := file_variable [[,DISPOSITION := disposition]] [[,USER_ACTION := user_action]] [[,ERROR := error_recovery]] ) Except for the file variable parameter, all other parameters are optional. If the nonpositional parameter names are not used, as in the first syntax, the parameters must be in the order specified. If nonpositional parameter names are used, as in the second syntax, the parameters can be specified in any order. 5 File_Variable The 'file_variable' is the name of the file variable associated with the file that VSI Pascal is to close. 5 Disposition The 'disposition' is a value that indicates what VSI Pascal should do with the file after you close the file. If SAVE is specified, the file is retained. If DELETE is specified, the file is deleted. If PRINT is specified, the file is printed on a line printer and is retained. If PRINT_DELETE is specified, the file is deleted after it is printed. If SUBMIT is specified, the file is submitted to a queue or placed in a background process and is retained. If SUBMIT_DELETE is specified, the file is deleted after being processed. SAVE is the default for external files. DELETE is the default for internal files. The disposition value in the CLOSE procedure supersedes a disposition value in the OPEN procedure. 5 User_Action The 'user_action' is a routine name that VSI Pascal calls to close the file. You can use a user-action routine to close the file using environment-specific capabilities. 5 Error_Recovery The 'error_recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. Execution of the CLOSE procedure causes the system to close the file and, if the file is internal, to delete it. Each file is automatically closed when control passes from the block in which it is declared. You cannot close a file that has not been opened (either explicitly by the OPEN procedure, or implicitly by the EXTEND, RESET, or REWRITE procedure). If you attempt to close a file that was never opened, an error occurs. The file can be in any mode (inspection, generation, or undefined) before the CLOSE procedure is called. Execution of CLOSE sets the mode to undefined. 3 Seq_Access_Input The sequential access input procedures are procedures used on files opened for sequential access, but they can also be used on files opened for direct and keyed access. 4 GET The GET procedure advances the file position and reads the next component of the file into the file buffer variable. If the file has relative or indexed organization, the component is also locked to prevent access by other processes. Syntax: GET( file_variable [[,ERROR := error-recovery]] ); The 'file_variable' is the name associated with the input file. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. Before the GET procedure is used for the first time to read one or more file components, the file must be in inspection mode and prepared for reading input. Depending on the access method specified when the file was opened, you can prepare the file for input in the following ways: o If the file is open for sequential access, call the RESET procedure. RESET sets the mode to inspection, advances the file position to the first component, and assigns the component's value to the file buffer variable. o If the file is open for direct access, call either the RESET or the FIND procedure to position the file. o If the file is open for keyed access, call the FINDK, RESET, or RESETK procedure to position the file. As a result of the GET procedure, the file remains in inspection mode, and the file position advances to the next component. If a component is found other than the end-of-file marker, the component is locked, EOF is set to FALSE, the file buffer variable takes on the value of the component, and UFB is set to FALSE. If a component is not found or the end of the file is reached, EOF and UFB are set to TRUE. If the GET procedure fails, UFB is set to TRUE and EOF becomes undefined. See the "HP Pascal Language Reference Manual" for the complete description of the GET procedure. 4 READ The READ procedure reads one or more file components into a variable. Syntax: READ( [[file_variable,]] {variable-identifier [[:radix-specifier]]},... [[, ERROR := error-recovery]] ); The 'file_variable' is the name associated with the input file. If you omit the name of the file, the default is INPUT. The 'variable-identifier' is the name of the variable into which a file component will be read; multiple identifiers are separated by commas. The 'radix-specifier' is one of the format values BIN, OCT, or HEX. These values, when used on a variable identifier, will read the variable in binary, octal, or hexadecimal radix respectively. You can use a radix specifier only when reading from a TEXT file. The 'error-recovery' is the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in inspection mode before READ is called. The file remains in inspection mode after execution of a READ procedure. By definition, the READ procedure for a nontext file performs an assignment statement, a GET procedure, and an UNLOCK procedure for each variable. The READ procedure reads from the file until it has found a value for each variable in the list. The first value read is assigned to the first variable in the list, the second value read is assigned to the second variable, and so on. The values and the variables must be of assignment-compatible types. Reading stops if an error occurs. For a TEXT file, more than one component (character) can be read into a single variable. For example, many characters can be read into a string or converted into a numeric variable. The READ procedure repeats the assignment, GET, and UNLOCK process until it has read a sequence of characters that represent a legal value for the next variable in the parameter list. The procedure continues to read components from the file until it has assigned a value to each variable in the list. See the "HP Pascal Language Reference Manual" for a complete description of the READ procedure. 4 RESET The RESET procedure readies a file for reading. Syntax: RESET( file_variable [[, file_name]] [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the input file. You do not need this argument if the file was opened with the OPEN procedure. The 'file_name' represents the string expression to be associated with the 'file_variable'. If the file was previously opened with the OPEN procedure, 'file_name' is ignored. The 'error-recovery' represents the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file can be in any mode before you call RESET; a call to RESET sets the file to inspection mode. If the file is an external file and is not already open, RESET opens it using the same defaults as the OPEN procedure. You cannot use RESET to create a file. After execution of RESET, the file is positioned at the first component, and the file buffer variable contains the value of this component. If the file is not empty, EOF and UFB return FALSE and the first component is locked to prevent access by other processes. If the file is empty, EOF and UFB return TRUE. If the file does not exist, RESET does not create it, but returns an error at run time. You should call RESET before reading any file with sequential organization except the predeclared file INPUT. The RESET procedure removes the end-of-file marker from any file connected to a terminal device (including INPUT), thus allowing reading from the file to continue. If you call RESET for the predeclared file OUTPUT, an error occurs. A call to RESET on a relative file opened for direct access positions the file at its first existing component. A call to RESET on an indexed file opened for keyed access positions the file at the first component relative to the primary key. See the "HP Pascal Language Reference Manual" for a complete description of the RESET procedure. 3 Seq_Access_Output The sequential access output procedures apply primarily to files opened for sequential access; but can also be used on direct and keyed access files. 4 EXTEND The EXTEND procedure opens an existing file, positions the file buffer after the last component, and prepares it for writing. It is commonly used to append to a file. Syntax: EXTEND( file_variable [[, file_name]] [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the output file. The 'file_name' is the name of the file to be associated with the 'file_variable'. If the file was opened with the OPEN procedure, the 'file_name' is ignored. The 'error-recovery' is the action to be taken if an error occurs during execution of the routine. The file can be in any mode before EXTEND is called to set the mode to generation. If the file is an external file and is not already open, EXTEND opens it using the defaults for the OPEN procedure. After execution of EXTEND, the file is positioned after the last component, and EOF and UFB return TRUE. If the file does not exist, EXTEND does not create it, but returns an error at run time. A call to EXTEND on a relative file opened for direct access positions the file after its last existing component. A call to EXTEND on an indexed file opened for random access by key positions the file after the last component relative to the primary key. See the "HP Pascal Language Reference Manual" for a complete description of the EXTEND procedure. 4 PUT The PUT procedure adds a new component to a file. Syntax: PUT( file_variable [[, ERROR := error-recovery]] ); The 'file_variable' specifies the name of the file variable associated with the output file. The 'error-recovery' is the action to be taken if an error occurs during execution of the routine. Before executing the first PUT procedure on a file opened for sequential access, you must execute an EXTEND, REWRITE or TRUNCATE procedure to set the file to generation mode. EXTEND, REWRITE and TRUNCATE set EOF to TRUE, thus preparing the file for output. (TRUNCATE is legal only on files with sequential organization.) If the file has indexed organization, the components to be written must be ordered by the primary key. Before executing the first PUT statement on a file opened for direct access, you must execute an EXTEND, REWRITE or LOCATE procedure to position the file. The PUT procedure writes the value of the file buffer variable at the end of the specified sequential-file or direct-access file. You can use LOCATE to position a direct-access file and then use PUT to write the value of the file buffer variable at that position. After execution of the PUT procedure, the value of the file buffer variable becomes undefined (UFB returns TRUE). EOF remains TRUE and the file remains in generation mode. You can call the PUT procedure for a keyed-access file, regardless of the file's mode (inspection, generation, or undefined). PUT causes the file buffer variable to be written to the file at the position indicated by the key. If the component has more than one key, the file buffer variable is inserted in each index at the appropriate location. After execution of PUT, a keyed-access file is in generation mode. See the "HP Pascal Language Reference Manual" for a complete description of the PUT procedure. 4 REWRITE The REWRITE procedure readies a file for output. Syntax: REWRITE( file_variable [[, file_name]] [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the output file. The 'file_name' is a string expression to be associated with the file_variable. Files opened with REWRITE and the 'file_name' stay resident on the disk after the program exits. However, if the file was opened with the OPEN procedure, the 'file_name' is ignored. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file can be in any mode before REWRITE is called to set the mode to generation. If the file variable has not been opened, REWRITE creates and opens it using the same defaults as the OPEN procedure. The REWRITE procedure truncates a file to length zero and sets EOF and UFB to TRUE. You can then write new components into the file with the PUT, WRITE, and WRITELN procedures (WRITELN is defined only for text files). After the file is open, successive calls to REWRITE truncate the existing file to a length of zero; they do not create new versions of the file. To update an existing file with sequential organization, you must either use the EXTEND procedure, use the TRUNCATE procedure, or copy the contents to another file, specifying new values for the components you need to update. When applied to a file with relative or indexed organization, REWRITE deletes the contents of the file and sets the file position to the beginning of an empty file. See the "HP Pascal Language Reference Manual" for a complete description of the REWRITE procedure. 4 WRITE The WRITE procedure assigns data to an output file. Syntax: WRITE( [[file_variable, ]]{expression},... [[,ERROR := error-recovery]] ) The 'file_variable' is the name of the file variable associated with the output file. If you omit the name of the file, the default is OUTPUT. The 'expression' is an expression whose value is to be written; multiple output values must be separated with commas. An output value must have the same type as the file components; however, values written to a TEXT file can also be expressions of any ordinal, real, or string type. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file (unless it is a random-access by key file) must be in generation mode before WRITE is called; it remains in that mode after WRITE has executed. By definition, a WRITE statement to a nontext file performs an assignment to the file buffer variable and a PUT statement for each output value. For nontext files, the types of the output values must be assignment compatible with the component type of the file. See the "HP Pascal Language Reference Manual" for a complete description of the WRITE procedure. 3 Misc The miscellaneous routines are generally used when dealing with sequential access files. In some cases, they can be used on direct or keyed access files. 4 EOF The EOF (end of file) function indicates whether the file pointer is positioned after the last component in a file by returning a Boolean value. Syntax: EOF[[( file_variable )]] The 'file_variable' is the name of the file variable associated with the input file. If you omit the name of the file, the default is INPUT. The file can be in either inspection or generation mode before EOF is called; however, end-of-file must be defined. The input operations GET, RESET, and FINDK are guaranteed to leave end-of-file defined. The file mode does not change after EOF has been executed. EOF returns TRUE when the file pointer is positioned after the last component in the file, and returns FALSE up to and including the time when the last component of the input file is read into the file buffer. You must attempt to retrieve another file component after the last to determine whether the file is positioned at end-of-file. When EOF is tested for a file with relative organization opened for direct access, the result is TRUE if the file is in inspection mode and the last GET or RESET operation positioned the file beyond the last existing component. If the file is in generation or undefined mode, the result of EOF is undefined. When EOF is tested for a file with indexed organization opened for keyed access, the result is TRUE if the file is in inspection mode and the last FINDK, GET, RESET, or RESETK operation positioned the file beyond the last component with the current key number. Successful attempts at FINDK, GET, RESET, and RESETK cause EOF to be FALSE. If the file is not in inspection mode, EOF is undefined. If you attempt to read a file after EOF becomes TRUE, an error occurs. See the "HP Pascal Language Reference Manual" for a complete description of the EOF function. 4 STATUS The STATUS function indicates the status of a file following the last operation performed on it. Syntax: STATUS( file_variable ) The 'file_variable' is the name of the file variable associated with the file to be tested. The file can be in any mode before STATUS is called; unless an error occurs, STATUS does not change the file mode upon execution. The STATUS function returns integer codes indicating the previous operation's effect on the file. If the operation is successful, 0 is returned. If end-of-file is encountered, -1 is returned. If an error is encountered, a positive integer is returned. (The actual number is environmental specific and indicates the exact error that occured.) A test by the STATUS function on a TEXT file causes delayed device access to occur, thus filling the file buffer with the next file component. Therefore, EOF, EOLN, UFB, and STATUS never return an error code following a successful STATUS function call. See the "HP Pascal Language Reference Manual" for a complete description of the STATUS function. 4 TRUNCATE The TRUNCATE procedure indicates that the current file component and all components following it are to be deleted. TRUNCATE can only be used on a file that has sequential organization. Syntax: TRUNCATE( file_variable [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the file to be truncated. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in inspection mode before TRUNCATE is called. After the procedure has been executed, the mode is set to generation so that you can write to the file. After the appropriate components have been deleted, the file remains positioned at the new end-of-file, but the file buffer itself is undefined. Thus, EOF and UFB are both set to TRUE. See the "HP Pascal Language Reference Manual" for a complete description of the TRUNCATE procedure. 4 UFB The UFB (undefined file buffer) function returns a Boolean value that indicates whether the last file operation gave the file buffer an undefined status. Syntax: UFB( file_variable ) The 'file_variable' is the name of the file variable associated with the file whose buffer is being tested. The file can be in any mode before UFB is called; execution of UFB does not change the file mode. UFB tests the effect of the last I/O operation done to the file. UFB returns FALSE if a successful GET, FIND, FINDK, RESET, or RESETK operation has filled the file buffer. GET, FIND, FINDK, RESET, and RESETK procedure calls that do not fill the file buffer set UFB to TRUE. UFB also returns TRUE after DELETE, EXTEND, LOCATE, PUT, REWRITE, TRUNCATE, and UPDATE procedures have left the contents of the file buffer unknown. Assigning a new value to the file buffer with an assignment statement does not change the value of UFB. See the "HP Pascal Language Reference Manual" for a complete description of the UFB function. 4 UNLOCK The UNLOCK procedure releases the current file component for access by other processes. Syntax: UNLOCK( file_variable [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the file whose component is to be unlocked. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in inspection mode before UNLOCK is called; it remains in inspection mode after UNLOCK has executed. If the component at which the file pointer is positioned has been locked, the UNLOCK procedure releases it. 3 Text_File Text file manipulation routines apply only to text files (including INPUT, OUTPUT, and ERR). 4 EOLN The EOLN function tests for the end-of-line marker within a text file and returns a Boolean value. Syntax: EOLN [[( file_variable )]] The 'file_variable' is the name of a file variable associated with a text file. If you omit the name of the file, the default is INPUT. The file must be in inspection mode and EOF must return FALSE before EOLN is called. EOLN leaves the file in inspection mode. The Boolean EOLN function returns TRUE when the file pointer is positioned after the last character in a line. When the EOLN function returns TRUE, the file buffer contains a blank character. The EOLN function returns FALSE when the last component in the line is read into the file buffer. Another character must be read to cause EOLN to return TRUE and to cause the file buffer to be positioned at the end-of-line marker following the last character of the line. If you use the EOLN function on a nontext file, an error occurs. See the "HP Pascal Language Reference Manual" for a complete description of the EOLN function. 4 LINELIMIT The LINELIMIT procedure stops execution of the program after a specified number of lines has been written into a TEXT file. Syntax: LINELIMIT( file_variable, n [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the TEXT file to which the limit applies. The 'n' is a positive integer expression that indicates the number of lines that can be written to the file before execution terminates. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file can be in any mode before LINELIMIT is called; the file mode does not change after LINELIMIT has been executed. VSI Pascal first uses environment-specific means to determine if there is a default line limit. If there is not environment-specific default, there is no default line limit. You can use a call to LINELIMIT to override the default. After the number of lines written into the file has reached the line limit, program execution terminates unless the WRITELN procedure that exceeded the line limit includes the ERROR := CONTINUE parameter. See the "HP Pascal Language Reference Manual" for a complete description of the LINELIMIT procedure. 4 PAGE The PAGE procedure skips from the current page to the next page of a TEXT file. Syntax: PAGE( file_variable [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with a TEXT file. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in generation mode before the PAGE procedure is called; the mode does not change as a result of the procedure's execution. Execution of the PAGE procedure clears the record buffer, if it contains data, by performing a WRITELN procedure, and then advances the output to a new page of the specified TEXT file. The next component written to the file begins on the first line of a new page. You can use this procedure only on TEXT files. If you specify a file of any other type, an error occurs. The value of the page eject component that is output to the file depends on the carriage control format for that file. When CARRIAGE or FORTRAN is enabled, the page eject record is equivalent to the carriage control character '1'. When LIST, NOCARRIAGE, or NONE is enabled, the page eject record is a single form feed character. See the "HP Pascal Language Reference Manual" for a complete description of the PAGE procedure. 4 READLN The READLN procedure reads lines of data from a TEXT file. Syntax: READLN [[( [[file_variable,]] {variable-identifier [[:radix-specifier]]},... [[, ERROR := error-recovery]]) ]]; The 'file_variable' is the name of the file variable associated with the TEXT file to be read. If you omit the name of the file, the default is INPUT. The 'variable-identifier' is the name of the variable into which a file component will be read; multiple identifiers are separated by commas. If you do not specify any variable name, READLN skips a line in the specified file. The 'radix-specifier' is one of the format values BIN, OCT, or HEX. These values, when used on a variable identifier, read the variable in binary, octal, or hexadecimal, respectively. You can use a radix specifier only when reading from a TEXT file. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in inspection mode before READLN is called; it remains in that mode after the procedure's execution. The READLN procedure reads values from a TEXT file. After reading values for all the listed variables, the READLN procedure skips over any characters remaining on the current line and positions the file at the beginning of the next line. The values need not all be on a single line; READLN continues until values have been assigned to all the specified variables, even if this process results in the reading of several lines of the input file. EOLN returns TRUE after a READLN procedure only if the new line is empty. See the "HP Pascal Language Reference Manual" for a complete description of the READLN procedure. 4 WRITELN The WRITELN procedure writes a line of data to a text file. Syntax: WRITELN [[( [[file_variable,]] {expression},... [[, ERROR := error-recovery]] )]] The 'file_variable' is the name of the file variable associated with the text file to be written. If you omit the name of the file, the default is OUTPUT. The 'expression' is an expression whose value is to be written; multiple output values must be separated by commas. The expressions can be of any ordinal, real, or string type and are written with a default field width. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in generation mode before WRITELN is called; it remains in that mode after WRITELN has been executed. The WRITELN procedure writes the specified values into the TEXT file, inserts an end-of-line marker after the end of the current line, and then positions the file at the beginning of the next line. You can specify a carriage-control character as the first item in an output line. When you use carriage-control characters, make sure that the file is open with either the CARRIAGE or FORTRAN option. If you specify a carriage format but use an invalid carriage control character, the first character in the line is ignored. The output appears with the first character truncated. See the "HP Pascal Language Reference Manual" for a complete description of the WRITELN procedure. 3 Direct_Access Direct access procedures are generally legal only on files opened for direct access. In some cases, procedures apply to keyed access files as well. 4 DELETE The DELETE procedure deletes the current file component. DELETE can be used only on files with relative or indexed organization that have been opened for direct or keyed access; it cannot be used on files with sequential organization. Syntax: DELETE( file_variable[[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the file from which a component is to be deleted. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in inspection mode before DELETE is called; the mode does not change after the procedure's execution. When the DELETE procedure is called, the current component, as indicated by the file buffer, must already have been locked by a successful FIND, FINDK, GET, RESET, or RESETK procedure before it can be deleted. After deletion, the component is unlocked and the UFB function returns TRUE. See the "HP Pascal Language Reference Manual" for a complete description of the DELETE procedure. 4 FIND The FIND procedure positions a file at a specified component. The file must be open for direct access and must contain fixed-length components. Syntax: FIND( file_variable, component-number [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with a file that is open for direct access. The 'component-number' is a positive integer expression that indicates the component at which the file is to be positioned. If the component number is zero or negative, a run-time error occurs. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The FIND procedure allows direct access to the components of a file. You can use the FIND procedure to move forward or backward in a file. After execution of the FIND procedure, the file is positioned at the specified component. The file buffer variable assumes the value of the component, and the file mode is set to inspection. If the file has relative organization, the current file component is locked. If there is no file component at the selected position, the file buffer is undefined (UFB becomes TRUE) and the mode becomes undefined. After any call to FIND, the value of EOF is undefined. You can use the FIND procedure only when reading a file that was opened by the OPEN procedure. If the file is open because of a default open (that is, with EXTEND, RESET, or REWRITE), a call to FIND results in a run-time error because the default access method is sequential. See the "HP Pascal Language Reference Manual" for a complete description of the FIND procedure. 4 LOCATE The LOCATE procedure positions a random-access file at a particular component so that the next PUT procedure can modify that component. Syntax: LOCATE( file_variable, component-number [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the file to be positioned. The 'component-number' is a positive integer expression indicating the relative component number of the component to be found. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file can be in any mode before LOCATE is called. The mode is set to generation after the procedure's execution. The LOCATE procedure positions the file so that the next PUT procedure writes the contents of the file buffer into the selected component. After LOCATE has been performed, UFB returns TRUE and EOF is undefined. See the "HP Pascal Language Reference Manual" for complete information on the LOCATE procedure. 4 UPDATE The UPDATE procedure writes the contents of the file buffer into the current component. Syntax: UPDATE( file_variable[[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the file whose component is to be updated. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file must be in inspection mode before UPDATE is called; it remains in that mode after the procedure's execution. The UPDATE procedure is legal for files that have been opened for random access ("direct" or "keyed"). The current component must already have been locked by a successful FIND, FINDK, GET, RESET, or RESETK procedure before the contents of the file buffer can be rewritten into it. After the update has taken place, the component is unlocked and UFB returns TRUE. See the "HP Pascal Language Reference Manual" for complete information on the UPDATE procedure. 3 Keyed_Access Keyed access procedures are legal only on files opened for keyed access. 4 FINDK The FINDK procedure searches the index of an indexed file opened for keyed access and locates a specific component. Syntax: FINDK( file_variable, key-number, key-value[[, match-type]] [[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the file to be searched. The 'key-number' is a positive integer expression that indicates the key position. The 'key-value' is an expression that indicates the key to be found. It must be assignment compatible with the key field in the specified key position. The 'match-type' is an identifier that indicates the relationship between the key value in the FINDK procedure call and key value of a component. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. When you establish key fields with the KEY attribute, you assign each one a key number from 0 to 254. Key number 0 represents the mandatory primary key of the file. Separate indexes are built for each key number in the file. The key value and the match type provide information about the key to be found. The key value must be assignment compatible with the key fields of the key number being searched. The match type must be EQL (equal to the key value), NXT (the next key in the collating sequence after the key value), or NXTEQL (the next or equal key in the collating sequence after the key value). If the FINDK procedure was used on an ascending collating sequence, NXT and NXTEQL would be equivalent to GTR and GEQ. If a descending collating sequence was used, it would be the same as LSS and LEQ. The match type is optional; if omitted, it defaults to EQL. The FINDK procedure can be called for any indexed file opened for keyed access, regardless of the file's mode. If the component described exists, the file buffer is filled with that component; UFB and EOF both become FALSE. The mode is set to inspection and the component is automatically locked. If no component is found to match the description, UFB becomes TRUE and EOF is undefined. The mode is set to undefined. See the "HP Pascal Language Reference Manual" for complete information on the FINDK procedure. 4 RESETK The RESETK procedure, like the RESET procedure, readies a file for reading. Syntax: RESETK( file_variable, key-number[[, ERROR := error-recovery]] ); The 'file_variable' is the name of the file variable associated with the input file. The 'key-number' is a positive integer expression that indicates the key position. The 'error-recovery' specifies the action to be taken if an error occurs during execution of the routine. By default, after the first error, the error message is printed and execution is stopped. The file can be in any mode before RESETK is called to set the mode to inspection. RESETK can be applied only to indexed files opened for random access by key. You assign a key number from 0 to 254 to each key field of a file component with the KEY attribute. The file is searched for the component with the lowest value in the specified key number. This component becomes the current component in the file and is locked. The value of the current component is copied into the file buffer; EOF and UFB are set to FALSE. If the component does not exist, EOF and UFB become TRUE. Note that a RESETK procedure on key number 0 is equivalent to a RESET procedure. See the "HP Pascal Language Reference Manual" for complete information on the RESETK procedure. 2 Compilation_Units A compilation unit is a unit of VSI Pascal code that can be compiled independently; the term refers to either a program or a module. Both programs and modules have declaration sections but only programs have executable sections. A program can be compiled, linked, and run by itself, but a module cannot be executed unless it is linked with a main program written in PASCAL, or another language. A module may contain routine declarations but these cannot be executed independently of a program. 3 PROGRAM A program is a set of instructions that can be compiled and executed by itself. Syntax: [[attribute-list]] PROGRAM comp-unit-identifier [[({file-identifier},...)]]; [[declaration-section]] BEGIN {statement};... END. The 'attribute-list' is one or more identifiers that provide additional information about the compilation unit. The 'comp-unit-identifier' specifies the name of the program. The identifier appears only in the heading and has no other purpose within the compilation unit. The 'file-identifier' specifies the names of any file variables associated with the external files used by the compilation unit. The 'declaration-section' is a VSI Pascal declaration section. The 'statement' is any VSI Pascal statement. The program heading includes all information preceding the program block. If your program contains any input or output routines, you must list all the external file variables that you are using in the compilation unit's heading. File variables listed in a heading must also be declared locally in the block, except for the predeclared file variables INPUT and OUTPUT. The INPUT identifier corresponds to a predefined external file that accepts input from the default device (usually, your terminal); the OUTPUT identifier corresponds to a predefined external file that sends output to the default device (usually, your terminal). If you redeclare INPUT or OUTPUT in a nested block, you lose access to the default input or output devices. 3 MODULE A module is a set of instructions that can be compiled, but not executed, by itself. Module blocks contain only a declaration section and TO BEGIN DO and TO END DO sections. Syntax: [[attribute-list]] MODULE comp-unit-identifier [[({file-identifier},...)]]; [[declaration-section]] [[TO BEGIN DO statement;]] [[TO END DO statement;]] END. The 'attribute-list' is one or more identifiers that provide additional information about the compilation unit. The 'comp-unit-identifier' specifies the name of the program. The identifier appears only in the heading and has no other purpose within the compilation unit. The 'file-identifier' specifies the names of any file variables associated with the external files used by the compilation unit. The 'declaration-section' is a VSI Pascal declaration section. The 'statement' is any VSI Pascal statement. Each module must be in a separate file; you cannot place multiple modules (or a module and a program) in the same file. You can compile modules and a program together or separately (the syntax of compilation depends on the operating system command-line interpreter you are using). The module syntax of VSI Pascal is slightly different than that of Extended Pascal. However, the concepts in both languages are the same. The module heading includes all information preceding the module block. If your program contains any input or output routines, you must list all the external file variables that you are using in the compilation unit's heading. File variables listed in a heading must also be declared locally in the block, except for the predeclared file variables INPUT and OUTPUT. The INPUT identifier corresponds to a predefined external file that accepts input from the default device (usually, your terminal); the OUTPUT identifier corresponds to a predefined external file that sends output to the default device (usually, your terminal). If you redeclare INPUT or OUTPUT in a nested block, you lose access to the default input or output devices. 2 Attributes An attribute is an identifier that directs the VSI Pascal compiler to change its behavior in some way. When an attribute is not explicitly stated, the compiler follows the default rules to assign properties to program elements. However, using attributes to override the defaults allows additional control over the properties of data items, routines, and compilation units. Syntax of a VSI Pascal attribute: [ {identifier1 [[ ( { constant-expression | identifier2 } ,...) ]] },... ] The 'identifier1' is the name of the attribute. The 'constant-expression' is a compile-time integer expression that qualifies several of the VSI Pascal attributes. The 'identifier2' is the name of an option available in one of the following cases: o With the CHECK, OPTIMIZE, or KEY attributes o With COMMON and PSECT attributes, indicating the name of a storage area o With the GLOBAL, EXTERNAL, WEAK_GLOBAL, and WEAK_EXTERNAL attributes, indicating an external name A list of attributes can appear anywhere in the VAR, TYPE, and CONST declaration sections, and anywhere in a program that a type, a type identifier, or the heading of a routine or compilation unit is legal. However, only one attribute from a particular class can appear in a given attribute list. The names of attributes, when used in a suitable context, cannot conflict with other identifiers with the same name in the program. Syntactically, an attribute list can appear before a VAR, TYPE, and CONST section in the declaration section. In this case, the attributes would apply to all elements in that particular section. However, at this time, VSI Pascal only allows you to use the HIDDEN attribute in this way. Some attributes require a special form of constant expression called a name string. The syntax of a name string differs from that of other strings in VSI Pascal only in that a name string cannot use the extended-string syntax. See the "HP Pascal Language Reference Manual" for the complete description of attributes. 3 ALIGN The ALIGN attribute controls the default alignment rules in a compilation unit or for a TYPE or VAR declaration section. The ALIGN attribute takes a single keyword parameter that has the same name and meaning as the keywords for the /ALIGN qualifier. Note that specifying the ALIGN attribute overrides any value you previously specified with the /ALIGN qualifier. Syntax: [ALIGN(keyword)] You can specify the following keywords: Value Action Default Information ----- ------ ------- ----------- NATURAL Uses natural alignment when Default on OpenVMS Alpha positioning record fields and OpenVMS I64 systems. or array components. Natural alignment is when a record field or an array component is positioned on a boundary based on its size. For example, 32-bit integers are aligned on the nearest 32-bit boundary. VAX Uses byte alignment when pos- Default on OpenVMS VAX itioning record fields or array systems. components. Record fields or array components larger than 32 bits are positioned on the nearest byte boundary. On OpenVMS VAX systems, when you specify a value of NATURAL, automatic variables are aligned on longword boundaries instead of quadword boundaries. This occurs because the largest allowable alignment for the stack is longword alignment. 3 Alignment Alignment attributes indicate whether the object should be aligned on a specific address boundary in memory. 4 ALIGNED The ALIGNED attribute indicates the object is to be aligned on a specific memory boundary. Syntax: ALIGNED [[( n )]] The default alignment of an object depends on its size. The constant expression n must denote an integer. If you omit n, the default is 0, indicating byte alignment. An aligned object is aligned on the memory boundary indicated by n. The constant expression n indicates that the address of the object must end in at least n zeros. ALIGNED(0) specifies byte alignment, ALIGNED(1) specifies word alignment, ALIGNED(2) specifies longword alignment, ALIGNED(3) specifies quadword alignment, ALIGNED(4) specifies octaword alignment, ALIGNED(9), specifies 512-byte alignment, and ALIGNED(13) specifies 8192-byte alignment. See the "HP Pascal Language Reference Manual" for the complete description of using the ALIGNED attribute. 4 UNALIGNED The UNALIGNED attribute specifies that an object can be aligned on any bit boundary. An UNALIGNED variable cannot have an allocation size greater than 32 bits. See the "HP Pascal Language Reference Manual" for the complete description of using the UNALIGNED attribute. 3 Allocation Allocation attributes indicate the form of storage that the object should occupy. 4 AUTOMATIC The AUTOMATIC attribute specifies that storage for the variable be allocated each time the program enters the routine in which the variable is declared. The storage is deallocated each time the program exits from that routine. An automatic variable exists as long as the declaring routine remains active. See the "HP Pascal Language Reference Manual" for the complete description of using the AUTOMATIC attribute. 4 AT The AT attribute specifies that VSI Pascal allocates no storage for the object (storage has already been allocated) and that it resides at the exact, specfied address. Syntax: AT( n ) The exact address is specified by the constant expression n. Variables representing machine-dependent entities are frequently given the AT attribute. See the "HP Pascal Language Reference Manual" for the complete description of using the AT attribute. 4 COMMON The COMMON attribute specifies that storage for a variable be allocated in an overlaid program section called a common block. Syntax: COMMON [[(identifier)]] The 'identifier' indicates the name of the common block. It is passed in uppercase on OpenVMS systems. If you omit the identifier, the name of the variable is used as the name of the common block. This attribute allows you to share variables with other HP languages, such as FORTRAN. See the "HP Pascal Language Reference Manual" for the complete description of using the COMMON attribute. 4 PSECT The PSECT attribute is useful for placing static variables and executable blocks in program sections that will be shared among executable images. Syntax: [PSECT(identifier)] The 'identifier' designates the program section in which storage for a variable, routine, or compilation is to be allocated. It is passed in uppercase on OpenVMS systems. If you omit the identifier, the name of the variable is used as the name of the common block. The identifier designates the compilation unit in which storage for a variable is to be allocated. 4 STATIC The STATIC attribute causes VSI Pascal to create a static object, which is allocated only once and which exists as long as the executable image in which it is allocated remains active. See the "HP Pascal Language Reference Manual" for the complete description of using the STATIC attribute. 3 ASYNCHRONOUS The ASYNCHRONOUS attribute indicates that a routine may be called by an asynchronous event (such as a condition handler). Since such an event can alter the values of variables within the routine upredictably, this attribute forces the routine to reference only local variables or variables declared with the VOLATILE attribute. See the "HP Pascal Language Reference Manual" for the complete description of using the ASYNCHRONOUS attribute. 3 CHECK The CHECK attribute specifies error-checking options that are to be enabled during program execution. Syntax: CHECK [[( {identifier},... )]] An identifier specifies an option to be enabled. If you omit the list of options, all available positive options are enabled. ALL Enables all forms of checking. NONE Suppresses all checking code. [NO]BOUNDS Verifies that an index expression is within the bounds of an array's index type and that character-string sizes are compatible with the operations being performed and that schema types are compatible. [NO]CASE_SELECTORS Verifies that the value of a case selector is contained in the corresponding case label list. [NO]DECLARATIONS Verifies that schema definitions yield valid types and that uses of GOTO from one block to an enclosing block are correct. [NO]OVERFLOW Verifies that the result of an integer computation does not exceed the machine representation. [NO]POINTERS Verifies that the value of a pointer variable is not NIL. [NO]SUBRANGE Verifies that values assigned to variables of subrange types are within the subrange; verifies that a set expression is assignment compatible with a set variable. See the "HP Pascal Language Reference Manual" for the complete description of using the CHECK attribute. 3 ENUMERATION_SIZE The ENUMERATION_SIZE attribute controls the allocation of unpacked enumerated data types and Boolean data types, which are considered to be an enumerated type containing two elements. Note that specifying this attribute overrides any value that you previously specified with the /ENUMERATION_SIZE qualifier. Syntax: [ENUMERATION_SIZE(keyword)] You can specify the following keywords: Keyword Action Default Information ------- ---------------------------- ------------------- BYTE Allocates unpacked enumerated Default on OpenVMS VAX types with fewer than 255 systems. elements in a 8-bit byte. Otherwise, the enumerated types are allocated in a 16-bit word. LONG Allocates unpacked enumerated Default on OpenVMS Alpha types in a 32-bit longword. and OpenVMS I64 systems. 3 ENVIRONMENT The ENVIRONMENT attribute can be applied to compilation units and causes the unit's program or module level declarations and definitions to be saved. Syntax: ENVIRONMENT [[( name-string )]] If the 'name string' is omitted, the name of the source file is used as the environment file name with the default file type PEN. The declarations and definitions made at the outermost level of the compilation unit (provided they do not have the AUTOMATIC or HIDDEN attribute) are saved in a newly created environment file. If the name string is specified, you must include a legal file specification. See the "HP Pascal Language Reference Manual" for the complete description of using the ENVIRONMENT attribute. 3 FLOAT The FLOAT attribute indicates the type of precision to use for objects of type REAL and DOUBLE. Syntax: [FLOAT(keyword)] You can specify the following float types for keywords: o D_FLOAT - REAL=FLOATING, DOUBLE=D_FLOATING o G_FLOAT - REAL=F_FLOATING, DOUBLE=G_FLOATING o IEEE_FLOAT - REAL=S_FLOATING, DOUBLE=T_FLOATING The [FLOAT] attribute is only valid on compilation-units. 3 HIDDEN The HIDDEN attribute prevents information concerning a constant definition or a type, variable, procedure, or function declaration from being included in a generated environment file. The HIDDEN attribute can be used only on objects at the outermost level of the compilation unit. It is possible to prevent all declarations within a declaration section from being included in the environment file by preceding the reserved word CONST, TYPE, or VAR with the HIDDEN attribute. 3 IDENT The IDENT attribute can be used to qualify the name of a compilation unit. In the absence of an IDENT attribute, the string '01' is supplied to the linker. Syntax: IDENT( name-string ) The 'name-string' can contain additional information whose use is implementation specific. The VSI Pascal compiler uses this string to supply identification information to the linker. 3 INHERIT The INHERIT attribute indicates the environment file or files to be inherited by a compilation unit. The environment files specified by the INHERIT attribute must already have been created in compilation units (by either the ENVIRONMENT attribute or a compilation switch). Syntax: INHERIT( {name-string},... ) The compilation unit inherits one or more environment files named by the file specifications in the name strings. The default file type for an inherited environment file is .PEN. 3 INITIALIZE The INITIALIZE attribute can be applied to procedures to indicate that the procedure is to be called before the main program is entered. A compilation unit might include any number of INITIALIZE procedures, all of which are called in an unspecified order before the main program is entered. See the "HP Pascal Language Reference Manual" for the complete description of using the INITIALIZE attribute. 3 KEY The KEY attribute can be applied to record fields to indicate that the field is to be used as a key field when the record is part of an indexed file. Syntax: KEY [[( n [[, {options},... ]] )]] KEY [[( {options},... )]] The 'n' represents the key number. A key number of 0 indicates that the field is the primary key of the record. All other key numbers indicate alternate keys. The key number must be a constant expression that denotes an integer value in the range from 0 through 254. See the "HP Pascal Language Reference Manual" for the complete description of using the KEY attribute. 4 Options You can specify certain characteristics of the record key by listing the desired options on the KEY attribute. With these options, you can control the order of the collating sequence and you can allow changes or duplicates on a key. See the "HP Pascal Language Reference Manual" for the complete description of using these options. 5 ASCENDING This option, along with DESCENDING, allows you to specify the collating sequence for the key field. By default, the primary key and alternate key are ASCENDING. When creating a new file, Pascal will create the key with the collating order specified. When opening an existing file, the Run-Time Library will verify that the existing key matches the collating order specified. If neither ASCENDING or DESCENDING is specified when opening an existing file, both types will be accepted. 5 CHANGES This option allows you to specify that changes can be performed on the key. The default for the primary key is NOCHANGES and the default for alternate keys is CHANGES. You can override the CHANGES on alternate keys with NOCHANGES. It is illegal to specify CHANGES on the primary key. When opening an existing file, the Pascal Run-Time Library ignores this option. 5 DESCENDING(see ASCENDING) 5 DUPLICATES This option allows you to specify that duplicates of the key are allowed. The default for the primary key is NODUPLICATES and the default for alternate keys is DUPLICATES. When opening an existing file, the Pascal Run-Time Library ignores this option. 3 LIST The LIST attribute can be applied to a formal parameter of a routine and indicates that the routine can be called with multiple actual parameters that correspond to the last formal parameter named in the routine heading. You can also use the ARGUMENT and ARGUMENT_LIST_LENGTH predeclared routines when writing procedures and functions that use the LIST attribute. See the "HP Pascal Language Reference Manual" for the complete description of using the LIST attribute. 3 Optimize The optimization attributes indicate whether the VSI Pascal compiler should optimize code. 4 OPTIMIZE The OPTIMIZE attribute specifies optimization options that are to be enabled during compilation of a compilation unit or routine. Syntax: OPTIMIZE [[( {identifier},... )]] All options are enabled by default. ALL Enables all OPTIMIZE options. NONE Disables all OPTIMIZE options. [NO]INLINE Enables inline expansion of user-defined routines. See the "HP Pascal Language Reference Manual" for the complete description of using the OPTIMIZE attribute. 4 NOOPTIMIZE The NOOPTIMIZE attribute prohibits the compiler from optimizing code for the compilation unit or routine. The NOOPTIMIZE attribute guarantees left-to-right evaluation order with full evaluation of both operands of the AND and OR Boolean operators to aid in diagnosing all potential programming errors. If you wish to have short circuit evaluation even with the NOOPTIMIZE attribute, then use the AND_THEN and OR_ELSE Boolean operators. See the "HP Pascal Language Reference Manual" for the complete description of using the NOOPTIMIZE attribute. 3 Parameter The parameter passing attributes indicate the passing mechanism to be used for a parameter. 4 CLASS_A The CLASS_A attribute causes a formal parameter to be passed by an array descriptor that describes contiguous arrays of atomic data types or contiguous arrays of fixed-length strings. This is the default mechanism for conformant array parameters on OpenVMS VAX systems. This attribute is illegal on parameters of schema types. See the "HP Pascal Language Reference Manual" for the complete description of using the CLASS_A attribute. 4 CLASS_NCA The CLASS_NCA attribute causes a formal parameter to be passed by a noncontiguous array descriptor. This attribute is illegal on parameters of schema types. This is the default mechanism for conformant array parameters on OpenVMS Alpha and OpenVMS I64 systems. 4 CLASS_S The CLASS_S attribute causes a formal parameter to be passed by a single descriptor form that is used for scalar data and fixed-length strings. This attribute allows routines written in VSI Pascal to accept actual parameters from languages that generate CLASS_S descriptors. See the "HP Pascal Language Reference Manual" for the complete description of using the CLASS_S attribute. 4 IMMEDIATE The IMMEDIATE attribute causes a formal parameter value in a routine declaration to be passed by immediate value. See the "HP Pascal Language Reference Manual" for the complete description of using the IMMEDIATE attribute. 4 REFERENCE The REFERENCE attribute causes the formal parameter in a routine to be passed by reference using foreign parameters. See the "HP Pascal Language Reference Manual" for the complete description of using the REFERENCE attribute. 3 PEN_CHECKING_STYLE The PEN_CHECKING_STYLE attribute selects the desired compile-time and link-time checking to perform when the generate environment file is inherited. PEN_CHECKING_STYLE( option ) COMPILATION_TIME Uses the compilation time of the environment file in all subsequent compile-time and link-time checking for users of this environment file. This is the default. IDENT_STRING Uses the [IDENT()] string of the environment file in all subsequent compile-time and link-time checking for users of this environment file. NONE Disables all compile-time and link-time checking for users of this environment file. 3 POS POS forces the field (of a packed or unpacked record) to a specific bit position within the record. Syntax: POS( n ) The constant expression 'n' specifies the bit location, relative to the beginning of the record, at which the field begins. See the "HP Pascal Language Reference Manual" for the complete description of using the POS attribute. 3 READONLY The READONLY attribute specifies that an object can be read by a program, but cannot have values assigned to it. See the "HP Pascal Language Reference Manual" for the complete description of using the READONLY attribute. 3 Size Size attributes indicate the amount of storage to be reserved for the object. 4 BIT The BIT attribute specifies the amount of storage in bits to be received by the object. Syntax: BIT [[( n )]] The optional constant 'n' indicates the number of bit storage units. It must denote a positive integer. If you omit n, the default value is 1. See the "HP Pascal Language Reference Manual" for the complete description of using the BIT attribute. 4 BYTE The BYTE attribute specifies the amount of storage in bytes to be received by the object. Syntax: BYTE [[( n )]] The optional constant 'n' indicates the number of byte storage units. It must denote a positive integer. If you omit 'n', the default value is 1. See the "HP Pascal Language Reference Manual" for the complete description of using the BYTE attribute. 4 WORD The WORD attribute specifies the amount of storage in words to be received by the object. Syntax: WORD [[( n )]] The optional constant 'n' indicates the number of word storage units. It must denote a positive integer. If you omit n, the default value is 1. See the "HP Pascal Language Reference Manual" for the complete description of using the WORD attribute. 4 LONG The LONG attribute specifies the amount of storage in longwords to be received by the object. Syntax: LONG [[( n )]] The optional constant 'n' indicates the number of longword storage units. It must denote a positive integer. If you omit 'n', the default value is 1. See the "HP Pascal Language Reference Manual" for the complete description of using the LONG attribute. 4 QUAD The QUAD attribute specifies the amount of storage in quadwords to be received by the object. Syntax: QUAD [[( n )]] The optional constant 'n' indicates the number of quadword storage units. It must denote a positive integer. If you omit 'n', the default value is 1. See the "HP Pascal Language Reference Manual" for the complete description of using the QUAD attribute. 4 OCTA The OCTA attribute specifies the amount of storage in octawords to be received by the object. Syntax: OCTA [[( n )]] The optional constant 'n' indicates the number of octaword storage units. It must denote a positive integer. If you omit 'n', the default value is 1. See the "HP Pascal Language Reference Manual" for the complete description of using the OCTA attribute. 3 TRUNCATE The TRUNCATE attribute indicates that an actual parameter list for a routine can be truncated at the point that the attribute was specified. This attribute can be specified on a formal parameter in a routine declaration, and can be used with the PRESENT function. See the "HP Pascal Language Reference Manual" for the complete description of using the TRUNCATE attribute. 3 UNBOUND The UNBOUND attribute specifies that a routine does not access automatic variables outside the scope in which it is declared. That is, the bound procedure value of an unbound routine does not include the static scope pointer. This attribute can be applied to routines and formal routine parameters. See the "HP Pascal Language Reference Manual" for the complete description of using the UNBOUND attribute. 3 UNSAFE The UNSAFE attribute indicates that an object can accept values of any type without type checking. The exact properties of an unsafe object depend on the object's machine representation. See the "HP Pascal Language Reference Manual" for the complete description of using the UNSAFE attribute. 3 VALUE The VALUE attribute causes the variable to be a reference to an external constant or to be the defining point of a global constant. See the "HP Pascal Language Reference Manual" for the complete description of using the VALUE attribute. 3 Visibility The visibility attributes indicate the ability of an object to be shared by compilation units. 4 LOCAL The LOCAL attribute indicates that an object is unavailable to other independently compiled units. By default, all variables and routines are local. See the "HP Pascal Language Reference Manual" for the complete description of using the LOCAL attribute. 4 GLOBAL The GLOBAL attribute provides a strong definition of a variable or routine so that other independently compiled units can refer to it. Syntax: [GLOBAL] or, [GLOBAL(idenifier)] or, [GLOBAL('string-literal')] The 'identifier' is the name of the identifier passed to the linker. It is passed in uppercase on OpenVMS systems. If you omit the identifier, the name of the variable is used. The 'string-literal' is a specified string literal that is passed unmodified to the linker. See the "HP Pascal Language Reference Manual" for the complete description of using the GLOBAL attribute. 4 EXTERNAL The EXTERNAL attribute indicates a variable or routine that is assumed to be global in another independently compiled unit. Syntax: [EXTERNAL] or, [EXTERNAL(identifer)] or, [EXTERNAL('string-literal')] The 'identifer' is the name of the identifier passed to the linker. It is passed in uppercase on OpenVMS systems. If you omit the identifier, the name of the variable is used. The 'string-literal' passes a specified string-literal to the linker unmodified. 4 WEAK_EXTERNAL The WEAK_EXTERNAL attribute specifies that a variable or routine is not critical to the linking operation. To resolve a weak reference, the linker searches only the named input modules. You can specify an identifier with this attribute to indicate the name by which the corresponding object is known to the linker. Syntax: [WEAK_EXTERNAL] or, [WEAK_EXTERNAL(identifier)] or, [WEAK_EXTERNAL('string-literal')] The 'identifier' is the name of the identifier passed to the linker. If you omit the identifier, the name of the variable is used. The 'string-literal' is the name of the string literal that is passed to the linker unmodified. Compilation units cannot have the EXTERNAL or WEAK_EXTERNAL attribute. 4 WEAK_GLOBAL The WEAK_GLOBAL attribute specifies that an object is linked only when it is specifically included in the linking operation. To resolve a weak reference, the linker searches only the named input modules. You can specify an identifier to indicate the name by which the corresponding object is known to the linker. Syntax: [WEAK_GLOBAL] or, [WEAK_GLOBAL(identifier)] or, [WEAK_GLOBAL('string_literal')] The 'identifier' is the name of the identifier passed to the linker. If you omit the identifier, the name of the variable is used. The 'string-literal' passes a specified string literal to the linker unmodified. See the "HP Pascal Language Reference Manual" for the complete description of using the WEAK_GLOBAL attribute. 3 VOLATILE The VOLATILE attribute indicates to the compiler that the value of an object is subject to change at unusual points in program execution. Normally, during execution, an object's value generally changes only when another value is assigned to it, when it is passed as a writeable VAR parameter, when it is read into by a READ, READLN, or READV procedure, or when it is used as the control variable of a FOR loop. In addition, the compiler expects to evaluate the object only when it appears in an expression. The value of a volatile object may change as the result of an action not directly specified in the program. Thus, the compiler assumes that the value of a volatile object can be changed or evaluated at any time during program execution. Consequently, a volatile object does not participate in any optimization based on assumptions about its value. The behavior of many device registers, and modifications by asynchronous processes and exception handlers, are two examples that demonstrate volatile behavior. See the "HP Pascal Language Reference Manual" for the complete description of using the VOLATILE attribute. 3 WRITEONLY The WRITEONLY attribute specifies that an object can have values assigned to it but cannot be read by a program. See the "HP Pascal Language Reference Manual" for the complete description of using the WRITEONLY attribute. 2 Directives 3 INCLUDE The %INCLUDE directive inserts the contents of a file at the location of the directive in the code and has the following form: Syntax: %INCLUDE 'file-spec [[/[[NO]]LIST]]' The 'file-spec' is the name of the file to be included. The /LIST qualifier indicates that the included file should be printed in the listing of the program if a listing is being generated. If not specified, the default is determined by the use of compilation switches. Use of this parameter overrides compilation switches. See the "HP Pascal Language Reference Manual" for the complete description of using the %INCLUDE directive. 3 DICTIONARY The %DICTIONARY directive allows access to data definitions stored in the CDD/Repository, which is a product that must be purchased separately and may not be available on your environment. Syntax: %DICTIONARY 'cdd-path-name [[/[[NO]]LIST]]' The 'cdd-path-name' is a character string that represents the full or relative path name of a CDD record description to be extracted. The resulting path name must conform to the rules for forming CDD path names. A full path name is one that begins with CDD$TOP and specifies the names of all its descendants; it is a complete path to the record definition. Descendant names are separated from each other by a period. A relative path name begins with any generation other than CDD$TOP, and specifies the names of the descendants after that point. You can create a relative path by establishing a default directory with a logical name. The /LIST qualifier indicates that the included declarations should be printed in the listing of the program if a listing is being generated. If not specified, the default is determined by compilation switches. Use of this parameter overrides compilation switches. Example: TYPE %DICTIONARY 'CDD$TOP.CORPORATE.SALARY_RANGE' The definition of 'CDD$TOP.CORPORATE.SALARY_RANGE' is placed in a program at the position of the TYPE declaration. 3 TITLE_and_SUBTITLE The %TITLE and %SUBTITLE directives allow you to specify a compile-time string expression for the listing title and subtitle lines. Syntax: %TITLE 'character string' or %SUBTITLE 'character string' The compiler listing header includes the %TITLE and %SUBTITLE strings in the title and subtitle sections. If you do not specify these directives, VSI Pascal fills the %TITLE field with blanks and the first %SUBTITLE field with 'source listing'. If a specified 'character string' is too long to fit in the predefined title and subtitle sections, the string will be truncated on the right without warning. If a %TITLE directive appears on the first line of a page, it sets the title area for the current page and any following pages until the compiler encounters another %TITLE directive. If the %TITLE directive does not appear on the first line of a page, then the title area is not set until the next page. The %SUBTITLE directive affects only the subtitle area in the source listing section. If a %SUBTITLE directive appears on the first or second line of a page, then the subtitle area is set for the current page. If the %SUBTITLE directive does not appear in the first two lines of a page, then the subtitle area is not set until the next page. On OpenVMS VAX, if either of these directives is used and if a listing is being generated, HP Pascal generates a table of contents page by default. This page appears first in the listing, preceding the source listing section. To disable the table of contents option, you must use a compilation switch. 3 IF The %IF family of directives (%IF, %ELSE, %ELIF, %ENDIF) is used to conditionally compile specific sections of source code. These directives are useful if you need to compile the same source code for various configurations or environments. %IF compile-time-expression %THEN Pascal tokens ... [%ELIF compile-time-expression %THEN Pascal tokens ... ] ... [%ELSE Pascal tokens ... ] %ENDIF A %IF directive can have zero or more %ELIF parts and zero or one %ELSE parts. %IF directives can be nested up to 32 deep. Note that skipped sections of source code must still be valid VSI Pascal tokens. The skipped tokens are not processed semantically by the compiler. The compile-time expression for the %IF and %ELIF directives is the same compile-time expression that can be used anywhere in VSI Pascal. The /CONSTANT DCL qualifier can be used together with the %IF directive to control the conditional processing from the command line. 3 ELSE See the %IF directive for more information on how to use %ELSE. 3 ELIF See the %IF directive for more information on how to use %ELIF. 3 ENDIF See the %IF directive for more information on how to use %ENDIF. 3 DEFINED The %DEFINED directive take a name and returns TRUE if the name has a meaning in the current scope; otherwise it returns FALSE. %IF NOT %DEFINED(MaxSize) %THEN CONST MaxSize = 100; %ENDIF 3 ERROR The %ERROR directive accepts one or more string expressions and at compile-time will generate a compiler error that includes the concatenation of the string expressions. %ERROR( string-expression,... ) 3 WARN The %WARN directive accepts one or more string expressions and at compile-time will generate a compiler warning that includes the concatenation of the string expressions. %WARN( string-expression,... ) 3 INFO The %INFO directive accepts one or more string expressions and at compile-time will generate a compiler informational that includes the concatenation of the string expressions. %INFO( string-expression,... ) 3 MESSAGE The %MESSAGE directive accepts one or more string expressions and at compile-time will generate a compiler message that includes the concatenation of the string expressions. The message is generated directly from the compiler and does not use the OpenVMS error message service $PUTMSG. %MESSAGE( string-expression,... ) 3 ARCH_NAME The %ARCH_NAME directive returns the string "VAX", "Alpha", or "IA64" depending on the architecture of the system on which the compilation is taking place. 3 SYSTEM_NAME The %SYSTEM_NAME directive returns the string "OpenVMS". 3 SYSTEM_VERSION The %SYSTEM_VERSION directive returns a string containing the value of the SYI$_VERSION itemcode from the $GETSYI system service. 3 DATE_and_TIME The %DATE directive returns a string containing the date at the beginning point of the compilation. The %TIME directive returns a string containing the time at the beginning point of the compilation. 3 COMPILER_VERSION The %COMPILER_VERSION directive returns a string containing the version of the VSI Pascal compiler performing the compilation. 3 LINE The %LINE directive returns an integer that denotes the current line number in the source file. 3 FILE The %FILE directive returns a string containing the file name that is currently being compiled. 3 ROUTINE The %ROUTINE directive returns a string with the name of the routine that is currently being compiled. If used in the executable portion of a program, the program's name is returned. If used in the declaration section of a MODULE/PROGRAM, the name of the MODULE/PROGRAM is returned. 3 MODULE The %MODULE directive returns a string containing the name of the MODULE/PROGRAM being compiled. 3 IDENT The %IDENT directive returns a string that contains the ident string of the compilation. The ident string is set with the IDENT attribute. 3 FLOAT The %FLOAT directive returns a string that indicates the current floating point default of the compilation. The possible values are "VAX_FLOAT" or "IEEE_FLOAT" depending on the setting of the /FLOAT DCL qualifier or the [FLOAT] module-level attribute. 3 F_FLOAT The %F_FLOAT directive produces a VAX F_floating literal regardless of the current floating point default of the compilation. Without the directive, the format of a single precision floating literal will be determined based on the setting of the /FLOAT DCL qualifier or the [FLOAT] module-level attribute. The syntax is: %F_FLOAT floating-point-literal For example, lib$wait(%f_float 1.0); will ensure the correct floating literal for LIB$WAIT even on OpenVMS I64 systems which default to IEEE floating format. 3 S_FLOAT The %S_FLOAT directive produces an IEEE S_floating literal regardless of the current floating point default of the compilation. Without the directive, the format of a single precision floating literal will be determined based on the setting of the /FLOAT DCL qualifier or the [FLOAT] module-level attribute. The %S_FLOAT directive is not supported on OpenVMS VAX systems. The syntax is: %S_FLOAT floating-point-literal 3 D_FLOAT The %D_FLOAT directive produces a VAX D_floating literal regardless of the current floating point default of the compilation. Without the directive, the format of a double precision floating literal will be determined based on the setting of the /FLOAT DCL qualifier or the [FLOAT] module-level attribute. The syntax is: %D_FLOAT floating-point-literal 3 G_FLOAT The %G_FLOAT directive produces a VAX G_floating literal regardless of the current floating point default of the compilation. Without the directive, the format of a double precision floating literal will be determined based on the setting of the /FLOAT DCL qualifier or the [FLOAT] module-level attribute. The syntax is: %G_FLOAT floating-point-literal 3 T_FLOAT The %T_FLOAT directive produces an IEEE T_floating literal regardless of the current floating point default of the compilation. Without the directive, the format of a double precision floating literal will be determined based on the setting of the /FLOAT DCL qualifier or the [FLOAT] module-level attribute. The %T_FLOAT directive is not supported on OpenVMS VAX systems. The syntax is: %T_FLOAT floating-point-literal 2 Comments Comments document the actions or elements of a program. The text of a comment can contain any ASCII character except a nonprinting control character, such as an ESCAPE character. You can place comments anywhere in a program that white space can appear. You signify a comment with braces or with a parenthesis and asterisk pair, as follows: Example: { This is a comment } (* This is also a comment *) VSI Pascal allows you to mix the two symbol pairs in one comment, as follows: { The delimiters of this comment do not match. *) (* VSI Pascal allows you to mix delimiters in this way. } VSI Pascal does not allow you to nest comments. The following example causes a compile-time error because the comment ends at the first closing delimiter (}). Example The following is illegal: (* Comments can not be nested { in VSI Pascal } within a program *) 2 Release_Notes Please refer to SYS$HELP:PASCAL%%%.RELEASE_NOTES for VSI Pascal release notes.