Node: Transforming SELECT CASE, Previous: Transforming Block IF, Up: Transforming Statements



Transforming SELECT CASE

SELECT CASE poses a few interesting problems for code generation, if efficiency and frugal stack management are important.

Consider SELECT CASE (I('PREFIX'//A)), where A is CHARACTER*(*). In a case like this--basically, in any case where largish temporaries are needed to evaluate the expression--those temporaries should not be "live" during execution of any of the CASE blocks.

So, evaluation of the expression is best done within its own block, which in turn is within the SELECT CASE block itself (which contains the code for the CASE blocks as well, though each within their own block).

Otherwise, we'd have the rough equivalent of this pseudo-code:

     {
       char temp[large];
     
       libg77_catenate (temp, 'prefix', a);
     
       switch (i (temp))
         {
         case 0:
           ...
         }
     }
     

And that would leave temp[large] in scope during the CASE blocks (although a clever back end *could* see that it isn't referenced in them, and thus free that temp before executing the blocks).

So this approach is used instead:

     {
       int temp0;
     
       {
         char temp1[large];
     
         libg77_catenate (temp1, 'prefix', a);
         temp0 = i (temp1);
       }
     
       switch (temp0)
         {
         case 0:
           ...
         }
     }
     

Note how temp1 goes out of scope before starting the switch, thus making it easy for a back end to free it.

The problem that solution has, however, is with SELECT CASE('prefix'//A) (which is currently not supported).

Unless the GBEL is extended to support arbitrarily long character strings in its case facility, the FFE has to implement SELECT CASE on CHARACTER (probably excepting CHARACTER*1) using a cascade of if, elseif, else, and endif constructs in GBEL.

To prevent the (potentially large) temporary, needed to hold the selected expression itself ('prefix'//A), from being in scope during execution of the CASE blocks, two approaches are available:

Both of these solutions require SELECT CASE implementation to be changed so all the corresponding CASE statements are seen during the actual code generation for SELECT CASE.