/***********************************************************************************
 * Chaga string arithmetic library                                                 *
 * Copyright (C) 2026 Robert James Bruce                                           *
 *                                                                                 *
 * This file is part of the Chaga string arithmetic library.                       *
 *                                                                                 *
 * The Chaga string arithmetic library is free software: you can redistribute it   * 
 * and/or modify it under the terms of the GNU General Public License as published *
 * by the Free Software Foundation, either version 3 of the License, or (at your   *
 * option) any later version.                                                      *
 *                                                                                 *
 * The Chaga string arithmetic library is distributed in the hope that it will be  *
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
 * License for more details.                                                       *
 *                                                                                 *
 * You should have received a copy of the GNU General Public License               *
 * along with the Chaga compiler. If not, see <https://www.gnu.org/licenses/>.     *
 ***********************************************************************************/
#include "include/libchaga-general_functions.h"
#include "include/libchaga-packed_string_integer_functions.h"
#include "include/libchaga-packed_string_float_functions.h"
#include "include/libchaga-diagnostic_tools.h"

digit_stack_node * push_digit_stack (digit_stack_node *digit_stack, unsigned char digit)
{
  digit_stack_node *new_element;
  unsigned char repacked_digits, nibble_lo, fourbit_digit;

  fourbit_digit = 0xf;
  switch (digit)
  {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      fourbit_digit = digit - '0';
    break;
    case '.':
      fourbit_digit = 0xa;
    break;
    case '+':
      fourbit_digit = 0xb;
    break;
    case '-':
      fourbit_digit = 0xc;
    break;
    default:
    break;
  }
  if ((fourbit_digit >= 0) && (fourbit_digit <= 0xc))
  {
    if (digit_stack != NULL) 
    {
      if ((digit_stack->stack_top_position >= 0) && (digit_stack->stack_top_position < MAX_DIGIT_STACK_BLOCK_SIZE))
      {
        if (digit_stack->stack_top_nibble_orientation == lo)
        {
          nibble_lo = digit_stack->digit[digit_stack->stack_top_position] & 0x0f;
          repacked_digits = (fourbit_digit << 4) + nibble_lo;
          digit_stack->digit[digit_stack->stack_top_position] = repacked_digits;
          digit_stack->stack_top_nibble_orientation = hi;
        }
        else
        {
          if (digit_stack->stack_top_nibble_orientation == hi)
          {
            if (digit_stack->stack_top_position + 1 < MAX_DIGIT_STACK_BLOCK_SIZE)
            {
              digit_stack->stack_top_position = digit_stack->stack_top_position + 1;
              digit_stack->digit[digit_stack->stack_top_position] = fourbit_digit;
              digit_stack->stack_top_nibble_orientation = lo;
            }
            else
            {
              new_element = (digit_stack_node *) malloc(sizeof(digit_stack_node));
              if (new_element != NULL)
              { 
                new_element->stack_top_position = 0;
                new_element->digit[0] = fourbit_digit;
                new_element->stack_top_nibble_orientation = lo;
                new_element->next = digit_stack;
                digit_stack = new_element;
              }
            }
          }
        }
      }
      else
      {
        new_element = (digit_stack_node *) malloc(sizeof(digit_stack_node));
        if (new_element != NULL)
        { 
          new_element->stack_top_position = 0;
          new_element->digit[0] = fourbit_digit;
          new_element->stack_top_nibble_orientation = lo;
          new_element->next = digit_stack;
          digit_stack = new_element;
        }
      }
    }
    else
    {
      new_element = (digit_stack_node *) malloc(sizeof(digit_stack_node));
      if (new_element != NULL)
      { 
        new_element->stack_top_position = 0;
        new_element->stack_top_nibble_orientation = lo;
        new_element->digit[0] = fourbit_digit;
        new_element->next = NULL;
        digit_stack = new_element;
      }
    }
  }
  return digit_stack;
}




digit_stack_node * pop_digit_stack (digit_stack_node *digit_stack)
{
  digit_stack_node *element;

  if (digit_stack != NULL)
  {
    if ((digit_stack->stack_top_position > 0) && (digit_stack->stack_top_position < MAX_DIGIT_STACK_BLOCK_SIZE))
    {
      if (digit_stack->stack_top_nibble_orientation == hi)
      {
        digit_stack->digit[digit_stack->stack_top_position] = digit_stack->digit[digit_stack->stack_top_position] & 0x0f; // erase the high nibble (pop).
        digit_stack->stack_top_nibble_orientation = lo;
      }
      else
      {
        if (digit_stack->stack_top_nibble_orientation == lo)
        {
          digit_stack->stack_top_position--;
          digit_stack->stack_top_nibble_orientation = hi;
        }
      }
    }
    else
    {
      if (digit_stack->stack_top_position == 0)
      {
        if (digit_stack->stack_top_nibble_orientation == hi)
        {
          digit_stack->digit[digit_stack->stack_top_position] = digit_stack->digit[digit_stack->stack_top_position] & 0x0f; // erase the high nibble (pop).
          digit_stack->stack_top_nibble_orientation = lo;
        }
        else
        {
          if (digit_stack->stack_top_nibble_orientation == lo)
          {
            element = digit_stack;
            digit_stack = digit_stack->next;
            free (element);
          } 
        }
      }
    }
  }
  return digit_stack;
}




unsigned char top_digit_stack (digit_stack_node *digit_stack)
{
  unsigned char byte, nibble;

  byte = 0; // NULL byte indicates an error occurred.
  if (digit_stack != NULL)
  {
    if ((digit_stack->stack_top_position >= 0) && (digit_stack->stack_top_position < MAX_DIGIT_STACK_BLOCK_SIZE))
    {
      if (digit_stack->stack_top_nibble_orientation == lo)
      {
        nibble = digit_stack->digit[digit_stack->stack_top_position] & 0x0f;
        switch (nibble)
        {
          case 0x0:
          case 0x1:
          case 0x2:
          case 0x3:
          case 0x4:
          case 0x5:
          case 0x6:
          case 0x7:
          case 0x8:
          case 0x9:
            byte = nibble + '0';
          break;
          case 0xa:
            byte = '.';
          break;
          case 0xb:
            byte = '+';
          break;
          case 0xc:
            byte = '-'; 
          break;
          default:
          break;
        }
      }
      else
      {
        if (digit_stack->stack_top_nibble_orientation == hi)
        {
          nibble = (digit_stack->digit[digit_stack->stack_top_position] & 0xf0) >> 4;
          switch (nibble)
          {
            case 0x0:
            case 0x1:
            case 0x2:
            case 0x3:
            case 0x4:
            case 0x5:
            case 0x6:
            case 0x7:
            case 0x8:
            case 0x9:
              byte = nibble + '0';
            break;
            case 0xa:
              byte = '.';
            break;
            case 0xb:
              byte = '+';
            break;
            case 0xc:
              byte = '-'; 
            break;
            default:
            break;
          }     
        }
      }
    }
  }
  return byte;
}




digit_queue_node * add_digit_queue (digit_queue_node *digit_queue, unsigned char digit)
{
  digit_queue_node *new_element, *temp_element;

  new_element = (digit_queue_node *) malloc(sizeof(digit_queue_node));
  if (new_element != NULL)
  {
    new_element->digit = digit;
    new_element->next = NULL;
  }
  if (digit_queue != NULL)
  {
    temp_element = digit_queue;
    while (temp_element->next != NULL)
    {
      temp_element = temp_element->next;
    }
    temp_element->next = new_element;
  }
  else
  {
    digit_queue = new_element;
  }
  return digit_queue;
}




digit_queue_node * free_digit_queue (digit_queue_node *digit_queue)
{
  digit_queue_node *temp_element;

  while (digit_queue != NULL)
  {
    temp_element = digit_queue;
    digit_queue = digit_queue->next;
    free (temp_element);
  }
  return digit_queue;
}




// ***************************************************************************************************
// * packed_string_number_component_copy_number                                                      *
// *                                                                                                 *
// * This function makes a duplicate copy of a packed string number component (psnc) data structure. *
// *                                                                                                 *
// * Input:  The string-based number component to copy.                                              *
// * Output: NULL on failure; pointer to a string-based number component (psnc) on success.          *
// ***************************************************************************************************
psnc * packed_string_number_component_copy_number (psnc *number_copy_head, psnc *number)
{
  psnc *new_number_block, *number_copy_previous, *temp_num;
  int state;
  unsigned char nibble_lo, packed_byte;
  long long int i;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (number_copy_head != NULL)
  {
    number_copy_head = packed_string_component_release_memory (number_copy_head);
  }
  if (number != NULL)
  {
    state = 0;
    temp_num = number;
    while (temp_num != NULL)
    {
      new_number_block = (psnc *) malloc(sizeof(psnc));
      if (new_number_block != NULL)
      {
        new_number_block->highest_digit_position  = temp_num->highest_digit_position;
        new_number_block->highest_nibble_position = temp_num->highest_nibble_position;
        new_number_block->first_number_block      = NULL;
        new_number_block->last_number_block       = NULL;
        new_number_block->previous_number_block   = NULL;
        new_number_block->next_number_block       = NULL;
        for (i = temp_num->highest_digit_position + 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
        {
          new_number_block->packed_number_block[i] = 0;
        }
        for (i = 0; i < temp_num->highest_digit_position; i++)
        {
          new_number_block->packed_number_block[i] = temp_num->packed_number_block[i];
        }
        if (temp_num->highest_nibble_position == hi)
        {
          new_number_block->packed_number_block[i] = temp_num->packed_number_block[i];
        }
        else
        {
          packed_byte = temp_num->packed_number_block[i];
          nibble_lo = packed_byte & 0x0f;
          new_number_block->packed_number_block[i] = nibble_lo;
        }
        switch (state)
        {
          case 0:
            number_copy_head = new_number_block;
            number_copy_head->first_number_block = new_number_block;
            number_copy_previous = NULL;
            state  = 10;
          break;
          case 10:
            if (number_copy_previous != NULL)
            {
              number_copy_previous->next_number_block = new_number_block;
            }
            new_number_block->first_number_block    = number_copy_head;
            new_number_block->previous_number_block = number_copy_previous; 
          break;
          default:
          break;
        }
        number_copy_previous = new_number_block;
      }
      temp_num = temp_num->next_number_block;
    }
    if (new_number_block != NULL)
    {
      temp_num = number_copy_head;
      while (temp_num != NULL)
      {
        temp_num->last_number_block = new_number_block;
        temp_num = temp_num->next_number_block;
      }
    }
  }
  return number_copy_head;
} 





// ********************************************************************************************************
// * packed_string_component_release_memory                                                               *
// *                                                                                                      *
// * This function releases memory formerly allocated for a packed, string-based number component (psnc). *
// *                                                                                                      *
// * Input:  pointer to a string number                                                                   *
// * Output: NULL                                                                                         *
// ********************************************************************************************************
psnc * packed_string_component_release_memory (psnc *number_component)
{
  psnc *temp_number_component;

  while (number_component != NULL)
  {
    temp_number_component = number_component;
    number_component = number_component->next_number_block;
    free (temp_number_component);
    temp_number_component = NULL;
  }
  return number_component;
}



// ***********************************************************
// * count_num_digits_in_packed_string_integer               *
// *                                                         *
// * This function returns the number of digits in a number. *
// *                                                         *
// * Input: a packed, string-based integer.                  *
// * Output: the number of digits in the input number.       *
// ***********************************************************
long long int count_num_digits_in_packed_string_integer (psint *number)
{
  psnc *temp_number_component;
  long long int number_of_digits;

  number_of_digits = 0;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      temp_number_component = number->left_of_decimal;
      while (temp_number_component != NULL)
      {
        if (temp_number_component->highest_nibble_position == hi)
        {
          number_of_digits = number_of_digits + (temp_number_component->highest_digit_position + 1) * 2; // memory starts at zero therefore add one. Two digits per byte.
        }         
        else
        {
          number_of_digits = number_of_digits + (temp_number_component->highest_digit_position + 1) * 2 - 1;
        }
        temp_number_component = temp_number_component->next_number_block;
      }
    }
  }
  return number_of_digits;
}




// ************************************************************************************************
// * add_psint_element_to_list                                                                    *
// *                                                                                              *
// * This function adds one packed, string-based integer (psint) to a linked list data structure. * 
// *                                                                                              *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer).           *
// * Output: a linked-list containing two packed, string-based integer elements.                  *
// ************************************************************************************************
psint_list_node * add_psint_element_to_list (psint_list_node *psint_list, psint *number)
{
  psint_list_node *new_element;
  psint *new_number;

  if (number != NULL)
  {
    new_element = (psint_list_node *) malloc(sizeof(psint_list_node));
    if (new_element != NULL)
    {
      new_number = NULL;
      new_number = packed_string_integer_copy_number (new_number, number);
      new_element->element = new_number;
      new_element->next_element = psint_list;
      psint_list = new_element;
    }
    else
    {
      printf ("Error in create_psint_list: malloc function returned NULL. Exiting now.\n");
      exit (EXIT_FAILURE);
    }
  }
  return psint_list;
}  





// *********************************************************************************************
// * create_two_element_psint_list                                                             *
// *                                                                                           *
// * This function creates a two-element packed, string-based integer (psint) linked list data * 
// * structure. It is useful interally to create a function return list with two string-based  *
// * integer parameters.                                                                       *
// *                                                                                           *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer).        *
// * Output: a linked-list containing two packed, string-based integer elements.               *
// *********************************************************************************************
psint_list_node * create_two_element_psint_list (psint *num1, psint *num2)
{
  psint_list_node *psint_list, *num1_element, *num2_element;

  psint_list = NULL;
  num1_element = NULL;
  num2_element = NULL;
  if ((num1 != NULL) && (num2 != NULL))
  {
    num2_element = (psint_list_node *) malloc(sizeof(psint_list_node));
    if (num2_element != NULL)
    {
      num2_element->element = num2;
      num2_element->next_element = NULL;
      num1_element = (psint_list_node *) malloc(sizeof(psint_list_node));
      if (num1_element != NULL)
      {
        num1_element->element = num1;
        num1_element->next_element = num2_element;
        psint_list = num1_element;
      }
      else
      {
        printf ("Error in create_two_element_psint_list(): malloc function returned NULL. Exiting now.\n");
        exit (EXIT_FAILURE);
      }
    }
    else
    {
      printf ("Error in create_two_element_psint_list(): malloc function returned NULL. Exiting now.\n");
      exit (EXIT_FAILURE);
    }
  }
  return psint_list;
}  




runtime_expression_stack_node * push_operator_runtime_expression_stack (runtime_expression_stack_node *runtime_expression_stack, chaga_operator_type operator)
{
  runtime_expression_stack_node *new_element;

  new_element = (runtime_expression_stack_node *) malloc(sizeof(runtime_expression_stack_node));
  if (new_element != NULL)
  {
    new_element->operator = operator;
    new_element->operand_type = _nothing; // to indicate this entry on stack is an OPERATOR, not an OPERAND
    new_element->operand = NULL;          // initialize pointer to non-existant operand as well.
    new_element->ok_to_free_memory_for_operand = FALSE;
    new_element->next = runtime_expression_stack;
    runtime_expression_stack = new_element;
  }
  return runtime_expression_stack;
}




runtime_expression_stack_node * push_operand_runtime_expression_stack (runtime_expression_stack_node *runtime_expression_stack, chaga_operand_type operand_type, void *operand, unsigned char ok_to_free_memory_for_operand)
{
  runtime_expression_stack_node *new_element;

  if (operand != NULL)
  {
    new_element = (runtime_expression_stack_node *) malloc(sizeof(runtime_expression_stack_node));
    if (new_element != NULL)
    {
      new_element->operator = _none;   // to indicate this entry on stack is an OPERAND, not an OPERATOR.
      new_element->operand_type = operand_type;
      new_element->operand = NULL;
      new_element->ok_to_free_memory_for_operand = ok_to_free_memory_for_operand;
      switch (operand_type)
      {
        case _int:
          new_element->operand = operand;
        break;
        case _bool:
          new_element->operand = operand;
        break;
        case _float:
          new_element->operand = operand;
        break;
        default:
        break;
      }
      new_element->next = runtime_expression_stack;
      runtime_expression_stack = new_element;
    }
  }
  return runtime_expression_stack;
}




runtime_expression_stack_node * pop_runtime_expression_stack (runtime_expression_stack_node *runtime_expression_stack)
{
  runtime_expression_stack_node *top_element;
  
  if (runtime_expression_stack != NULL)
  {
    top_element = runtime_expression_stack;
    runtime_expression_stack = runtime_expression_stack->next;
    free (top_element);
  }
  return runtime_expression_stack;
}




// ********************************************************************************************
// * evaluate_runtime_expression_return_boolean_result                                        *
// *                                                                                          *
// * This subroutine evaluates an expression stack using Dijkstra's Shunting Yard algorithm.  *
// *                                                                                          *
// * The expression stack is comprised of the following in postfix order:                     *
// *       packed string float datatype (operand),                                            *
// *       packed string integer datatype (operand),                                          *
// *       Boolean datatype (operand),                                                        *
// *       plus (operator),                                                                   *
// *       minus (operator),                                                                  *
// *       times (operator),                                                                  *
// *       divide (operator),                                                                 *
// *       modulo (operator),                                                                 *
// *       and (operator),                                                                    *
// *       or (operator),                                                                     *
// *       not (operator)                                                                     *
// *                                                                                          *
// * This subroutine is called to evaluate Boolean expressions for the following statements:  *
// *       IF (BOOLEAN EXPRESSION) THEN                                                       *
// *       IF (BOOLEAN EXPRESSION) THEN-ELSE                                                  *
// *       DO-UNTIL (BOOLEAN EXPRESSION)                                                      *
// *       WHILE (BOOLEAN EXPRESSION)                                                         *
// *                                                                                          *
// * Note: the Boolean result is stored in temporary heap memory as is marked for deletion    *
// * (freeing the memory allocated for the temporary Boolean result on the heap) once one of  *
// * the statements above is evaluated.                                                       *
// *                                                                                          *
// * Return value: unsigned character return value containing either a 0 (FALSE) or 1 (TRUE). *
// ********************************************************************************************
unsigned char evaluate_runtime_expression_return_boolean_result (runtime_expression_stack_node *expression_stack)
{
  unsigned char boolean_expression_result;
  runtime_expression_stack_node *temp_expression_stack;
  psint *packed_string_integer, *packed_string_integer2, *packed_string_integer3;
  psflt *packed_string_float, *packed_string_float2, *packed_string_float3;
  unsigned char *bool_value, *bool_value2, *bool_value3;
  unsigned char bool_value_is_a_temporary_variable, bool_value2_is_a_temporary_variable, bool_value3_is_a_temporary_variable;

  temp_expression_stack  = NULL;
  packed_string_integer  = NULL;
  packed_string_integer2 = NULL;
  packed_string_integer3 = NULL;
  packed_string_float    = NULL;
  packed_string_float2   = NULL;
  packed_string_float3   = NULL;
  bool_value             = NULL;
  bool_value2            = NULL;
  bool_value3            = NULL;
  boolean_expression_result = 0; // initialize it.
  while (expression_stack != NULL)
  {
    if (expression_stack->operator == _none)
    {
      if (expression_stack->operand != NULL)
      {
        switch (expression_stack->operand_type)
        {
          case _int:
          case _float:
          case _bool:
            temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, expression_stack->operand_type, expression_stack->operand, expression_stack->ok_to_free_memory_for_operand);
            printf ("\n\nEXPRESSION STACK IS:\n");
            display_runtime_expression_stack (temp_expression_stack);
          break;
          default:
          break;
        }
      }
    }
    else
    {
      switch (expression_stack->operator)
      {
        case  _greater_than_or_equal:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      bool_value = (unsigned char *) malloc(sizeof(unsigned char));
                      if (bool_value != NULL)
                      {
                        *bool_value = packed_string_integer_greater_than_or_equal (packed_string_integer, packed_string_integer2);
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value, TRUE);
                      }
                      else
                      {
                        printf ("malloc() failed. Exiting now.\n");
                        exit (EXIT_SUCCESS);
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _greater_than:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      bool_value = (unsigned char *) malloc(sizeof(unsigned char));
                      if (bool_value != NULL)
                      {
                        *bool_value = packed_string_integer_greater_than (packed_string_integer, packed_string_integer2);
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value, TRUE);
                        //printf ("\n\nEXPRESSION STACK IS (after > operation):\n");
                        //display_runtime_expression_stack (temp_expression_stack);
                      }
                      else
                      {
                        printf ("malloc() failed. Exiting now.\n");
                        exit (EXIT_SUCCESS);
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _less_than_or_equal:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      bool_value = (unsigned char *) malloc(sizeof(unsigned char));
                      if (bool_value != NULL)
                      {
                        *bool_value = packed_string_integer_less_than_or_equal (packed_string_integer, packed_string_integer2);
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value, TRUE);
                      }
                      else
                      {
                        printf ("malloc() failed. Exiting now.\n");
                        exit (EXIT_SUCCESS);
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _less_than:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      bool_value = (unsigned char *) malloc(sizeof(unsigned char));
                      if (bool_value != NULL)
                      {
                        *bool_value = packed_string_integer_less_than (packed_string_integer, packed_string_integer2);
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value, TRUE);
                      }
                      else
                      {
                        printf ("malloc() failed. Exiting now.\n");
                        exit (EXIT_SUCCESS);
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _equal:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      bool_value = (unsigned char *) malloc(sizeof(unsigned char));
                      if (bool_value != NULL)
                      {
                        *bool_value = packed_string_integer_equal (packed_string_integer, packed_string_integer2);
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value, TRUE);
                      }
                      else
                      {
                        printf ("malloc() failed. Exiting now.\n");
                        exit (EXIT_SUCCESS);
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _not_equal:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      bool_value = (unsigned char *) malloc(sizeof(unsigned char));
                      if (bool_value != NULL)
                      {
                        *bool_value = packed_string_integer_not_equal (packed_string_integer, packed_string_integer2);
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value, TRUE);
                      }
                      else
                      {
                        printf ("malloc() failed. Exiting now.\n");
                        exit (EXIT_SUCCESS);
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _and:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          bool_value_is_a_temporary_variable  = FALSE;
          bool_value2_is_a_temporary_variable = FALSE;
          bool_value3_is_a_temporary_variable = FALSE;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _bool)
              {
                bool_value2 = (unsigned char *) temp_expression_stack->operand;
                bool_value2_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack->operand != NULL)
                {
                  if (temp_expression_stack->operand_type == _bool)
                  {
                    bool_value = (unsigned char *) temp_expression_stack->operand;
                    bool_value_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                    if (bool_value3 != NULL)
                    {
                      *bool_value3 = bool_value && bool_value2;
                      temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                    }
                    if (bool_value_is_a_temporary_variable == TRUE)
                    {
                       free (bool_value);
                       bool_value = NULL;
                    }
                    if (bool_value2_is_a_temporary_variable == TRUE)
                    {
                       free (bool_value2);
                       bool_value = NULL;
                    }
                  }
                }
              }
            }
          }
        break;
        case _or:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          bool_value_is_a_temporary_variable  = FALSE;
          bool_value2_is_a_temporary_variable = FALSE;
          bool_value3_is_a_temporary_variable = FALSE;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _bool)
              {
                bool_value2 = (unsigned char *) temp_expression_stack->operand;
                bool_value2_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack->operand != NULL)
                {
                  if (temp_expression_stack->operand_type == _bool)
                  {
                    bool_value = (unsigned char *) temp_expression_stack->operand;
                    bool_value_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                    if (bool_value3 != NULL)
                    {
                      *bool_value3 = bool_value || bool_value2;
                      temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                    }
                    else
                    {
                      printf ("malloc() failed. Exiting now.\n");
                      exit (EXIT_SUCCESS);
                    }
                    if (bool_value_is_a_temporary_variable == TRUE)
                    {
                       free (bool_value);
                       bool_value = NULL;
                    }
                    if (bool_value2_is_a_temporary_variable == TRUE)
                    {
                       free (bool_value2);
                       bool_value = NULL;
                    }
                  }
                }
              }
            }
          }
        break;
        case _not:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          bool_value_is_a_temporary_variable  = FALSE;
          bool_value2_is_a_temporary_variable = FALSE;
          bool_value3_is_a_temporary_variable = FALSE;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _bool)
              {
                bool_value = (unsigned char *) temp_expression_stack->operand;
                bool_value_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                bool_value2 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value2 != NULL)
                {
                  *bool_value2 = !bool_value;
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value2, TRUE);
                }
                else
                {
                  printf ("malloc() failed. Exiting now.\n");
                  exit (EXIT_SUCCESS);
                }
                if (bool_value_is_a_temporary_variable == TRUE)
                {
                  free (bool_value);
                  bool_value = NULL;
                }
              }
            }
          }
        break;
        case _plus:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_integer3 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          packed_string_float3   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      packed_string_integer3 = packed_string_integer_add (packed_string_integer3, packed_string_integer, packed_string_integer2);
                      if (packed_string_integer3 != NULL)
                      {
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                      }
                      else
                      {
                        printf ("packed_string_integer_add failed. Exiting now.\n");
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _minus:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_integer3 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          packed_string_float3   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      packed_string_integer3 = packed_string_integer_subtract (packed_string_integer3, packed_string_integer, packed_string_integer2);
                      if (packed_string_integer3 != NULL)
                      {
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                      }
                      else
                      {
                        printf ("packed_string_integer_subtract failed. Exiting now.\n");
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _times:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_integer3 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          packed_string_float3   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      packed_string_integer3 = packed_string_integer_multiply (packed_string_integer3, packed_string_integer, packed_string_integer2);
                      if (packed_string_integer3 != NULL)
                      {
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                      }
                      else
                      {
                        printf ("packed_string_integer_multiply failed. Exiting now.\n");
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _divide:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_integer3 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          packed_string_float3   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      packed_string_integer3 = packed_string_integer_divide (packed_string_integer3, packed_string_integer, packed_string_integer2);
                      if (packed_string_integer3 != NULL)
                      {
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                      }
                      else
                      {
                        printf ("packed_string_integer_divide failed. Exiting now.\n");
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        case _modulo:
          packed_string_integer  = NULL;
          packed_string_integer2 = NULL;
          packed_string_integer3 = NULL;
          packed_string_float    = NULL;
          packed_string_float2   = NULL;
          packed_string_float3   = NULL;
          bool_value             = NULL;
          bool_value2            = NULL;
          bool_value3            = NULL;
          if (temp_expression_stack != NULL)
          {
            if (temp_expression_stack->operand != NULL)
            {
              if (temp_expression_stack->operand_type == _int)
              {
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                if (temp_expression_stack != NULL)
                {
                  if (temp_expression_stack->operand != NULL)
                  {
                    if (temp_expression_stack->operand_type == _int)
                    { 
                      packed_string_integer = (psint *) temp_expression_stack->operand;
                      temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                      packed_string_integer3 = packed_string_integer_modulo (packed_string_integer3, packed_string_integer, packed_string_integer2);
                      if (packed_string_integer3 != NULL)
                      {
                        temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                      }
                      else
                      {
                        printf ("packed_string_integer_multiply failed. Exiting now.\n");
                      }
                    }
                    else
                    {
                      if (expression_stack->operand_type == _float)
                      { 
                        // convert the string float into a string integer and put the new converted string integer into packed_string_integer2. Then apply the ">=" operator on packed_string_int1 and 2.
                        exit (EXIT_SUCCESS);
                      }
                      else
                      {
                        // Datatype mismatch here. I guess second operand is a Boolean? Whoops!
                        exit (EXIT_FAILURE);
                      }
                    }                      
                  }
                }
              }
              else
              {
                if (expression_stack->operand_type == _float)
                {
                  packed_string_integer = (psint *) expression_stack->operand;
                  temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                  if (temp_expression_stack != NULL)
                  {
                  }
                }
                else
                {
                  if (expression_stack->operand_type == _float)
                  {
                    packed_string_integer = (psint *) expression_stack->operand;
                    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                    if (temp_expression_stack != NULL)
                    {
                    }
                  }
                }
              }
            }
          }
        break;
        default:
        break;
      }
    }
    expression_stack = pop_runtime_expression_stack (expression_stack);
  }
  if (temp_expression_stack != NULL)
  {
    if (temp_expression_stack->operand != NULL)
    {
      if (temp_expression_stack->operand_type == _bool)
      {
        bool_value = (unsigned char *) temp_expression_stack->operand;
        bool_value_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
        temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
        boolean_expression_result = *bool_value;
        if (bool_value_is_a_temporary_variable == TRUE)
        {
          free (bool_value);
          bool_value = NULL;
        } 
      }
    }
  }
  if (temp_expression_stack == NULL)
  {
    printf ("temp_expression_stack is NULL. Excellent!\n");
  }
  return boolean_expression_result;
}




// ********************************************************************************************
// * evaluate_runtime_expression_return_integer_result_for_set_statement                      *
// *                                                                                          *
// * This subroutine evaluates an expression stack using Dijkstra's Shunting Yard algorithm.  *
// *                                                                                          *
// * The expression stack is comprised of the following in postfix order:                     *
// *       packed string float datatype (operand),                                            *
// *       packed string integer datatype (operand),                                          *
// *       Boolean datatype (operand),                                                        *
// *       plus (operator),                                                                   *
// *       minus (operator),                                                                  *
// *       times (operator),                                                                  *
// *       divide (operator),                                                                 *
// *       modulo (operator),                                                                 *
// *       and (operator),                                                                    *
// *       or (operator),                                                                     *
// *       not (operator)                                                                     *
// *                                                                                          *
// * This subroutine is called to evaluate a numerical expression for a SET statement when    *
// * the target variable is a packed string integer datatype.                                 *
// *                                                                                          *
// *                                                                                          *
// * Note: If the numerical expression contains contains packed string float datatypes, the   *
// * packed string float datatypes will be truncated to packed string integers during the     *
// * evaluation as the final (target variable) result is a packed string integer datatype.    *
// *                                                                                          *
// * Example:                                                                                 *
// * set foo = 12 / bar * 123456.0123 - baz + 2.5;                                            *
// *                                                                                          *
// * Return value: packed string integer (psint).                                             *
// ********************************************************************************************
psint * evaluate_runtime_expression_return_integer_result_for_set_statement (runtime_expression_stack_node *expression_stack)
{
  runtime_expression_stack_node *temp_expression_stack;
  psint *packed_string_integer1, *packed_string_integer2, *packed_string_integer3, *packed_string_integer_result;
  psflt *packed_string_float1, *packed_string_float2, *packed_string_float3;
  unsigned char *bool_value1, *bool_value2, *bool_value3;
  unsigned char packed_string_integer1_is_a_temporary_variable, packed_string_integer2_is_a_temporary_variable, packed_string_integer3_is_a_temporary_variable;
  unsigned char packed_string_float1_is_a_temporary_variable, packed_string_float2_is_a_temporary_variable, packed_string_float3_is_a_temporary_variable;
  unsigned char bool_value1_is_a_temporary_variable, bool_value2_is_a_temporary_variable, bool_value3_is_a_temporary_variable;
  chaga_operator_type operator;
  chaga_operand_type  operand;
  int state;

  temp_expression_stack  = NULL;
  packed_string_integer1 = NULL;
  packed_string_integer2 = NULL;
  packed_string_integer3 = NULL;
  packed_string_float1   = NULL;
  packed_string_float2   = NULL;
  packed_string_float3   = NULL;
  bool_value1            = NULL;
  bool_value2            = NULL;
  bool_value3            = NULL;
  packed_string_integer_result = NULL;
  state = 0;
  while (state < 999)
  {
    //printf ("state = %d\n", state);
    switch (state)
    {
      case 0:
        operator               = _none;
        operand                = _nothing;
        packed_string_integer1 = NULL;
        packed_string_float1   = NULL;
        packed_string_integer2 = NULL;
        packed_string_float2   = NULL;
        packed_string_integer3 = NULL;
        packed_string_float3   = NULL;
        bool_value1            = NULL;
        bool_value2            = NULL;
        bool_value3            = NULL;
        packed_string_integer1_is_a_temporary_variable = FALSE;
        packed_string_integer2_is_a_temporary_variable = FALSE;
        packed_string_integer3_is_a_temporary_variable = FALSE;
        packed_string_float1_is_a_temporary_variable   = FALSE;
        packed_string_float2_is_a_temporary_variable   = FALSE;
        packed_string_float3_is_a_temporary_variable   = FALSE;
        bool_value1_is_a_temporary_variable            = FALSE;
        bool_value2_is_a_temporary_variable            = FALSE;
        bool_value3_is_a_temporary_variable            = FALSE;
        if (expression_stack != NULL)
        {
          if (expression_stack->operator == _none)
          {
            if (expression_stack->operand != NULL)
            {
              switch (expression_stack->operand_type)
              {
                case _int:
                case _float:
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, expression_stack->operand_type, expression_stack->operand, expression_stack->ok_to_free_memory_for_operand);
                  expression_stack = pop_runtime_expression_stack (expression_stack);
                break;
                case _nothing:
                  state = 999;
                break;
                case _bool:
                  state = 999;
                break;
                default:
                  printf ("ERROR: Unknown datatype encountered.\n");
                  state = 999;
                break;
              }
            }
          }
          else
          {
            switch (expression_stack->operator)
            {
              case _greater_than_or_equal:
              case _greater_than:
              case _less_than_or_equal:
              case _less_than:
              case _equal:
              case _not_equal:
              case _and:
              case _or:
              case _plus:
              case _minus:
              case _times:
              case _divide:
              case _modulo:
                operator = expression_stack->operator;
                expression_stack = pop_runtime_expression_stack (expression_stack);
                state = 10;
              break;
              case _not:
                operator = expression_stack->operator;
                expression_stack = pop_runtime_expression_stack (expression_stack);
                state = 20; // The Boolean not operator only accepts one operand.
              break;
              default:
                printf ("ERROR: Unknown operand encountered.\n");
              break;
            }
          }
        } 
        else
        {
          state = 1000;
        }
      break;
// *********************************************************************************************
// * STATE 10: Expecting second operand on stack (operands on stack appear in reversed order). *
// *********************************************************************************************
      case 10:
        if (temp_expression_stack != NULL)
        {
          if (temp_expression_stack->operand != NULL)
          {
            operand = (chaga_operand_type) temp_expression_stack->operand_type;
            switch (operand)
            {
              case _int:
                packed_string_integer2 = (psint *) temp_expression_stack->operand;
                packed_string_integer2_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                state = 20;
              break;
              case _float:
                packed_string_float2 = (psflt *) temp_expression_stack->operand;
                packed_string_float2_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                state = 20;
              break;
              default:
                state = 999;
              break;
            }
          }
          else
          {
            state = 999;
          } 
        }
        else
        {
          state = 1010;
        }
      break;
// *****************************************************************************************
// * STATE 20: Expecting first operand on stack (operands on stack are in reversed order). *
// *****************************************************************************************
      case 20:
        if (temp_expression_stack != NULL)
        {
          if (temp_expression_stack->operand != NULL)
          {
            operand = (chaga_operand_type) temp_expression_stack->operand_type;
            switch (operand)
            {
              case _int:
                packed_string_integer1 = (psint *) temp_expression_stack->operand;
                packed_string_integer1_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                state = 30;
              break;
              case _float:
                packed_string_float1 = (psflt *) temp_expression_stack->operand;
                packed_string_float1_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
                temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
                state = 30;
              break;
              default:
                state = 999;
              break;
            }
          }
          else
          {
            state = 999;
          } 
        }
        else
        {
          state = 1000;
        }
      break;
// ************************************************************************************
// * STATE 30: Convert first and second operand to the same datatype (if applicable). *
// ************************************************************************************
      case 30:
        if (operator == _modulo)
        {
// **********************************************************************************************************************************
// * For modulo operator, both datatypes must be converted to integer since the modulo function only operates on integer datatypes. *
// **********************************************************************************************************************************
          if (packed_string_float1 != NULL)
          {
            packed_string_integer1 = packed_string_float_truncate_to_packed_string_integer (packed_string_integer1, packed_string_float1);
            packed_string_integer1_is_a_temporary_variable = TRUE;
          }
          if (packed_string_float2 != NULL)
          {
            packed_string_integer2 = packed_string_float_truncate_to_packed_string_integer (packed_string_integer2, packed_string_float2);
            packed_string_integer2_is_a_temporary_variable = TRUE;
          }
          state = 40;
        }
        else
        {
          if (operator == _not)
          {
// **********************************************************************************************
// * For NOT operator, the datatype must be converted to Boolean since NOT is a unary operator. *
// **********************************************************************************************
            if (packed_string_integer1 != NULL)
            {
              // TODO: convert operand_string_integer1 to a boolean datatype
              bool_value1_is_a_temporary_variable = TRUE;
              printf ("Need to write subroutine to convert an integer into a Boolean. Exiting now.\n");
              state = 999;
            }
            else
            {
              if (packed_string_float1 != NULL) 
              {
                // TODO: convert operand_string_float1 to a boolean datatype
                bool_value1_is_a_temporary_variable = TRUE;
                printf ("Need to write subroutine to convert a float into a Boolean. Exiting now.\n");
                state = 999;
              }
            }
          }
          else
          {
            if ((operator == _plus) || (operator == _minus) || (operator == _times) || (operator == _divide))
            {
// ****************************************************************************************************************
// * For operators {plus, minus, times, divide} both operands must be in either INTEGER format or FLOAT datatype. *
// ****************************************************************************************************************
              if (packed_string_integer1 != NULL)
              {
                if (packed_string_float2 != NULL)
                {
// *****************************************************
// * Convert first operand (and integer) into a float. *
// *****************************************************
                  packed_string_float1 = convert_packed_string_integer_to_packed_string_float (packed_string_float1, packed_string_integer1);
                  packed_string_float1_is_a_temporary_variable = TRUE;
                }
              }
              else
              {
                if (packed_string_float1 != NULL)
                {
                  if (packed_string_integer2 != NULL)
                  {
// ******************************************************
// * Convert second operand (and integer) into a float. *
// ******************************************************
                    packed_string_float2 = convert_packed_string_integer_to_packed_string_float (packed_string_float2, packed_string_integer2);
                    packed_string_float2_is_a_temporary_variable = TRUE;
                  }
                }
              }
              state = 40;
            }
            else
            {
              if ((operator == _greater_than_or_equal) || (operator == _less_than_or_equal) || 
                  (operator == _greater_than)          || (operator == _less_than)          || 
                  (operator == _equal)                 || (operator == _not_equal)          ||
                  (operator == _and)                   || (operator == _or)                 ||
                  (operator == _xor))
              {
// *****************************************************************************************************
// * For operators {>=, >, ==, <, <=, <>} the operands must be converted to INTEGER or FLOAT datatype. *
// *****************************************************************************************************
                if (packed_string_integer1 != NULL)
                {
                  // convert operand_string_integer1 to a bool datatype
                  bool_value1_is_a_temporary_variable = TRUE;
                  printf ("I need to write a subroutine to convert operand_string_integer1 to a bool datatype. Exiting now.\n");
                  state = 999;
                }
                else
                {
                  if (packed_string_float1 != NULL)
                  {
                    // convert operand_string_float1 to a bool datatype
                    bool_value1_is_a_temporary_variable = TRUE;
                    printf ("I need to write a subroutine to convert operand_string_float1 to a bool datatype. Exiting now.\n");
                    state = 999;
                  }
                  else
                  {
                    if (packed_string_integer2 != NULL)
                    {
                      // convert operand_string_integer2 to a bool datatype
                      bool_value2_is_a_temporary_variable = TRUE;
                      printf ("I need to write a subroutine to convert operand_string_integer2 to a bool datatype. Exiting now.\n");
                      state = 999;
                    }
                    else
                    {
                      if (packed_string_float2 != NULL)
                      {
                        // convert operand_string_float2 to a bool datatype
                        bool_value2_is_a_temporary_variable = TRUE;
                        printf ("I need to write a subroutine to convert operand_string_float2 to a bool datatype. Exiting now.\n");
                        state = 999;
                      }
                    }
                  }
                }
              }
              else
              {
                printf ("Unknown operator.\n");
                state = 999;
              }
            }
          }
        }
      break;
// **************************************************************************************************
// * STATE 40: Execute the operator command then push the result on the temporary expression stack. *
// **************************************************************************************************
      case 40:
        switch (operator)
        {
          case _plus:
            printf ("State 40, operator: +\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              packed_string_integer3 = packed_string_integer_add (packed_string_integer3, packed_string_integer1, packed_string_integer2);
              packed_string_integer3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
              if (packed_string_integer3 != NULL)
              {
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                state = 50;
              }
              else
              {
                printf ("ERROR: packed_string_integer_add returned NULL.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                packed_string_float3 = packed_string_float_add (packed_string_float3, packed_string_float1, packed_string_float2);
                packed_string_float3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                if (packed_string_float3 != NULL)
                {
                  printf ("State 40, packed_string_float3 = ");
                  packed_string_float_display (packed_string_float3, 0);
                  printf ("\n");
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _float, packed_string_float3, TRUE);
                  state = 50;
                }
              }
              else
              {
                printf ("Encountered plus operator but all operands are NULL.\n");
                state = 999;
              }
            }
          break;
          case _minus:
            printf ("State 40, operator: -\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              packed_string_integer3 = packed_string_integer_subtract (packed_string_integer3, packed_string_integer1, packed_string_integer2);
              packed_string_integer3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
              if (packed_string_integer3 != NULL)
              {
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                state = 50;
              }
              else
              {
                printf ("ERROR: packed_string_integer_subtract returned NULL.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                packed_string_float3 = packed_string_float_subtract (packed_string_float3, packed_string_float1, packed_string_float2);
                packed_string_float3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                if (packed_string_float3 != NULL)
                {
                  printf ("State 40, packed_string_float3 = ");
                  packed_string_float_display (packed_string_float3, 0);
                  printf ("\n");


                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _float, packed_string_float3, TRUE);
                  state = 50;
                }
                else
                {
                  printf ("ERROR: packed_string_integer_subtract returned NULL.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered minus operator but all operands are NULL.\n");
                state = 999;
              }
            }
          break;
          case _times:
            printf ("State 40, operator: *\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              packed_string_integer3 = packed_string_integer_multiply (packed_string_integer3, packed_string_integer1, packed_string_integer2);
              packed_string_integer3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
              if (packed_string_integer3 != NULL)
              {
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                state = 50;
              }
              else
              {
                printf ("ERROR: packed_string_integer_multiply returned NULL.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                packed_string_float3 = packed_string_float_multiply (packed_string_float3, packed_string_float1, packed_string_float2);
                packed_string_float3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                if (packed_string_float3 != NULL)
                {
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _float, packed_string_float3, TRUE);
                  state = 50;
                }
                else
                {
                  printf ("ERROR: packed_string_float_multiply returned NULL.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered times operator but all operands are NULL.\n");
                state = 999;
              }
            }
          break;
          case _divide:
            //printf ("State 40, operator: /\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              packed_string_integer3 = packed_string_integer_divide (packed_string_integer3, packed_string_integer1, packed_string_integer2);
              packed_string_integer3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
              if (packed_string_integer3 != NULL)
              {
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                state = 50;
              }
              else
              {
                printf ("ERROR: packed_string_integer_divide returned NULL.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                packed_string_float3 = packed_string_float_divide (packed_string_float3, packed_string_float1, packed_string_float2, 100); // TODO: the 100 is a hardcoded scale value. Need to replace.
                packed_string_float3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                if (packed_string_float3 != NULL)
                {
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _float, packed_string_float3, TRUE);
                  state = 50;
                }
                else
                {
                  printf ("ERROR: packed_string_float_divide returned NULL.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered divide operator but all operands are NULL.\n");
                state = 999;
              }
            }
          break;
          case _modulo:
            //printf ("State 40, operator: %%\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              packed_string_integer3 = packed_string_integer_modulo (packed_string_integer3, packed_string_integer1, packed_string_integer2);
              packed_string_integer3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
              if (packed_string_integer3 != NULL)
              {
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _int, packed_string_integer3, TRUE);
                state = 50;
              }
              else
              {
                printf ("ERROR: packed_string_integer_modulo returned NULL.\n");
                state = 999;
              }
            }
            else
            {
              printf ("Encountered modulo operator but all operands are NULL.\n");
              state = 999;
            }
          break;
          case _and:
            //printf ("State 40, operator: AND\n");
            if ((bool_value1 != NULL) && (bool_value2 != NULL))
            {           
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = *bool_value1 && *bool_value2;
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              printf ("ERROR: Encountered AND operator but all operands are NULL.\n");
              state = 999;
            }
          break;
          case _or:
            //printf ("State 40, operator: OR\n");
            if ((bool_value1 != NULL) && (bool_value2 != NULL))
            {           
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = *bool_value1 || *bool_value2;
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              printf ("ERROR: Encountered AND operator but all Boolean operands are NULL. TODO: implement INTEGER-TO-BOOLEAN and FLOAT-TO-BOOLEAN conversion subroutines.\n");
              state = 999;
            }
          break;
          case _xor:
            printf ("State 40, operator: XOR\n");
            printf ("Encountered XOR operator.  TODO: implement XOR subroutine on BOOLEAN operands.\n");
            state = 999;
          break;
          case _not:
            //printf ("State 40, operator: NOT\n");
            if (bool_value1 != NULL)
            {           
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = !*bool_value1;
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              printf ("ERROR: Encountered NOT operator but all Boolean operands are NULL. TODO: implement INTEGER-TO-BOOLEAN and FLOAT-TO-BOOLEAN conversion subroutines.\n");
              state = 999;
            }
          break;
          case _greater_than_or_equal:
            //printf ("State 40, operator: >=\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = packed_string_integer_greater_than_or_equal (packed_string_integer1, packed_string_integer2);
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value3 != NULL)
                {
//                  *bool_value3 = packed_string_float_greater_than_or_equal (packed_string_float1, packed_string_float2);
//                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
//                  state = 50;
                  printf ("TODO: I need to write packed_string_float_greater_than_or_equal function.\n");
                  state = 999;
                }
                else
                {
                  printf ("malloc() failed.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("ERROR: Encountered GREATER THAN OR EQUAL operator but INTEGER and FLOAT operands are NULL. TODO: Write subroutines to convert BOOLEAN datatypes to INTEGER datatypes.\n");
                state = 999;
              }
            }
          break;
          case _greater_than:
            //printf ("State 40, operator: >\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = packed_string_integer_greater_than (packed_string_integer1, packed_string_integer2);
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value3 != NULL)
                {
//                  *bool_value3 = packed_string_float_greater_than (packed_string_float1, packed_string_float2);
//                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
//                  state = 50;
                  printf ("TODO: I need to write packed_string_float_greater_than subroutine.\n");
                  state = 999;
                }
                else
                {
                  printf ("malloc() failed.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("ERROR: Encountered GREATER THAN operator but INTEGER and FLOAT operands are NULL. TODO: Write subroutines to convert BOOLEAN datatypes to INTEGER datatypes.\n");
                state = 999;
              }
            }
          break;
          case _equal:
            //printf ("State 40, operator: ==\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = packed_string_integer_equal (packed_string_integer1, packed_string_integer2);
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value3 != NULL)
                {
                  *bool_value3 = packed_string_float_equal (packed_string_float1, packed_string_float2);
                  bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                  state = 50;
                }
                else
                {
                  printf ("malloc() failed.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered EQUAL operator but INTEGER and FLOAT operands are NULL. TODO: Write subroutines to convert BOOLEAN datatypes to INTEGER datatypes.\n");
                state = 999;
              }
            }
          break;
          case _not_equal:
            //printf ("State 40, operator: <>\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = packed_string_integer_not_equal (packed_string_integer1, packed_string_integer2);
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value3 != NULL)
                {
//                  *bool_value3 = packed_string_float_not_equal (packed_string_float1, packed_string_float2);
//                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
//                  state = 50;
                  printf ("TODO: I need to write packed_string_float_not_equal subroutine.\n");
                  state = 999;
                }
                else
                {
                  printf ("malloc() failed.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered NOT EQUAL operator but INTEGER and FLOAT operands are NULL. TODO: Write subroutines to convert BOOLEAN datatypes to INTEGER datatypes.\n");
                state = 999;
              }
            }
          break;
          case _less_than:
            //printf ("State 40, operator: <\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = packed_string_integer_less_than (packed_string_integer1, packed_string_integer2);
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value3 != NULL)
                {
                  *bool_value3 = packed_string_float_less_than (packed_string_float1, packed_string_float2);
                  bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                  state = 50;
                }
                else
                {
                  printf ("malloc() failed.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered NOT EQUAL operator but INTEGER and FLOAT operands are NULL. TODO: Write subroutines to convert BOOLEAN datatypes to INTEGER datatypes.\n");
                state = 999;
              }
            }
          break;
          case _less_than_or_equal:
            //printf ("State 40, operator: <=\n");
            if ((packed_string_integer1 != NULL) && (packed_string_integer2 != NULL))
            {
              bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
              if (bool_value3 != NULL)
              {
                *bool_value3 = packed_string_integer_less_than_or_equal (packed_string_integer1, packed_string_integer2);
                bool_value3_is_a_temporary_variable = FALSE; // don't want to release memory immediately since it is on the stack. On the stack it is marked as temporary to release at later iteration.
                temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
                state = 50;
              }
              else
              {
                printf ("malloc() failed.\n");
                state = 999;
              }
            }
            else
            {
              if ((packed_string_float1 != NULL) && (packed_string_float2 != NULL))
              {
                bool_value3 = (unsigned char *) malloc(sizeof(unsigned char));
                if (bool_value3 != NULL)
                {
//                  *bool_value3 = packed_string_float_less_than_or_equal (packed_string_float1, packed_string_float2);
//                  temp_expression_stack = push_operand_runtime_expression_stack (temp_expression_stack, _bool, bool_value3, TRUE);
//                  state = 50;
                  printf ("TODO: I need to write packed_string_float_less_than_or_equal subroutine.\n");
                  state = 999;
                }
                else
                {
                  printf ("malloc() failed.\n");
                  state = 999;
                }
              }
              else
              {
                printf ("Encountered NOT EQUAL operator but INTEGER and FLOAT operands are NULL. TODO: Write subroutines to convert BOOLEAN datatypes to INTEGER datatypes.\n");
                state = 999;
              }
            }
          break;
          default:
            printf ("Unknown operator encounted.\n");
            state = 999;
          break;
        }
      break;
// *****************************************************************************************************
// * State = 50: Remove any temporary variables created during the evaluation process (if applicable). *
// *****************************************************************************************************
      case 50:
        if (packed_string_integer1 != NULL)
        {
          if (packed_string_integer1_is_a_temporary_variable)
          {
            packed_string_integer1 = packed_string_integer_release_memory (packed_string_integer1);
          }
        }
        if (packed_string_integer2 != NULL)
        {
          if (packed_string_integer2_is_a_temporary_variable)
          {
            packed_string_integer2 = packed_string_integer_release_memory (packed_string_integer2);
          }  
        }
        if (packed_string_integer3 != NULL)
        {
          if (packed_string_integer3_is_a_temporary_variable)
          {
            packed_string_integer3 = packed_string_integer_release_memory (packed_string_integer3);
          }  
        }
        if (packed_string_float1 != NULL)
        {
          if (packed_string_float1_is_a_temporary_variable)
          {
            packed_string_float1 = packed_string_float_release_memory (packed_string_float1);
          }
        }
        if (packed_string_float2 != NULL)
        {
          if (packed_string_float2_is_a_temporary_variable)
          {
            packed_string_float2 = packed_string_float_release_memory (packed_string_float2);
          }  
        }
        if (packed_string_float3 != NULL)
        {
          if (packed_string_float3_is_a_temporary_variable)
          {
            packed_string_float3 = packed_string_float_release_memory (packed_string_float3);
          }  
        }
        if (bool_value1 != NULL)
        {
          if (bool_value1_is_a_temporary_variable)
          {
            free (bool_value1);
            bool_value1 = NULL;
          }
        }
        if (bool_value2 != NULL)
        {
          if (bool_value2_is_a_temporary_variable)
          {
            free (bool_value2);
            bool_value1 = NULL;
          }
        }
        if (bool_value3 != NULL)
        {
          if (bool_value3_is_a_temporary_variable)
          {
            free (bool_value3);
            bool_value1 = NULL;
          }
        }
        state = 0;
      break;
      default:
        printf ("ERROR: Unknown state reached. Exiting now.\n");
        state = 999;
      break;
    }
  }
  if (state == 1000)
  {
    if (temp_expression_stack != NULL)
    {
      if (temp_expression_stack->operator == _none)
      {
        if (temp_expression_stack->operand != NULL)
        {
          switch (temp_expression_stack->operand_type)
          {
            case _int:
              packed_string_integer_result = (psint *) temp_expression_stack->operand;
              temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
            break;
            case _float:
              packed_string_float1 = (psflt *) temp_expression_stack->operand;
              packed_string_float1_is_a_temporary_variable = temp_expression_stack->ok_to_free_memory_for_operand;
              temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
              packed_string_integer_result = packed_string_float_truncate_to_packed_string_integer (packed_string_integer_result, packed_string_float1);
              if (packed_string_float1_is_a_temporary_variable == TRUE)
              {
                packed_string_float1 = packed_string_float_release_memory (packed_string_float1);
              }
            break;
            default:
            break;
          }
        }
      }
    }    
  }
  while (expression_stack != NULL)
  {
    expression_stack = pop_runtime_expression_stack (expression_stack);
  }
  while (temp_expression_stack != NULL)
  {
    temp_expression_stack = pop_runtime_expression_stack (temp_expression_stack);
  }      
  return packed_string_integer_result;
}
  
  
