/* Test the two-stack Polish evaluation algorithm. */

#include "polish.h"

int main(void)
{
   char    str[] = "13 4.5 - 2 3 * +";
   stack   polish;
   node f1, f2, f3, a1, m1, s1, d1;


   init_node(&f1);
   init_node(&f2);
   init_node(&f3);
   init_node(&a1);
   init_node(&m1);
   init_node(&s1);
   init_node(&d1);

   f1.val=10;
   f2.val=0;
   f3.val=0.5;
   a1.op='+';
   m1.op='*';
   s1.op='-';
   d1.op='/';
  
   init_stack(&polish);
   printf("test of printing\n");
   push(f1, &polish);
   push(f3, &polish);
   push(a1, &polish);

   printstack(&polish);
   if ( evaluate (&polish) != (f1.val + f3.val) )
     printf("error in + %f", pop( &polish));
   pop( &polish );


   push(f1, &polish);
   push(f3, &polish);
   push(m1, &polish);

   if ( evaluate (&polish) != (f1.val * f3.val) )
     printf("error in m %f", pop( &polish));
   pop( &polish );

   push(f1, &polish);
   push(f3, &polish);
   push(d1, &polish);

   if ( evaluate (&polish) != (f1.val / f3.val) )
     printf("error in / %f", pop( &polish));
   pop( &polish );

   push(f1, &polish);
   push(f3, &polish);
   push(s1, &polish);

   if ( evaluate (&polish) != (f1.val - f3.val) )
     printf("error in + %f", pop( &polish));
   pop( &polish );

   /*test of f1 f3 - f2 * */
   push(f1, &polish);
   push(f3, &polish);
   push(s1, &polish);
   push(f2, &polish);
   push(m1, &polish);


   if ( evaluate (&polish) != ((f1.val - f3.val) * f2.val) )
     printf("error in complex %f", pop( &polish));
   pop( &polish );

   push(f1, &polish);
   push(f3, &polish);
   push(s1, &polish);
   push(f2, &polish);
   push(f1, &polish);
   push(a1, &polish);
   push(m1, &polish);

   if ( evaluate (&polish) != ((f1.val - f3.val) * (f2.val+f1.val)) )
     printf("error in complex 2 %f", pop( &polish));
   pop( &polish );


   return 0;
}


float evaluate(stack *polish)
{
   node op, d1, d2;

   if ( !empty(polish) ) {
     op = pop(polish);

     d1 = pop(polish);
     while ( !isspace(d1.op) ) {
       push(d1, polish);
       evaluate(polish);
       d1 = pop(polish);
     }

     d2 = pop(polish);
     while ( !isspace(d2.op) ) {
       push(d2, polish);
       evaluate(polish);
       d2 = pop(polish);
     }
     
     switch (op.op) {
     case '+': 
       d1.val = d2.val+d1.val;
       break;
     case '-':  
       d1.val = d2.val-d1.val;
       break;
     case '*':  
       d1.val = d2.val*d1.val;
       break;
     case '/':  
       d1.val = d2.val/d1.val;
       break;
     }
     
     d2 = pop(polish);
     if ( !empty(polish) && !isspace(d2.op) ) {
       push(d2, polish);
       evaluate(polish);
     }
     push(d1, polish);
     return d1.val;
   }
   else 
     return 0;
}

