VMS Help  —  PASCAL  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.

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.

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.

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'

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'

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.

1.3  –  INTEGER8

  The INTEGER8 predefined type is equivalent to the following:

  Syntax:

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

1.4  –  INTEGER16

  The INTEGER16 predefined type is equivalent to the following:

  Syntax:

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

1.5  –  INTEGER32

  The INTEGER32 predefined type is equivalent to the following:

  Syntax:

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

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.

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.

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'

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'

1.9  –  UNSIGNED8

  The UNSIGNED8 data type is equivalent to the following:

  Syntax:

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

1.10  –  UNSIGNED16

  The UNSIGNED16 data type is equivalent to the following:

  Syntax:

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

1.11  –  UNSIGNED32

  The UNSIGNED32 data type is equivalent to the following:

  Syntax:

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

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}

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)

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.

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.

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.

2  –  Real

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

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.

2.2  –  SINGLE

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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

3.3  –  UNIV_PTR

  The predefined UNIV_PTR type is equivalent to:

  TYPE
      UNIV_PTR = POINTER;

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.

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;

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.

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.

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)

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

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.

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.

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

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

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.

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

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.

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.

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.

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.

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.

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

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.

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.

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.

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'

7  –  Misc Types

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

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.
Close Help