dcl Next_color ordinal Color;
do Next_color = first (:Color:)
repeat ordinalsucc( Next_color )
until (Next_color = last (:Color:));
display( ordinalname( Next_color ) );
end;
do Next_color = last (:Color:)
repeat ordinalpred( Next_color)
until (Next_color = first(:Color:);
display( ordinalname( Next_color));
end;
The sample output for the first loop would be:
RED ORANGE YELLOW GREEN BLUE INDIGO VIOLET
An ordinal cannot be used as an index into an array and cannot define an extent for a variable, including the lower or upper bound of an array. However, an ordinal can be converted to binary using the BINARYVALUE built-in function. The value which is returned by this function can then be used to index into an array or define an extent.
For example, the following package defines an array usage_count to hold the number of times each color is used, a procedure Record_usage to update this array, and a procedure Show_usage to display the values in this array.
Usage: package exports(*);
define ordinal Color ( Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet );
dcl Usage_count( binvalue( first(:Color:))
: binvalue( last(:Color:)) )
static fixed bin(31) init( (*) 0 );
/* first(:Color:) = Red */
/* last(:Color:) = Violet */
Record_usage: proc (Wall_color );
dcl Wall_color type Color parm byvalue;
Usage_count( binvalue(Wall_color) )
= 1 + Usage_count( binvalue(Wall_color) );
end Record_usage;
Show_usage: proc;
dcl Next_color type Color;
do Next_color = Red upthru Violet;
put skip list( ordinalname( Next_color) );
put list( Usage_count( binvalue(Next_color) ));
end;
end Show_usage;
end Usage;
Ordinals can be used to create functions that are easy to maintain and enhance, but which are as efficient as table look-ups.
In the following example, the function Is_mellow returns a bit indicating whether a color is or is not "mellow". If more colors are defined, the "mellow" ones can be added to the list of colors in the select-group. In a select-group, unlike a hand-built table, the colors do not have to be in the same order as in the DEFINE statement, or in any particular order at all.
However, since all of the statements inside the select-group consist of RETURN statements that return constant values, the compiler will convert the entire select-group into a simple table look-up.
Is_mellow: proc( Test_color ) returns( bit(1) aligned );
dcl Test_color type Color parm byvalue;
select (Test_color);
when( Yellow, Indigo)
return( '1'b );
otherwise
return( '0'b );
end;
end;
This feature can also be used to define your own version of the ORDINALNAME built-in function. Your own version can return the name you want to be displayed for each ordinal value. For example, the following function Color_name returns the color name associated with each name with the first letter capitalized:
Color_name: proc( Test_color ) returns( char(8) varying );
dcl Test_color type Color parm byvalue;
select (Test_color);
when ( Blue ) return( 'Blue');
when ( Green ) return( 'Green');
when ( Orange ) return( 'Orange');
when ( Red ) return( 'Red');
when ( Yellow ) return( 'Yellow');
otherwise return (");
end;
end;