10.8 Repetitive Compilation (Compile Time Loops)


10.8 Repetitive Compilation (Compile Time Loops)

HLA's #while..#endwhile and #for..#endfor statements provide compile time loop constructs. The #while statement tells HLA to process the same sequence of statements repetitively during compilation. This is very handy for constructing data tables as well as providing a traditional looping structure for compile time programs. Although you will not employ the #while statement anywhere near as often as the #if statement, this compile time control structure is very important when you write advanced HLA programs.

The #while statement uses the following syntax:

 #while( constant_boolean_expression )      << text >> #endwhile 

When HLA encounters the #while statement during compilation, it will evaluate the constant boolean expression. If the expression evaluates false, HLA will skip over the text between the #while and the #endwhile clause (the behavior is similar to the #if statement if the expression evaluates false). If the expression evaluates true, then HLA will process the statements between the #while and #endwhile clauses and then "jump back" to the start of the #while statement in the source file and repeat this process, as shown in Figure 10-3.

start figure

 #while(constant_boolean_expression)           HLA repetitively compiles this code           as long as the expression is true.           It effectively inserts multiple copies           of this statement sequence into your           source file (the exact number of copies           depends on the value of the loop control           expression). endwhile 

end figure

Figure 10-3: HLA Compile Time #WHILE Statement Operation.

To understand how this process works, consider the program in Listing 10-2.

Listing 10-2: #WHILE..#ENDWHILE Demonstration.

start example
 program ctWhile; #include( "stdlib.hhf" ) static ary: uns32[5] := [ 2, 3, 5, 8, 13 ]; begin ctWhile;      ?i := 0;      #while( i < 5 )           stdout.put( "array[ ", i, " ] = ", ary[i*4], nl );           ?i := i + 1;      #endwhile end ctWhile; 
end example

As you can probably surmise, the output from this program is the following:

 array[ 0 ] = 2 array[ 1 ] = 3 array[ 2 ] = 4 array[ 3 ] = 5 array[ 4 ] = 13 

What is not quite obvious is how this program generates this output. Remember, the #while..#endwhile construct is a compile time language feature, not a run-time control construct. Therefore, the previous #while loop repeats five times during compilation. On each repetition of the loop, the HLA compiler processes the statements between the #while and #endwhile clauses. Therefore, the preceding program is really equivalent to the code that is shown in Listing 10-3.

Listing 10-3: Program Equivalent to the Code in Listing 10-2.

start example
 program ctWhile; #include( "stdlib.hhf" ) static      ary: uns32[5] := [ 2, 3, 5, 8, 13 ]; begin ctWhile;      stdout.put( "array[ ", 0, " ] = ", ary[0*4], nl );      stdout.put( "array[ ", 1, " ] = ", ary[1*4], nl );      stdout.put( "array[ ", 2, " ] = ", ary[2*4], nl );      stdout.put( "array[ ", 3, " ] = ", ary[3*4], nl );      stdout.put( "array[ ", 4, " ] = ", ary[4*4], nl ); end ctWhile; 
end example

As you can see, the #while statement is very convenient for constructing repetitivecode sequences. This is especially invaluable for unrolling loops. Additional uses of the #while loop appear in later sections of this text.

HLA provides three forms of the #for..#endfor loop. These three loops take the following general form:

 #for( valObject := startExpr to endExpr )      .      .      . #endfor #for( valObject := startExpr downto endExpr )      .      .      . #endfor #for( valObject in composite_expr )      .      .      . #endfor 

As its name suggests, valObject must be an object you've defined in a val declaration (or must be currently undefined; these #for loops will define the symbol locally for you if the loop control variable is undefined).

For the first two forms of the #for loop above, the startExpr and endExprcomponents can be any HLA constant expression that yields an integer value. The first of these #for loops is semantically equivalent to the following #while code:

 ?valObject := startExpr; #while( valObject <= endExpr )          .          .          .     ?valObject := valObject + 1; #endwhile 

The second of these #for loops is semantically equivalent to the #while loop:

 ?valObject := startExpr; #while( valObject >= endExpr )          .          .          .     ?valObject := valObject - 1; #endwhile 

The third of these #for loops (the one using the in keyword) is especially useful for processing individual items from some composite data type. This loop repeats once for each element, field, character, and so on, of the composite value you specify for composite_expr. This can be an array, string, record, or character set expression. For arrays, this #for loop repeats once for each element of the array and on each iteration of the loop; the loop control variable contains the current element's value. For example, the following compile time loop displays the values ‘1,’ ‘10,’ ‘100,’ and ‘1000’:

 #for( i in [1, 10, 100, 1000])      #print( i ) #endfor 

If the composite_expr constant is a string constant, the #for loop repeats once for each character in the string and sets the value of the loop control variable to the current character. If the composite_expr constant expression is a record constant, then the loop will repeat once for each field of the record and on each iteration the loop control variable will take on the type and value of the current field. If the composite_expr expression is a character set, the loop will repeat once for each character in the set, and the loop control variable will be assigned that character.

The #for loop actually turns out to be more useful than the #while loop because the larger number of compile time loops you encounter repeat a fixed number of times (e.g., processing a fixed number of array elements, macro parameters, and so on). However, because #for was added relatively late in HLA's design, you'll still see a large number of #while loops in existing source code (most of those are simulating a #for loop).




The Art of Assembly Language
The Art of Assembly Language
ISBN: 1593272073
EAN: 2147483647
Year: 2005
Pages: 246
Authors: Randall Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net