//
//  NAME
//    eval.cpp
//
//  DESCRIPTION
//    This file contains functions used to implement the Evaluation
//    module.
//
//    For descriptions of the parameters and return values of 
//    exported (non-static) functions, see eval.h.
//


//
//  Include files.
//

#include <stdlib.h>
#include <iostream.h>
#include "bool.h"
#include "eval.h"


//
//  NAME
//    evaluate
//
//  DESCRIPTION
//    This function evaluates the given expression by first
//    recursively evaluating the subexpressions, then applying
//    the operation to the resulting values.
//

double evaluate(const expr * e) {

   switch (e->oper) {

      case Constant: {
	 return e->number;
	 }

      case Addition: {
         return evaluate(e->op1) + evaluate(e->op2);
         }

      case Subtraction: {
         return evaluate(e->op1) - evaluate(e->op2);
         }

      case Multiplication: {
         return evaluate(e->op1) * evaluate(e->op2);
         }

      case Division: {
         return evaluate(e->op1) / evaluate(e->op2);
         }

      }

   return 0.0;   //  This line should never be reached.
}


//
//  NAME
//    freeExpr
//
//  DESCRIPTION
//    This function frees the memory allocated to an expression.
//

void freeExpr(expr * e) {

   if (e == NULL) {
      return;
      }

   freeExpr(e->op1);
   freeExpr(e->op2);
   delete e;

   return;
}


//
//  NAME
//    display
//
//  DESCRIPTION
//    This function displays an expression.
//

void display(const expr * e) {

   if (e == NULL) {
      cout << "(NULL)";
      return;
      }

   switch (e->oper) {

      case Constant : {
         cout << e->number;
         break;
         }

      case Addition: {
         cout << "(+ ";
         display(e->op1);
         cout << " ";
         display(e->op2);
         cout << ")";
         break;
         }

      case Subtraction: {
         cout << "(- ";
         display(e->op1);
         cout << " ";
         display(e->op2);
         cout << ")";
         break;
         }

      case Multiplication: {
         cout << "(* ";
         display(e->op1);
         cout << " ";
         display(e->op2);
         cout << ")";
         break;
         }

      case Division: {
         cout << "(/ ";
         display(e->op1);
         cout << " ";
         display(e->op2);
         cout << ")";
         break;
         }

      }



   return;
}


//
//  End of file.
//