> ##

> ## 3.13 Sample Programs

> This section presents two sample programs. The first demonstrates the use of iterators using a fibonacci number iterator. The second demonstrates the use of procedural parameters.

> ### 3.13.1 Generating the Fibonacci Sequence Using an Iterator

> The following program generates the Fibonacci sequence f1, f2, f3, ..., fcount where count is a parameter. This simple example displays all the fibonacci numbers the iterator generates.

>     program iterDemo;

>     #include( "stdlib.hhf" )

>         //  Basic (recursive version) algorithm for

>         //  the fibonacci sequence.

>         //

>         //  int fib(int N)

>         //  {

>         //      if(N<=2)

>         //          return 1;

>         //      else

>         //      return fib(N-1) + fib(N-2)

>         //  }

>         //

>         // Iterator (iterative) that computes all the fibonacci

>         // numbers between fib(1) and fib(count).

>         iterator fib( count:uns32 ); nodisplay;

>         var

>             lastVal:        uns32;

>             BeforeLastVal:  uns32;

>         begin fib;

>             if( count > 0 ) then

>                 mov( 0, BeforeLastVal );

>                 mov( 1, eax );

>                 mov( eax, lastVal );

>                 // Handle fib(1) as a special case.

>                 yield();

>                 dec( count );

>                 // Okay, handle fib(2)..fib(count) here.

>                 while( @nz ) do

>                     // Compute fib(n) = fib(n-1) + fib(n-2).

>                     // and then copy fib(n-1) {lastVal} to

>                     // fib(n-2) {BeforeLastVal} and store the

>                     // current result into lastVal so we'll

>                     // have the n-1 and n-2 values on the next

>                     // call.

>                     mov( lastVal, eax );

>                     add( BeforeLastVal, eax );

>                     mov( lastVal, BeforeLastVal );

>                     mov( eax, lastVal );

>                     // Yield fib(n) to the FOREACH loop.

>                     yield();

>                     // Repeat this iterator the specified number

>                     // of times.

>                     dec( count );

>                 endwhile;

>             endif;

>         end fib;

>     static

>         iteration:uns32;

>     begin iterDemo;

>         // Display the fibonacci sequence for the first

>         // ten fibonacci numbers.

>         mov( 1, iteration );

>         foreach fib( 10 ) do

>             stdout.put( "fib(", iteration, ") = ", (type uns32 eax), nl );

>             inc( iteration );

>         endfor;

>     end iterDemo;

> ### 3.13.2 Outer Product Computation with Procedural Parameters

> The following program generates an addition table, a subtraction table, or a multiplication table based on user inputs. These tables are computed using an outer product calculation and procedural parameters. An outer product is simply the process of computing all the values for the elements of a matrix by using the row and column indices as inputs to some function (e.g., addition, subtraction, or multiplication).

>     program funcTable;

>     #include( "stdlib.hhf" )

>     static

>         size: uns32;

>         ftbl: array.dArray( uns32, 2 );

>         // GenerateTable-

>         //

>         // This function computes the "Outer Product".  That is,

>         // take the cartesian product of the indices into

>         // the rows and columns of this array [(0,0), (0,1), ... (0,size-1),

>         // (1,0), (1,1), ..., (size-1,size-1)], then feed the left and

>         // right values of each coordinate to the "func" procedure passed

>         // as a parameter.  Whatever result the function returns, store that

>         // into element (l,r) of the ftbl array.

>         procedure GenerateTable( func:procedure( l:uns32; r:uns32 )); nodisplay;

>         begin GenerateTable;

>             push( eax );

>             push( ebx );

>             push( ecx );

>             push( edi );

>             for( mov( 0, ebx ); ebx < size; inc( ebx )) do

>                 for( mov( 0, ecx ); ecx < size; inc( ecx )) do

>                     array.index( edi, ftbl, ebx, ecx );

>                     func( ebx, ecx );

>                     mov( eax, [edi] );

>                 endfor;

>             endfor;

>             pop( edi );

>             pop( ecx );

>             pop( ebx );

>             pop( eax );

>         end GenerateTable;

>         // The following functions compute the various

>         // values used to fill the table (obviously,

>         // "+" = addFunc, "-" = subFunc, and "*" = mulFunc).

>         procedure addFunc( left:uns32; right:uns32 ); nodisplay;

>         begin addFunc;

>             mov( left, eax );

>             add( right, eax );

>         end addFunc;

>         procedure subFunc( left:uns32; right:uns32 ); nodisplay;

>         begin subFunc;

>             mov( left, eax );

>             sub( right, eax );

>         end subFunc;

>         procedure mulFunc( left:uns32; right:uns32 ); nodisplay;

>         begin mulFunc;

>             mov( left, eax );

>             intmul( right, eax );

>         end mulFunc;

>     begin funcTable;

>         stdout.put( "Function table generator: " nl );

>         stdout.put( "------------------------- " nl nl );

>         // Get the size of the function table from the user:

>         forever

>             try

>                 stdout.put( "Enter the size of the matrix: " );

>                 stdin.getu32();

>                 bound( eax, 1, 20 );

>                 unprotected break;

>               exception( ex.ConversionError )

>                 stdout.put( "Illegal character, re-enter" nl );

>               exception( ex.ValueOutOfRange )

>                 stdout.put( "Value out of range (1..20), please re-enter" nl );

>               exception( ex.BoundInstr )

>                 stdout.put( "Value out of range (1..20), please re-enter" nl );

>             endtry;

>         endfor;

>         // Allocate storage for the function table:

>         mov( eax, size );

>         array.daAlloc( ftbl, size, size );

>         // Get the function from the user:

>         stdout.put( "What type of table do you want to generate?" nl nl );

>         stdout.put( "+) Addition" nl );

>         stdout.put( "-) Subtraction" nl );

>         stdout.put( "*) Multiplication" nl );

>         stdout.newln();

>         repeat

>             stdout.put( "Choice? (+, -, *): " );

>             stdin.FlushInput();

>             stdin.getc();

>         until( al in {'+', '-', '*'} );

>         // Fill in the entries in the table:

>         if( al = '+' ) then

>             GenerateTable( &addFunc );

>         elseif( al = '-' ) then

>             GenerateTable( &subFunc );

>         elseif( al = '*' ) then

>             GenerateTable( &mulFunc );

>         endif;

>         // Display the column labels across the top:

>         stdout.put( nl nl "      " );

>         for( mov( 0, ebx ); ebx < size; inc( ebx )) do

>             stdout.put( (type uns32 ebx):5 );

>         endfor;

>         stdout.newln();

>         stdout.put( "      " );

>         for( mov( 0, ebx ); ebx < size; inc( ebx )) do

>             stdout.put( "-----" );

>         endfor;

>         stdout.newln();

>         // Display the row labels and fill in the table.

>         // Note that this code prints the result as int32

>         // rather than uns32 because the subFunc function

>         // returns negative values.

>         for( mov( 0, ebx); ebx < size; inc( ebx )) do

>             stdout.put( (type uns32 ebx):4, ": " );

>             for( mov( 0, ecx); ecx < size; inc( ecx )) do

>                 array.index( edi, ftbl, ebx, ecx );

>                 stdout.puti32size( [edi], 5, ' ' );

>             endfor;

>             stdout.newln();

>         endfor;

>     end funcTable;

> ## 3.14 Putting It All Together

> In this chapter you saw the low level implementation of procedures and calls to procedures. You learned more about passing parameters by value and reference and you also learned a little more about local variables. This chapter discussed activations records and HLA procedure options. Finally, this chapter wraps up with a discussion of iterators and the FOREACH loop

> Your journey through procedures is hardly complete, however. The next volume presents new ways to pass parameters, discusses nested procedures, and explains the low-level implementation of iterators. For more details, see the next volume in this series.