TOC PREV NEXT INDEX

Put your logo here!



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.


Web Site Hits Since
Jan 1, 2000

TOC PREV NEXT INDEX