Library /sys$common/syshlp/helplib.hlb  —  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.

1  –  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.

3    /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.

4    /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.

5    /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.

6    /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.

7    /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.

8    /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.

9    /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.

10    /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.

11    /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.

12    /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.

13    /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.

14    /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.

15    /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.

16    /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.

17    /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

18    /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.

19    /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.

20    /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:

21  –  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.

22    /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.

23    /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.

24    /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

25    /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.

26    /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.

27    /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.

28    /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.

29    /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.

30    /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.

31    /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.

32    /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.

33    /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.

34    /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.

35    /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.

36    /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.

37    /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.

38    /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.

39  –  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.

40  –  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.

40.1  –  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."

40.2  –  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 (<>).

40.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.

40.4  –  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

40.4.1  –  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.

40.4.2  –  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.

41  –  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.

41.1  –  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.

41.1.1  –  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.

41.1.1.1  –  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'

41.1.1.2  –  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'

41.1.2  –  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.

41.1.3  –  INTEGER8

  The INTEGER8 predefined type is equivalent to the following:

  Syntax:

     TYPE INTEGER8=[BYTE]-128..127;{ 16#80..16#7F}

41.1.4  –  INTEGER16

  The INTEGER16 predefined type is equivalent to the following:

  Syntax:

     TYPE INTEGER16=[WORD]-32768..32767;{ 16#8000..16#7FFF }

41.1.5  –  INTEGER32

  The INTEGER32 predefined type is equivalent to the following:

  Syntax:

     TYPE INTEGER32=[LONG]-2147483648..2147483647;{ 16#80000000..16#7FFFFFFF }

41.1.6  –  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.

41.1.7  –  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.

41.1.8  –  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'

41.1.8.1  –  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'

41.1.9  –  UNSIGNED8

  The UNSIGNED8 data type is equivalent to the following:

  Syntax:

     TYPE UNSIGNED8 = [BYTE]UINT(0)..UINT(255); {0..16#FF}

41.1.10  –  UNSIGNED16

  The UNSIGNED16 data type is equivalent to the following:

  Syntax:

     TYPE UNSIGNED16 = [WORD]UINT(0)..UINT(65535); {0..16#FFFF}

41.1.11  –  UNSIGNED32

  The UNSIGNED32 data type is equivalent to the following:

  Syntax:

     TYPE UNSIGNED32 = [LONG]UINT(0)..UINT(4294967295); {0..16#FFFFFFFF}

41.1.12  –  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}

41.1.13  –  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)

41.1.14  –  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.

41.1.15  –  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.

41.1.16  –  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.

41.2  –  Real

  Real types specify real number values with different degrees  of
  precision.

41.2.1  –  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.

41.2.2  –  SINGLE

  The SINGLE  type  denotes  single-precision  real  values.   The
  SINGLE type is synonymous with the REAL type.

41.2.3  –  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.

41.2.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.

41.2.5  –  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.

41.2.6  –  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.

41.2.7  –  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.

41.2.8  –  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.

41.2.9  –  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.

41.2.10  –  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.

41.2.11  –  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.

41.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.

41.3.1  –  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.

41.3.2  –  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

41.3.3  –  UNIV_PTR

  The predefined UNIV_PTR type is equivalent to:

  TYPE
      UNIV_PTR = POINTER;

41.4  –  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.

41.4.1  –  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;

41.4.1.1  –  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.

41.4.1.2  –  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.

41.4.1.3  –  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)

41.4.2  –  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'.

41.4.2.1  –  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.

41.4.2.1.1  –  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.

41.4.2.2  –  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))

41.4.3  –  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']

41.4.3.1  –  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.

41.4.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^.

41.4.4.1  –  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.

41.4.4.2  –  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.

41.5  –  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 )

  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.

41.5.1  –  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 )
  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.

41.5.2  –  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 )

  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.

41.6  –  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';

41.6.1  –  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.

41.6.2  –  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.

41.6.2.1  –  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.

41.6.3  –  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'

41.7  –  Misc Types

  VSI Pascal provides a predefined data types  that  can  be  used
  with specific routines.

41.7.1  –  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.

42  –  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 ]]

42.1  –  simple_expression

  The syntax for a simple expression is:

       {+ | -} term [[ {{+ | - | OR | OR_ELSE} term}...]]

42.2  –  term

  The syntax for a term is:

       primary [[ {{* | / | DIV | REM | MOD | AND
                                | AND_THEN} primary}... ]]

42.3  –  primary

  The syntax for a primary is:

       factor [[ {** factor}... ]]

42.4  –  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

42.5  –  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.

42.6  –  Operators

  Pascal provides several classes  of  operators.   You  can  form
  complex  expressions  by  using  operators to combine constants,
  constant identifiers, variables, and function designators.

42.6.1  –  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

42.6.2  –  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 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

42.6.3  –  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)

42.6.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 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)

42.6.5  –  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 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

42.6.6  –  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.

43  –  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
           .
           .
           .

43.1  –  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;

43.2  –  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.'

43.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.

43.4  –  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.

43.5  –  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.

43.6  –  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.

43.7  –  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.

43.8  –  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.

43.8.1  –  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.

43.8.1.1  –  identifier

  The 'identifier' is the name of the formal parameter.   Multiple
  identifiers must be separated with commas.

43.8.1.2  –  attribute_list

  The 'attribute-list' is one or more optional  identifiers  which
  provide information about the formal parameter.

43.8.1.3  –  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.

43.8.1.4  –  type_id

  A type identifier is the type identifier of  the  parameters  in
  this parameter section.

43.8.1.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.

43.8.1.6  –  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.

43.8.1.7  –  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.

43.8.2  –  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.

43.8.3  –  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.

44  –  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.

44.1  –  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.

44.1.1  –  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']}

44.2  –  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.

44.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.

44.3.1  –  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.

44.4  –  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.

44.5  –  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.

44.6  –  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.

44.7  –  EXIT

  The EXIT statement is identical to the BREAK statement

44.8  –  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.

44.8.1  –  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.

44.9  –  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.

44.9.1  –  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.

44.10  –  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.

44.10.1  –  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}

44.11  –  NEXT

  The NEXT statement is identical to the CONTINUE statement.

44.12  –  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.

44.12.1  –  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.

44.13  –  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.

44.13.1  –  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.

44.14  –  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.

44.15  –  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.

44.15.1  –  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;

44.16  –  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.

44.16.1  –  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.

44.17  –  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.

44.17.1  –  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.

45  –  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.

45.1  –  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.

45.1.1  –  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.

45.1.2  –  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.

45.1.3  –  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.

45.1.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.

45.1.5  –  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.

45.1.6  –  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.

45.2  –  Arithmetic

  Arithmetic routines perform mathematical  computations.   Actual
  parameters  to the arithmetic functions can be of any arithmetic
  type.

45.2.1  –  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.

45.2.2  –  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.

45.2.3  –  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.

45.2.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.

45.2.5  –  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.

45.2.6  –  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.

45.2.7  –  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.

45.2.8  –  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.

45.2.9  –  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.

45.2.10  –  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.

45.2.11  –  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.

45.2.12  –  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.

45.2.13  –  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.

45.2.14  –  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.

45.2.15  –  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.

45.2.16  –  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.

45.2.17  –  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.

45.3  –  Char Strng

  VSI  Pascal  supplies  predeclared  routines   that   manipulate
  character strings.

45.3.1  –  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.

45.3.2  –  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.

45.3.3  –  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.

45.3.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.

45.3.5  –  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.

45.3.6  –  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.

45.3.7  –  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.

45.3.8  –  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.

45.3.9  –  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.

45.3.10  –  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.

45.3.11  –  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.

45.3.12  –  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.

45.3.13  –  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.

45.3.14  –  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.

45.3.15  –  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.

45.3.16  –  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.

45.3.17  –  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.

45.3.18  –  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.

45.3.19  –  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.

45.3.20  –  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.

45.4  –  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.

45.4.1  –  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.

45.4.2  –  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.

45.4.3  –  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.

45.4.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.

45.4.5  –  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.

45.5  –  Low Level

  The  low-level  routines  allow  for  parallel   processes   and
  asynchronous routines to operate in a real-time or multi-tasking
  environment.

45.5.1  –  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.

45.5.2  –  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'.

45.5.3  –  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'.

45.5.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.

45.5.5  –  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.

45.5.6  –  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'.

45.5.7  –  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.

45.6  –  Ordinal

  Ordinal routines provide information on the ordered sequence  of
  values.

45.6.1  –  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.

45.6.2  –  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.

45.6.3  –  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.

45.6.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.

45.7  –  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.

45.7.1  –  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.

45.7.2  –  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.

45.7.3  –  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.

45.7.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.

45.8  –  Parameter

  VSI  Pascal  provides  routines  that  give  information   about
  variable-length parameter lists.

45.8.1  –  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.

45.8.2  –  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.

45.8.3  –  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.

45.9  –  Transfer

  Transfer routines convert an actual parameter to data of another
  type.

45.9.1  –  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.

45.9.2  –  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.

45.9.3  –  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.

45.9.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.

45.9.5  –  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.

45.9.6  –  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).

45.9.7  –  QUAD

  The  QUAD  function  converts  the  parameter  and  returns  its
  QUADRUPLE equivalent.

  Syntax:

     QUAD( x )

  The parameter 'x' must be of an arithmetic type.

45.9.8  –  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.

45.9.9  –  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.

45.9.10  –  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.

45.9.11  –  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.

45.9.12  –  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.

45.9.13  –  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.

45.9.14  –  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.

45.9.15  –  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.

45.10  –  Privileged

  Privileged routines manipulate privileged hardware registers.

45.10.1  –  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.

45.10.2  –  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.

45.11  –  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.

45.11.1  –  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.

45.11.2  –  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.

45.11.3  –  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.

45.11.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.

45.11.5  –  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 }

45.11.6  –  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.

45.11.7  –  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.

45.11.8  –  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.

45.11.9  –  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.

45.11.10  –  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.

45.11.11  –  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.

45.11.12  –  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.

45.11.13  –  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.

45.11.14  –  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.

45.11.15  –  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.

45.11.16  –  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.

45.11.17  –  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.

45.11.18  –  REVERT

  The REVERT procedure cancels a condition  handler  activated  by
  the  ESTABLISH  procedure.   This  procedure  does  not  have  a
  parameter list.

45.11.19  –  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.

45.11.20  –  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

45.11.21  –  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.

45.11.22  –  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

45.11.23  –  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.

46  –  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.

46.1  –  General

46.1.1  –  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.

46.1.1.1  –  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.

46.1.1.2  –  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.

46.1.1.3  –  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.

46.1.1.4  –  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.

46.1.1.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.

46.1.1.6  –  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.

46.1.1.7  –  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.

46.1.1.8  –  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.

46.1.1.9  –  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.

46.1.1.10  –  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.

46.1.1.11  –  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.

46.1.1.12  –  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.

46.1.1.13  –  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.

46.1.2  –  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.

46.1.2.1  –  File Variable

  The 'file_variable' is the name of the file variable  associated
  with the file that VSI Pascal is to close.

46.1.2.2  –  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.

46.1.2.3  –  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.

46.1.2.4  –  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.

46.2  –  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.

46.2.1  –  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.

46.2.2  –  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.

46.2.3  –  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.

46.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.

46.3.1  –  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.

46.3.2  –  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.

46.3.3  –  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.

46.3.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.

46.4  –  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.

46.4.1  –  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.

46.4.2  –  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.

46.4.3  –  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.

46.4.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.

46.4.5  –  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.

46.5  –  Text File

  Text  file  manipulation  routines  apply  only  to  text  files
  (including INPUT, OUTPUT, and ERR).

46.5.1  –  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.

46.5.2  –  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.

46.5.3  –  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.

46.5.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.

46.5.5  –  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.

46.6  –  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.

46.6.1  –  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.

46.6.2  –  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.

46.6.3  –  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.

46.6.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.

46.7  –  Keyed Access

  Keyed access procedures are legal only on files opened for keyed
  access.

46.7.1  –  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.

46.7.2  –  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.

47  –  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.

47.1  –  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.

47.2  –  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.

48  –  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.

48.1  –  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.

48.2  –  Alignment

  Alignment attributes  indicate  whether  the  object  should  be
  aligned on a specific address boundary in memory.

48.2.1  –  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.

48.2.2  –  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.

48.3  –  Allocation

  Allocation attributes indicate the  form  of  storage  that  the
  object should occupy.

48.3.1  –  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.

48.3.2  –  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.

48.3.3  –  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.

48.3.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.

48.3.5  –  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.

48.4  –  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.

48.5  –  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.

48.6  –  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.

48.7  –  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.

48.8  –  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.

48.9  –  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.

48.10  –  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.

48.11  –  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.

48.12  –  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.

48.13  –  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.

48.13.1  –  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.

48.13.1.1  –  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.

48.13.1.2  –  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.

48.13.1.3  –  DESCENDING(see ASCENDING)

48.13.1.4  –  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.

48.14  –  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.

48.15  –  Optimize

  The optimization attributes  indicate  whether  the  VSI  Pascal
  compiler should optimize code.

48.15.1  –  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.

48.15.2  –  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.

48.16  –  Parameter

  The parameter passing attributes indicate the passing  mechanism
  to be used for a parameter.

48.16.1  –  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.

48.16.2  –  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.

48.16.3  –  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.

48.16.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.

48.16.5  –  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.

48.17  –  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.

48.18  –  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.

48.19  –  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.

48.20  –  Size

  Size attributes indicate the amount of storage  to  be  reserved
  for the object.

48.20.1  –  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.

48.20.2  –  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.

48.20.3  –  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.

48.20.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.

48.20.5  –  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.

48.20.6  –  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.

48.21  –  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.

48.22  –  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.

48.23  –  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.

48.24  –  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.

48.25  –  Visibility

  The visibility attributes indicate the ability of an  object  to
  be shared by compilation units.

48.25.1  –  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.

48.25.2  –  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.

48.25.3  –  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.

48.25.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.

48.25.5  –  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.

48.26  –  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.

48.27  –  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.

49  –  Directives

49.1  –  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.

49.2  –  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.

49.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.

49.4  –  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.

49.5  –  ELSE

  See the %IF directive for more information on how to use %ELSE.

49.6  –  ELIF

  See the %IF directive for more information on how to use %ELIF.

49.7  –  ENDIF

  See the %IF directive for more information on how to use %ENDIF.

49.8  –  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

49.9  –  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,... )

49.10  –  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,... )

49.11  –  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,... )

49.12  –  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,... )

49.13  –  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.

49.14  –  SYSTEM_NAME

  The %SYSTEM_NAME directive returns the string "OpenVMS".

49.15  –  SYSTEM_VERSION

  The %SYSTEM_VERSION directive returns a  string  containing  the
  value  of  the  SYI$_VERSION  itemcode  from  the $GETSYI system
  service.

49.16  –  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.

49.17  –  COMPILER_VERSION

  The %COMPILER_VERSION directive returns a string containing  the
  version of the VSI Pascal compiler performing the compilation.

49.18  –  LINE

  The %LINE directive returns an integer that denotes the  current
  line number in the source file.

49.19  –  FILE

  The %FILE directive returns a string containing  the  file  name
  that is currently being compiled.

49.20  –  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.

49.21  –  MODULE

  The %MODULE directive returns a string containing  the  name  of
  the MODULE/PROGRAM being compiled.

49.22  –  IDENT

  The %IDENT directive returns a string that  contains  the  ident
  string  of  the  compilation.   The ident string is set with the
  IDENT attribute.

49.23  –  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.

49.24  –  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.

49.25  –  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

49.26  –  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

49.27  –  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

49.28  –  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

50  –  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 *)

51  –  Release Notes

  Please refer to SYS$HELP:PASCAL%%%.RELEASE_NOTES for VSI  Pascal
  release notes.
Close Help