Typed Enumerations

A typed enumeration is an enumeration that is defined with a data-type keyword. See Data-type keywords supported for enumerations for the data-type keywords you can specify.

A typed enumeration has a default value. You can use the DFT keyword to identify one of the constants as the default value for the enumeration. Otherwise, the first constant specified for the enumeration is the default value. In the following example, the default constant for the status_codes enumeration is the first constant, no_error, because none of the constants has the DFT keyword. The default constant for the employee_types enumeration is regular because it has the DFT keyword.

DCL-ENUM status_codes INT(10);
   no_error 0;
   customer_not_found 1;
   order_not_found 2;
END-ENUM;

DCL-ENUM employee_types CHAR(3) QUALIFIED;
   ceo 'CEO';
   manager 'MGR';
   regular 'REG' DFT;
END-ENUM;

Defining an item like a typed enumeration

You can define a variable, a prototyped parameter, or the return value of a prototype like a typed enumeration.

The CCSID keyword cannot be specified for an item defined like an enumeration. The CCSID of the new item is the same as the CCSID of the enumeration.

Figurative constants *HIVAL and *LOVAL cannot be used with items defined like an enumeration. Use %HIVAL or %LOVAL for the high or low value of the item.

Other items related to an item defined like a typed enumeration

When an item is defined like a typed enumeration, the following are considered to be related to the item:
  • The name of one of the enumeration constants.
  • The name of another item that is defined like the enumeration. In the following example, both like_en1 and like_like_en1 are considered to be defined like the enumeration en1.
    
       DCL-ENUM en1 INT(10);
          v1 1;
       END-ENUM;
       DCL-S like_en1 LIKE(en1);
       DCL-S like_like_en1 LIKE(like_en1);
    
  • %HIVAL and %LOVAL where the parameter can be the enumeration or an item defined like the enumeration.

Rules for variables that are defined like an enumeration

  • The parameter for the INZ keyword must be the name of one of the enumeration constants.
  • If the INZ keyword is not specified, the variable is initialized to the default constant.
  • The CLEAR operation code clears the variable to the default value of the enumeration. This might not be the same as the normal default value for the data type.
  • The result of the %HIVAL or %LOVAL built-in function for the variable returns the same value for the variable as it returns for the enumeration. See %HIVAL and %LOVAL (Highest Value or Lowest Value).
In the following example:
  1. The default constant for enumeration employee_types is regular.
  2. The INZ keyword is specified for the dept data structure, so every subfield is initialized, either to the value specified by the INZ keyword for the subfield or for the default value for the subfield.
  3. Subfield manager.type is defined like the enumeration. The subfield is explicitly initialized to employee_types.manager ('MGR').
  4. Subfield employees.type is also defined like the enumeration. The subfield is not explicitly initialized so it is initialized to its default value, which is the default constant for the enumeration, regular ('REG').
  5. The parameter for the get_bonus procedure is also defined like the enumeration. When the parameter is used in the IF and ELSEIF operations, it is compared to the constant names in the enumeration.

CTL-OPT CCSID(*EXACT);

DCL-ENUM employee_types CHAR(3) QUALIFIED;
   ceo 'CEO';
   manager 'MGR';
   regular 'REG' DFT; //  1 
END-ENUM;

DCL-DS emp_info_t QUALIFIED TEMPLATE;
   name VARCHAR(50);
   salary PACKED(7 : 2);
END-DS;

DCL-DS dept INZ QUALIFIED; //  2 
   DCL-DS manager;
      type LIKE(employee_types) INZ(employee_types.manager); //  3 
      info LIKEDS(emp_info_t);
   END-DS;

   num_employees INT(10);
   DCL-DS employees DIM(20);
      type LIKE(employee_types); //  4 
      info LIKEDS(emp_info_t);
   END-DS;
END-DS;

DCL-PROC get_bonus;
   DCL-PI *N PACKED(5 : 2);
      emp_type LIKE(employee_types); //  5 
   END-PI;

   IF emp_type = employee_types.ceo;         //  5 
      RETURN 0;
   ELSEIF emp_type = employee_types.manager; //  5 
      RETURN 100;
   ELSEIF emp_type = employee_types.regular; //  5 
      RETURN 200;
   ENDIF;
END-PROC;

Rules for assignment, prototyped parameters, and return values defined like an enumeration

Consider the following definitions in this section.


   DCL-ENUM en1 INT(10) QUALIFIED;
      v1 1;
      v2 2;
   END-ENUM;

   DCL-ENUM en2 INT(5) QUALIFIED;
      v1 1;
      v2 2;
   END-ENUM;

   DCL-S fld1 INT(10);
The following rules apply to
  • Assignment to a variable defined like an enumeration
    
       DCL-S like_en1 LIKE(en1);
       DCL-S like_like_en1 LIKE(like_en1);
       DCL-S array_like_en1 LIKE(en1) DIM(5);
    
  • Passing a value to a parameter defined like an enumeration
    
       DCL-PR proc1;
          parm1 LIKE(en1);
       END-PR;
    
       DCL-PR proc2_const;
          parm1 LIKE(en1) CONST;
       END-PR;
    
  • Returning a value from a procedure defined like an enumeration
    
       DCL-PROC proc_return;
          DCL-PI *N LIKE(en1) END-PI;
    
          RETURN ...
       END-PROC;
    
  1. The following can be assigned to the variable, passed to the parameter, or returned from the procedure:
    • An item that is related to the variable. See Other items related to an item defined like a typed enumeration.
      
               like_en1 = like_like_en1;
               like_en1 = en1.v2;
               like_en1 = proc_return ();
               array_like_en1 = en1;
               array_like_en1 = like_en1;
      
               proc1 (like_en1);
               proc2_const (en1.v1);
      
               DCL-PROC proc_return;
                  DCL-PI *N LIKE(en1) END-PI;
                  ...
                     RETURN like_en1;
                  ...
                     RETURN like_like_en1;
                  ...
                     RETURN en1.v1;
               END-PROC;
            
    • A variable that is valid for data type of the enumeration.
      
               like_en1 = fld1;
      
               proc1 (fld1);
               proc1_const (fld1);
      
               DCL-PROC proc_return;
                  DCL-PI *N LIKE(en1) END-PI;
      
                  RETURN fld1;
               END-PROC;
            
    • An expression whose value is not known at compile-time and whose data type is valid for the enumeration.
      
               like_en1 = fld1 + 5;
      
               proc1 (fld1 + 5);
               proc2 (fld1 + 5);
      
               DCL-PROC proc2;
                  DCL-PI *N LIKE(en1) END-PI;
      
                  RETURN fld1 + 5;
               END-PROC;
            
    Note: There is no runtime checking to ensure that variables and expressions contain one of the values in the enumeration.
  2. The following cannot be assigned to the variable, passed to the parameter, or returned from the procedure:
    • A literal
      
               like_en1 = 1;        //  ERROR 
      
               proc1_const (1);     //  ERROR 
      
               DCL-PROC proc_return;
                  DCL-PI *N LIKE(en1) END-PI;
      
                  RETURN 1;         //  ERROR 
               END-PROC;
            
    • A named constant
      
               DCL-C con1 1;
      
               like_en1 = con1;     //  ERROR 
      
               proc1_const (con1);  //  ERROR 
      
               DCL-PROC proc_return;
                  DCL-PI *N LIKE(en1) END-PI;
      
                  RETURN con1;      //  ERROR 
               END-PROC;
            
    • A constant from a different enumeration.
      
               like_en1 = en2.v1;     //  ERROR 
      
               proc1_const (en2.v1);  //  ERROR 
      
               DCL-PROC proc_return;
                  DCL-PI *N LIKE(en1) END-PI;
      
                  RETURN en2.v1;      //  ERROR 
               END-PROC;
            
    • An expression whose value is known at compile-time.
      
               like_en1 = 5 + 2;      //  ERROR 
      
               proc1_const (5 + 2);   //  ERROR 
      
               DCL-PROC proc_return;
                  DCL-PI *N LIKE(en1) END-PI;
      
                  RETURN 5 + 2;       //  ERROR 
               END-PROC;
            

Rules for prototyped parameters with OPTIONS(*EXACT)

When OPTIONS(*EXACT) is specified for a parameter defined like an enumeration, only items that are related to the enumeration can be passed as a parameter.

In the following example:
  1. The parameter for procedure like_enum_no_exact is not defined with OPTIONS(*EXACT).
  2. The parameter for procedure like_enum_exact is defined with OPTIONS(*EXACT).
  3. The parameter passed to both procedures is a constant from the enumeration. This is allowed for both calls.
  4. The parameter passed to both procedures is a literal value. This is not allowed for either call.
  5. The parameter passed to both procedures is a field name that is not defined like the enumeration.
    • This is allowed for procedure like_enum_no_exact.
    • This is not allowed for procedure like_enum_exact.
  6. The parameter passed to both procedures is an expression.
    • This is allowed for procedure like_enum_no_exact.
    • This is not allowed for procedure like_enum_exact.

DCL-ENUM enum1 INT(10) QUALIFIED;
   v1 5;
   v2 10;
END-ENUM;

DCL-PR like_enum_no_exact;
   p1 LIKE(enum1) CONST; //  1 
END-PR;

DCL-PR like_enum_exact;
   p1 LIKE(enum1) CONST OPTIONS(*EXACT);  //  2 
END-PR;

DCL-S num INT(10);

like_enum_no_exact (enum1.v1);  // OK  3 
like_enum_exact (enum1.v1);     // OK  3 

like_enum_no_exact (5);         // NOT OK  4 
like_enum_exact (5);            // NOT OK  4 

like_enum_no_exact (num);       // OK  5 
like_enum_exact (num);          // NOT OK  5 

like_enum_no_exact (num + 1);   // OK  6 
like_enum_exact (num + 1);      // NOT OK  6 

Data-type keywords supported for enumerations

Character, graphic, and UCS-2 data-type keywords
CHAR and VARCHAR

The enumeration can contain either character literals or hexadecimal literals depending on the CCSID.

The CCSID keyword can be specified. If it is not specified, the CCSID defaults to the current default CCSID for character data. See /SET for more information about the current default CCSID.

If the CCSID is 65535 or *HEX, the enumeration must contain only hexadecimal literals.

If the CCSID is not 65535 or *HEX, the enumeration must contain only character literals.

If the enumeration does not contain hexadecimal literals, Control keyword CCSID(*EXACT) must be specified.

GRAPH and VARGRAPH

The enumeration must contain graphic literals.

The CCSID keyword can be specified. If it is not specified, the CCSID defaults to the current default CCSID for graphic data. See /SET for more information about the current default CCSID.

The CCSID cannot be *JOBRUN.

Control keyword CCSID(*EXACT) must be specified.

Control keyword CCSID(*GRAPH:*IGNORE) cannot be specified.

UCS2 and VARUCS2

The enumeration can contain character literals, graphic literals, and UCS-2 literals.

Control keyword CCSID(*EXACT) must be specified if it contains any character literals or graphic literals.

The CCSID keyword can be specified. If it is not specified, the CCSID defaults to the current default CCSID for UCS-2 data. See /SET for more information about the current default CCSID.

Numeric data-type keywords
INT
The enumeration must contain numeric literals with no decimal positions.
UNS
The enumeration can contain positive numeric literals with no decimal positions and hexadecimal literals.
BINDEC, PACKED, and ZONED
The enumeration can contain any non-float numeric literals.
FLOAT
The enumeration must contain float numeric literals.
Other data-type keywords
IND
The enumeration must contain character literals with the value '0' or '1'.
DATE

The enumeration must contain date literals.

If the date format is not specified for the DATE keyword, the format defaults to tge current default date format. See /SET for more information about the current default date format.

If the date format has 2-digit years (*MDY, *DMY, *YMD, and *JUL), the default date format for the module must also be a format with 2-digit years. The default date format for the module is specified by the DATFMT Control keyword.

TIME

The enumeration must contain time literals.

If the time format is not specified for the TIME keyword, the format defaults to the current default time format. See /SET for more information about the current default time format.

If the time format is *USA, the default time format for the module must also be *USA. The default time format for the module is specified by the TIMFMT Control keyword.

TIMESTAMP

The enumeration must contain timestamp literals.

The number of fractional seconds for the timestamp must be between 6 and 12. If the parameter of the TIMESTAMP keyword is specified, it must be between 6 and 12.

Diagnostic messages from the compiler related to typed enumerations

Many messages issued by the compiler for coding errors related to typed enumerations have reason codes.

The constant is incompatible with the type of the enumeration.
The reason codes are
  • DECPOS: The number of decimal positions is greater than the number of decimal positions of the enumeration.
  • INDICATOR_VALUE: The literal is not '0' or '1' for an enumeration of type IND.
  • LEN: The constant is too long for the type of the enumeration.
  • NUM_HEX_LITERAL_UNS_ONLY: Hexadecimal literals are not allowed for enumerations defined with numeric types unless the type is UNS.
  • RANGE: The numeric literal is out of range for the type of the enumeration. For example, if the type of the enumeration is UNS(5), the valid range is 0 - 65535. The value 65536 is out of range.
  • TYPE: The data type of the constant does not match the data type of the enumeration.
The constant is incompatible with the CCSID of the enumeration.
The reason codes are
  • CANNOT_CONVERT_CCSID: The literal cannot be converted from the CCSID of the source file to the CCSID of the enumeration.
  • CCSID_CONVERT_LEN: The literal is too long after it is converted from the CCSID of the source file to the CCSID of the enumeration. For example, the literal 'ábç' has 3 bytes in an EBCDIC source file, but it has 5 bytes when converted to UTF-8. If the CCSID of the enumeration is 1208 or *UTF8, the length must be at least 5.
  • HEX_LITERAL_FOR_NON_HEX_CCSID: A hexadecimal literal cannot be specified when the CCSID of the enumeration is not 65535 or *HEX.
  • NON_HEX_LITERAL_FOR_HEX_CCSID: A hexadecimal literal must be specified when the CCSID of the enumeration is 65535 or *HEX.
Several messages related to calculations with items defined like enumerations.
The messages are:
  • The item is not valid for assignment to a field defined like an enumeration.
  • The item is not valid for passing to a parameter defined like an enumeration.
  • The item is not valid for the RETURN operation for a procedure that returns a value defined like an enumeration.
The reason codes for these messages indicate why the item is not valid with the variable, parameter, or procedure that is defined like an enumeration.
  • DIFF_ENUM:
    • An array defined like an enumeration is assigned from a different enumeration.
  • DIFF_ENUM_CONST:
    • A named constant from a different enumeration is not allowed.
    • %HIVAL or %HIVAL is not allowed if the parameter of the built-in function is another enumeration or an item defined like another enumeration.
  • FIG_CONST_NOT_ALLOWED:
  • LITERAL_NOT_ALLOWED: A literal is not allowed. Literals are not allowed even if they are the same as one of the constants in the enumeration. Use the name of the enumeration constant instead.
  • NON_ENUM_CONST: A named constant is not allowed if it is not one of the named constants in the enumeration.