/**************************************************************************************
 * Chaga compiler                                                                     *
 * Copyright (C) 2026 Robert James Bruce                                              *
 *                                                                                    *
 * This file is part of the Chaga compiler.                                           *
 *                                                                                    *
 * The Chaga compiler 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 compiler 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/chaga_compiler-x86_assembler.h"

//  ****************************************************************************************************************************
// * Create stackframe cross reference table for function or procedure called "main".                                          *
// *                                                                                                                           *
// * This table provides the negative offset relative to the stack pointer's current location for each variable stored in the  *
// * stackframe. Each offset is cross-referenced with the variables stored in each function or procecedure. This functionality *
// * is necessary when creating the assembler output code.                                                                     *
// *****************************************************************************************************************************
stackframe_node * create_stackframe_cross_reference_table_for_main_only (symtab_node *symbol_table)
{
  stackframe_node          *stackframe_cross_reference_table, *new_stackframe_element, *previous_stackframe_element;
  symtab_node              *symbol_table_element_for_main_function, *symbol_table_element;
  token_node               *current_token;
  int                      comparison_result;
  unsigned long long int   scope_level_for_main_function;  
  size_t                   stackframe_offset;

  stackframe_cross_reference_table = NULL;
  previous_stackframe_element = NULL;
  stackframe_offset = 16; // iniitalize offset to 16 bytes to give some extra memory padding on the stack frame. I also allocate 16 additional bytes total storage required in other subroutines to compensate for this as well.
  if (symbol_table != NULL)
  {
    symbol_table_element_for_main_function = retrieve_symbol_table_element_for_function_or_procedure_name (symbol_table, "main", _function);
    if (symbol_table_element_for_main_function != NULL)
    {
      scope_level_for_main_function = symbol_table_element_for_main_function->scope_level;
// *********************************************************************************************************
// * First pass: Allocate all int and float datatypes since they take 8-bytes (as a pointer) on the stack. *
// *********************************************************************************************************
      symbol_table_element = symbol_table;
      while (symbol_table_element != NULL)
      { 
        if (symbol_table_element->scope_level == scope_level_for_main_function)
        {
          if (symbol_table_element->attribute_type == _datatype)
          {
            if ((symbol_table_element->datatype == _int) || (symbol_table_element->datatype == _float))
            {
              if (symbol_table_element->identifier != NULL)
              {
                if (strncmp(symbol_table_element->identifier, "argc", 4) != 0)
                {
                  new_stackframe_element = (stackframe_node *) malloc(sizeof(stackframe_node));
                  if (new_stackframe_element != NULL)
                  {
                    new_stackframe_element->symbol_table_entry    = symbol_table_element;
                    new_stackframe_element->stackframe_offset     = stackframe_offset;
                    new_stackframe_element->storage_size_in_bytes = 8; // Chaga _int datatype is internally a 64-bit pointer to a string integer. Thus this datatype takes 8 bytes of storage space on a stack frame.
                    new_stackframe_element->next                  = NULL;
                    stackframe_offset = stackframe_offset + 8;
                    if (stackframe_cross_reference_table != NULL)
                    {
                      if (previous_stackframe_element == NULL)
                      {
                        previous_stackframe_element = stackframe_cross_reference_table;
                      }
                      previous_stackframe_element->next = new_stackframe_element;
                      previous_stackframe_element = new_stackframe_element;
                    }
                    else
                    {
                      stackframe_cross_reference_table = new_stackframe_element;
                    }
                  }
                }
              }
            }
          }
        }
        symbol_table_element = symbol_table_element->next;
      }
// *********************************************************************************************************
// * Second pass: Allocate all bool datatypes since they take 1-byte and can packed together on the stack. * 
// *********************************************************************************************************
      symbol_table_element = symbol_table;
      while (symbol_table_element != NULL)
      { 
        if (symbol_table_element->scope_level == scope_level_for_main_function)
        {
          if (symbol_table_element->attribute_type == _datatype)
          {
            if (symbol_table_element->datatype == _bool)
            {
              if (symbol_table_element->identifier != NULL)
              {
                new_stackframe_element = (stackframe_node *) malloc(sizeof(stackframe_node));
                if (new_stackframe_element != NULL)
                {
                  new_stackframe_element->symbol_table_entry    = symbol_table_element;
                  new_stackframe_element->stackframe_offset     = stackframe_offset;
                  new_stackframe_element->storage_size_in_bytes = 1; // Chaga _bool datatype is internally an 8-bit char. This datatype takes 1 byte of storage space on a stack frame.
                  new_stackframe_element->next                  = NULL;
                  stackframe_offset = stackframe_offset + 1;
                  if (stackframe_cross_reference_table != NULL)
                  {
                    if (previous_stackframe_element == NULL)
                    {
                      previous_stackframe_element = stackframe_cross_reference_table;
                    }
                    previous_stackframe_element->next = new_stackframe_element;
                    previous_stackframe_element = new_stackframe_element;
                  }
                  else
                  {
                    stackframe_cross_reference_table = new_stackframe_element;
                  }
                }
              }
            }
          }
        }
        symbol_table_element = symbol_table_element->next;
      }
    }
  }
  return stackframe_cross_reference_table;
}




asmblr_node * create_assembler_program (ast_node *abstract_syntax_tree, symtab_node *symbol_table, stackframe_node *stackframe_cross_reference_table)
{
  ast_node    *ast_element;
  symtab_node *symbol_table_element, *temp_symbol_table_element;
  asmblr_node *assembler_program;
  int         state, inside_main_function, num_left_curly_braces, num_right_curly_braces, added_stringint_library, added_chaga_input_output_library, current_token_type;
  size_t      token_string_length; 
  unsigned long long int scope_level;
  char        *current_token;

  added_stringint_library          = FALSE;
  added_chaga_input_output_library = FALSE;
  assembler_program = NULL;
  if (symbol_table != NULL)
  {
    inside_main_function = FALSE;
    state = 0;
    ast_element = abstract_syntax_tree;
    while ((ast_element != NULL) && (state != 99999))
    {
      current_token = ast_element->token;
      current_token_type = ast_element->token_type;
      if (current_token != NULL)
      {
        //printf ("IN create_assembler_program, state = %d, ast_element->token->token = %s\n", state, current_token);
      }
      switch (state)
      {
        case 0:
          if (ast_element->statement_type == _define)
          {
            state = 10;
          }
        break;
        case 10:
          current_token = ast_element->token;
          if (current_token != NULL)
          {
            if (current_token != NULL)
            {
              if (current_token_type == TOKEN_IDENTIFIER)
              {
                token_string_length = strlen (current_token);
                switch (token_string_length)
                {
                  case 4:
                    if (strncmp(current_token, "main", 4) == 0)
                    {
                      symbol_table_element = ast_element->symbol_table_entry;
                      if (symbol_table_element != NULL)
                      {
                        scope_level = symbol_table_element->scope_level;
                        assembler_program = create_assembler_output_for_main_function_definition (assembler_program, symbol_table, stackframe_cross_reference_table, scope_level);
                        inside_main_function = TRUE;
                        num_left_curly_braces = 0;
                        num_right_curly_braces = 0;
                        state = 2000;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  break;
                  default:
                    state = 99999;
                  break;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
        case 2000:
          if (ast_element->statement_type == _left_curly_brace)
          {
            num_left_curly_braces++;
            state = 4000;
          }
          else
          {
            state = 99999;
          }
        break;
// ******************************
// * PRINT statement processing *
// ******************************
        case 4000:
          if (ast_element->statement_type == _print)
          {
            if (!added_chaga_input_output_library)
            {
              assembler_program = create_assembler_output_for_internal_chaga_input_output_library (assembler_program);
              added_chaga_input_output_library = TRUE;  
            }
            assembler_program = create_assembler_output_print_statement (assembler_program, ast_element, stackframe_cross_reference_table);
// **************************************************************************************************
// * Now advance to the next statement since we've procssed all the tokens for the printf statement *
// **************************************************************************************************
            while (ast_element->sibling != NULL)
            {
              ast_element = ast_element->sibling;
            }
            state = 4000;
          }
          else
          {
            if (ast_element->statement_type == _set)
            {
              state = 5000;
            }
            else
            {
              if (ast_element->statement_type == _right_curly_brace)
              {
                num_right_curly_braces++;
                if (num_right_curly_braces > num_right_curly_braces)
                {
                  state = 99999;
                }
                else
                {
                  if (num_left_curly_braces == num_right_curly_braces)
                  {
                    if (inside_main_function)
                    {
                      assembler_program = create_assembler_output_exit_main_function (assembler_program);
                    }
                    state = 0;
                  }
                }
              }
              else
              {
                state = 99999;
              }
            }
          }
        break;
// ****************************
// * SET statement processing *
// ****************************
        case 5000:
// **************************************************************************************************************************************
//  Check if the target (assignee) variable is an integer or float datatype. If so, I must include the Chaga string arithmetic library. *
// **************************************************************************************************************************************
          if (ast_element->token_type == TOKEN_IDENTIFIER)
          {
            temp_symbol_table_element = ast_element->symbol_table_entry;
            if (temp_symbol_table_element != NULL)
            {
              if (temp_symbol_table_element->attribute_type == _datatype)
              {
                if (!added_chaga_input_output_library)
                {
                  assembler_program = create_assembler_output_for_internal_chaga_input_output_library (assembler_program);
                  added_chaga_input_output_library = TRUE;  
                }
                if (temp_symbol_table_element->datatype == _int)
                {
                  assembler_program = create_assembler_output_set_statement_numerical_expression_integer (assembler_program, ast_element, symbol_table, stackframe_cross_reference_table);
                }
                else
                {
                  if (temp_symbol_table_element->datatype == _float)
                  {
                    assembler_program = create_assembler_output_set_statement_numerical_expression_float (assembler_program, ast_element, symbol_table, stackframe_cross_reference_table);
                  }
                  else
                  {
                    if (temp_symbol_table_element->datatype == _bool)
                    {
                      assembler_program = create_assembler_output_set_statement_boolean_expression (assembler_program, ast_element, symbol_table, stackframe_cross_reference_table);
                    }
                  }
                }
// *********************************************************************************************
// * Now advance to the next statement since we've processed all tokens for the set statement. *
// *********************************************************************************************
                while (ast_element->sibling != NULL)
                {
                  ast_element = ast_element->sibling;
                }
                state = 4000;
              }
              else
              {
                state = 99999;
              }
            }
          }
          else
          {
            state = 99999;
          }
        break;
        default:
        break;
      }
      if (state != 99999)
      {
        if (ast_element->sibling != NULL)
        {
          ast_element = ast_element->sibling;
        }
        else
        {
          ast_element = ast_element->child;
        }
      }
    }
  }
  return assembler_program;
}




// ********************************************************************************
// * This subroutine creates assembly language code for main function definition. *
// ********************************************************************************
asmblr_node * create_assembler_output_for_main_function_definition (asmblr_node *assembler_program, symtab_node *symbol_table, stackframe_node *stackframe_cross_reference_table, unsigned long long int scope_level)
{
  asmblr_node *assembler_statement, *assembler_element, *temp_assembler_element;
  symtab_node *symbol_table_element;
  size_t token_string_length, buffer_size, num_datatype_declarations, i, j, stackframe_storage_allocation_in_bytes;
  unsigned char temp_buffer[1024];

  assembler_statement = malloc(sizeof(asmblr_node));
  if (assembler_statement != NULL)
  {
    assembler_statement->program_section       = 1;  // indicates this is the main program
    assembler_statement->label                 = 0;
    assembler_statement->data_section_contents = NULL;       
    assembler_statement->next                  = NULL;
    num_datatype_declarations = symbol_table_count_number_of_datatype_declarations_for_given_scope_level_excluding_argv_argc_in_main (symbol_table, scope_level);

    if (num_datatype_declarations == 0)
    {
      buffer_size = 256;
      assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * buffer_size);
      if (assembler_statement->code_section_contents != NULL)
      {
        strncpy (assembler_statement->code_section_contents, "     .text\n     .globl main\n     .type main, @function\nmain:\n     endbr64\n     push rbp\n     mov rbp, rsp\n", buffer_size);
      }
    }
    else
    {
// ****************************************************************************************************************************************
// * I need to output the following x86 assembler code to initialize each variable declared in the main procedure (except argc and argc). *
// * This code intializes each pointer to NULL.                                                                                           *
// *                                                                                                                                      *
// * An unsigned long long int may contain a MINIMUM 1 digit and a MAXIMUM 20 digits. Worst case scenario:                                *
// * "    mov QWORD PTR -12345678901234567890[rbp], 0\n"                                                                                  *
// *  123456789012345678901234567890123456789012345678                                                                                    *
// * Therefore (in a worst-case scenario) I need 50 bytes (for each variable declared) + 1 (for NULL terminating byte at end of buffer).  *
// ****************************************************************************************************************************************
      buffer_size = 256 + 64 * num_datatype_declarations; // this includes the one extra byte for NULL terminator at end of buffer.
      assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * buffer_size);
      if (assembler_statement->code_section_contents != NULL)
      {
        strncpy (assembler_statement->code_section_contents, "     .text\n     .globl main\n     .type main, @function\nmain:\n     endbr64\n     push rbp\n     mov rbp, rsp\n", buffer_size);
// **************************************************************************************************************************************
// * Now subtract an offset to the stack to allocate storage space for each variable defined in main. In GNU/Linux, stackframe storage  *
// * space must be on increments of 16 bytes. This is outlined in what is called the Application Binary Interface (ABI).                *
// *                                                                                                                                    *
// *                                                                                                                                    *
// * Example 1: One variable is declared in main. That variable is a 64-bit pointer. It requires 8 bytes of storage space on the stack. *
// *    Result: 16 bytes of storage space is allocated on the stack.                                                                    * 
// *                                                                                                                                    *
// *                                                                                                                                    *
// * Example 2: Three variables are declared in main. Each variable is a 64-bit pointer. Each pointer requires 8 bytes of storage on    *
// *            the stack. Thus the three pointers need 24 bytes of storage.                                                            *
// *    Result: 32 bytes of storage space is allocated on the stack since 32 bytes is the next increment of 16 bytes that can safely    *
// *            store 24 bytes.                                                                                                         *
// **************************************************************************************************************************************
        stackframe_storage_allocation_in_bytes = determine_stackframe_storage_size_for_all_locally_defined_variables_in_main (stackframe_cross_reference_table, symbol_table);
        snprintf (&temp_buffer[0], sizeof(temp_buffer), "     sub rsp, %ld\n", stackframe_storage_allocation_in_bytes); 
        strncat (assembler_statement->code_section_contents, &temp_buffer[0], buffer_size);
// ***************************************************************
// * Now initialize all local variables in main to zero or NULL. *
// ***************************************************************
        j = 1;
        i = stackframe_storage_allocation_in_bytes;
        while (i > 0)
        {
          snprintf (&temp_buffer[0], sizeof(temp_buffer), "     mov QWORD PTR -%ld[rbp], 0\n", j*8);
          strncat (assembler_statement->code_section_contents, &temp_buffer[0], buffer_size);
          j++;
          i = i - 8;
        }
      }
    }
    if (assembler_program != NULL)
    {
      temp_assembler_element = assembler_program;
      while (temp_assembler_element->next != NULL)
      {
        temp_assembler_element = temp_assembler_element->next;
      }
      temp_assembler_element->next = assembler_statement;
    }
    else
    {
      assembler_program = assembler_statement;
    }
  }
  return assembler_program;
}




// ********************************************************************************************************************************
// * create_assembler_output_print_statement                                                                                      *
// *                                                                                                                              *
// * This subroutine creates the assembler output for a printf() statement.                                                       *
// *                                                                                                                              *
// * NOTE: This subroutine is limited to generating assembler output for STATIC (non-changing) string data in a printf statement. *
// *       formatting options inside printf are not supported yet.                                                                *
// ********************************************************************************************************************************
asmblr_node * create_assembler_output_print_statement (asmblr_node *assembler_program, ast_node *abstract_syntax_tree, stackframe_node *stackframe_cross_reference_table)
{
  asmblr_node     *assembler_statement, *assembler_element, *temp_assembler_element;
  ast_node        *ast_element;
  binstr_node     *binary_output_string;
  stackframe_node *stackframe_element;
  symtab_node     *symbol_table_entry;
  unsigned char byte, *hex_string, *data_section_string_buffer;
  int state, token_type;
  size_t i, j, token_string_length, code_section_string_buffer_max_length, data_section_string_buffer_length; 
  unsigned long long int label;
  char *token, *escaped_double_quotes_token;

  state = 0;
  ast_element = abstract_syntax_tree;
  while ((ast_element != NULL) && (state != 99999))
  {
    token = ast_element->token;
    if (token != NULL)
    {
      //printf ("In create_assembler_output_print_statement: state = %d, token = %s\n", state, token);
    }
    switch (state)
    {
      case 0:
        assembler_statement  = malloc(sizeof(asmblr_node));
        if (assembler_statement != NULL)
        {
          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
          assembler_statement->abstract_syntax_tree  = ast_element;
          assembler_statement->label                 = 0;
          assembler_statement->code_section_contents = NULL;       
          assembler_statement->data_section_contents = NULL;       
          assembler_statement->next                  = NULL;
          state = 10;
          ast_element = ast_element->sibling;
        }
        else
        {
          state = 99999;
        }
      break;
      case 10:
        if (assembler_statement != NULL)
        {
          token = ast_element->token;
          token_type = ast_element->token_type;
          if (token != NULL)
          {
            if (token != NULL)
            {
              if (token_type == TOKEN_STRING)
              {
                label = retrieve_highest_label_number_from_assembly_output (assembler_program);
                assembler_statement->label = label + 1;
// ********************************************************************************************************
// * All double quotes found within a token must be escaped! If not, it will cause the assembler to fail. *
// ********************************************************************************************************
                escaped_double_quotes_token = escape_double_quotes_inside_text (token);
                if (escaped_double_quotes_token != NULL)
                {
                  token_string_length = strlen(escaped_double_quotes_token);
                  data_section_string_buffer_length = token_string_length + 31;
                  data_section_string_buffer = malloc(sizeof(char)*data_section_string_buffer_length); 
                  if (data_section_string_buffer != NULL)
                  {
                    data_section_string_buffer[0]  = ' ';
                    data_section_string_buffer[1]  = ' ';
                    data_section_string_buffer[2]  = ' ';
                    data_section_string_buffer[3]  = ' ';
                    data_section_string_buffer[4]  = ' ';
                    data_section_string_buffer[5]  = '.';
                    data_section_string_buffer[6]  = 's';
                    data_section_string_buffer[7]  = 't';
                    data_section_string_buffer[8]  = 'r';
                    data_section_string_buffer[9]  = 'i';
                    data_section_string_buffer[10] = 'n';
                    data_section_string_buffer[11] = 'g';
                    data_section_string_buffer[12] = ' ';
                    data_section_string_buffer[13] = '"';
                    for (i = 0; i < token_string_length; i++)
                    {
                      data_section_string_buffer[14+i] = escaped_double_quotes_token[i];
                    }
                    data_section_string_buffer[14+token_string_length] = '"';
                    data_section_string_buffer[15+token_string_length] = '\n';
                    data_section_string_buffer[16+token_string_length] = ' ';
                    data_section_string_buffer[17+token_string_length] = ' ';
                    data_section_string_buffer[18+token_string_length] = ' ';
                    data_section_string_buffer[19+token_string_length] = ' ';
                    data_section_string_buffer[20+token_string_length] = ' ';
                    data_section_string_buffer[21+token_string_length] = '.';
                    data_section_string_buffer[22+token_string_length] = 'a';
                    data_section_string_buffer[23+token_string_length] = 'l';
                    data_section_string_buffer[24+token_string_length] = 'i';
                    data_section_string_buffer[25+token_string_length] = 'g';
                    data_section_string_buffer[26+token_string_length] = 'n';
                    data_section_string_buffer[27+token_string_length] = ' ';
                    data_section_string_buffer[28+token_string_length] = '8';
                    data_section_string_buffer[29+token_string_length] = '\n';
                    data_section_string_buffer[30+token_string_length] = '\0';
                  }
                  free (escaped_double_quotes_token);
                  escaped_double_quotes_token = NULL;
                }
                assembler_statement->data_section_contents = data_section_string_buffer;
// ********************************************************
// * Now enter assembly code for the print functionality. *
// ********************************************************
                code_section_string_buffer_max_length = 4096;
                assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * code_section_string_buffer_max_length);
                if (assembler_statement->code_section_contents != NULL)
                {
                  snprintf (assembler_statement->code_section_contents, code_section_string_buffer_max_length, "     lea rax, .M%llu[rip]\n     mov rdi, rax\n     mov eax, 0\n     call printf@PLT\n", assembler_statement->label);
                }
                if (assembler_program != NULL)
                {
                  temp_assembler_element = assembler_program;
                  while (temp_assembler_element->next != NULL)
                  {
                    temp_assembler_element = temp_assembler_element->next;
                  }
                  temp_assembler_element->next = assembler_statement;
                }
                else
                {
                  assembler_program = assembler_statement;
                }
                state = 20;
                ast_element = ast_element->sibling;
              }
              else
              {
                if (token_type == TOKEN_IDENTIFIER)
                {
                  symbol_table_entry = ast_element->symbol_table_entry;
                  if (symbol_table_entry != NULL)
                  {
                    if ((symbol_table_entry->attribute_type == _datatype) && (symbol_table_entry->datatype == _int)) 
                    {
                      stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_entry);
                      if (stackframe_element != NULL)
                      {
// *******************************************************************************************
// * Now I will call stringint_display (internal library) to display the value of a variable *
// *******************************************************************************************
                        code_section_string_buffer_max_length = 4096;
                        assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * code_section_string_buffer_max_length);
                        if (assembler_statement->code_section_contents != NULL)
                        {
                          snprintf (assembler_statement->code_section_contents, code_section_string_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     mov esi, 0\n     mov rdi, rax\n     call packed_string_integer_display@PLT\n", stackframe_element->stackframe_offset);
                          state = 20;
                          ast_element = ast_element->sibling;
                          if (assembler_program != NULL)
                          {
                            temp_assembler_element = assembler_program;
                            while (temp_assembler_element->next != NULL)
                            {
                              temp_assembler_element = temp_assembler_element->next;
                            }
                            temp_assembler_element->next = assembler_statement;
                          }
                          else
                          {
                            assembler_program = assembler_statement;
                          }
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      if ((symbol_table_entry->attribute_type == _datatype) && (symbol_table_entry->datatype == _float)) 
                      {
                        stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_entry);
                        if (stackframe_element != NULL)
                        {
// *******************************************************************************************
// * Now I will call stringint_display (internal library) to display the value of a variable *
// *******************************************************************************************
                          code_section_string_buffer_max_length = 4096;
                          assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * code_section_string_buffer_max_length);
                          if (assembler_statement->code_section_contents != NULL)
                          {
                            snprintf (assembler_statement->code_section_contents, code_section_string_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     mov esi, 0\n     mov rdi, rax\n     call packed_string_float_display@PLT\n", stackframe_element->stackframe_offset);
                            state = 20;
                            ast_element = ast_element->sibling;
                            if (assembler_program != NULL)
                            {
                              temp_assembler_element = assembler_program;
                              while (temp_assembler_element->next != NULL)
                              {
                                temp_assembler_element = temp_assembler_element->next;
                              }
                              temp_assembler_element->next = assembler_statement;
                            }
                            else
                            {
                              assembler_program = assembler_statement;
                            }
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        if ((symbol_table_entry->attribute_type == _datatype) && (symbol_table_entry->datatype == _bool)) 
                        {
                          stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_entry);
                          if (stackframe_element != NULL)
                          {
// **************************************************************************************
// * Now I will call bool_display (internal library) to display the value of a variable *
// **************************************************************************************
                            code_section_string_buffer_max_length = 4096;
                            assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * code_section_string_buffer_max_length);
                            if (assembler_statement->code_section_contents != NULL)
                            {
                              snprintf (assembler_statement->code_section_contents, code_section_string_buffer_max_length, "     movzx eax, BYTE PTR -%ld[rbp]\n     mov edi, eax\n     call bool_display@PLT\n", stackframe_element->stackframe_offset);
                              state = 20;
                              ast_element = ast_element->sibling;
                              if (assembler_program != NULL)
                              {
                                temp_assembler_element = assembler_program;
                                while (temp_assembler_element->next != NULL)
                                {
                                  temp_assembler_element = temp_assembler_element->next;
                                }
                                temp_assembler_element->next = assembler_statement;
                              }
                              else
                              {
                                assembler_program = assembler_statement;
                              }
                            }
                            else
                            {
                              state = 99999;
                            }
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          state = 99999;
                        }
                      } 
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        }
        else
        {
          state = 99999;
        }
      break;  
      case 20:
        assembler_statement  = malloc(sizeof(asmblr_node));
        if (assembler_statement != NULL)
        {
          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
          assembler_statement->abstract_syntax_tree  = ast_element;
          assembler_statement->label                 = 0;
          assembler_statement->code_section_contents = NULL;       
          assembler_statement->data_section_contents = NULL;       
          assembler_statement->next                  = NULL;
          state = 10;
        }
        else
        {
          state = 99999;
        }
      break;
      default:
      break;
    } 
  }
  return assembler_program;
}




asmblr_node * create_assembler_output_set_statement_numerical_expression_integer (asmblr_node *assembler_program, ast_node *abstract_syntax_tree, symtab_node *symbol_table, stackframe_node *stackframe_cross_reference_table)
{
  asmblr_node *assembler_statement, *temp_assembler_element;
  ast_node *ast_element;
  symtab_node *symbol_table_element, *temporary_storage_variable, *operand1_symbol_table_entry, *operand2_symbol_table_entry;
  expression_stack_node *expression_stack, *temp_variables_used_stack;
  stackframe_node *stackframe_element, *stackframe_element_operand1, *stackframe_element_operand2, *stackframe_element_target_variable;
  unsigned long long int scope_level, assembly_output_data_label, temp_jump_label1, temp_jump_label2, counter_for_new_variables;
  chaga_attribute_type attribute_type;
  chaga_attribute_datatype datatype, desired_datatype;
  int state, token_type;
  unsigned char *operand1, *operand2, *code_section_assembly_language_output_buffer, *data_section_assembly_language_output_buffer, new_variable[1024];
  size_t i, operand1_string_length, operand2_string_length, token_string_length, code_section_assembly_language_output_buffer_max_length, data_section_assembly_language_output_buffer_length;
  char *token, *expression_stack_token;

  expression_stack = NULL;
  temp_variables_used_stack = NULL;
  if (abstract_syntax_tree != NULL)
  {
    state = 0;
    expression_stack = NULL;
    ast_element = abstract_syntax_tree;
    while ((ast_element != NULL) && (state != 99999))
    {
      token = ast_element->token;
      token_type = ast_element->token_type;
      if (token != NULL)
      {
        //printf ("\nIn create_assembler_output_set_statement_numerical_expression_integer: state = %d, ast_element->token = %s,\n", state, token);
        //printf ("EXPRESSION STACK FRAME:");
        //display_expression_stack (expression_stack);
        //putchar ('\n');
        switch (state)
        {
          case 0:
            if (token_type == TOKEN_IDENTIFIER)
            {
              symbol_table_element = ast_element->symbol_table_entry;
              if (symbol_table_element != NULL)
              {
                stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                if (stackframe_element != NULL)
                {
                  scope_level      = symbol_table_element->scope_level;
                  attribute_type   = symbol_table_element->attribute_type;
                  datatype         = symbol_table_element->datatype;              
                  expression_stack = push_expression_stack (expression_stack, token, token_type, NULL, stackframe_element);
                  symbol_table_set_status_to_available_unused_temporary_variables_for_numerical_expression_processing (symbol_table, scope_level);
                  assembly_output_data_label = retrieve_highest_label_number_from_assembly_output (assembler_program);
                  state = 20;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          break;
          case 20:
            if (token_type == TOKEN_IDENTIFIER)
            {
              symbol_table_element = ast_element->symbol_table_entry;
              if (symbol_table_element != NULL)
              {
                stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                if (stackframe_element != NULL)
                {
                  expression_stack = push_expression_stack (expression_stack, token, token_type, NULL, stackframe_element);
                  state = 20;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT)
              {
                symbol_table_element = ast_element->symbol_table_entry;
                if (symbol_table_element != NULL)
                {
                  if (symbol_table_element->identifier != NULL)
                  {
                    token_string_length = strlen(token);
                    data_section_assembly_language_output_buffer_length = token_string_length + 31;
                    data_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char)*data_section_assembly_language_output_buffer_length); 
                    if (data_section_assembly_language_output_buffer != NULL)
                    {
                      data_section_assembly_language_output_buffer[0]  = ' ';
                      data_section_assembly_language_output_buffer[1]  = ' ';
                      data_section_assembly_language_output_buffer[2]  = ' ';
                      data_section_assembly_language_output_buffer[3]  = ' ';
                      data_section_assembly_language_output_buffer[4]  = ' ';
                      data_section_assembly_language_output_buffer[5]  = '.';
                      data_section_assembly_language_output_buffer[6]  = 's';
                      data_section_assembly_language_output_buffer[7]  = 't';
                      data_section_assembly_language_output_buffer[8]  = 'r';
                      data_section_assembly_language_output_buffer[9]  = 'i';
                      data_section_assembly_language_output_buffer[10] = 'n';
                      data_section_assembly_language_output_buffer[11] = 'g';
                      data_section_assembly_language_output_buffer[12] = ' ';
                      data_section_assembly_language_output_buffer[13] = '"';
                      for (i = 0; i < token_string_length; i++)
                      {
                        data_section_assembly_language_output_buffer[14+i] = token[i];
                      }
                      data_section_assembly_language_output_buffer[14+token_string_length] = '"';
                      data_section_assembly_language_output_buffer[15+token_string_length] = '\n';
                      data_section_assembly_language_output_buffer[16+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[17+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[18+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[19+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[20+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[21+token_string_length] = '.';
                      data_section_assembly_language_output_buffer[22+token_string_length] = 'a';
                      data_section_assembly_language_output_buffer[23+token_string_length] = 'l';
                      data_section_assembly_language_output_buffer[24+token_string_length] = 'i';
                      data_section_assembly_language_output_buffer[25+token_string_length] = 'g';
                      data_section_assembly_language_output_buffer[26+token_string_length] = 'n';
                      data_section_assembly_language_output_buffer[27+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[28+token_string_length] = '8';
                      data_section_assembly_language_output_buffer[29+token_string_length] = '\n';
                      data_section_assembly_language_output_buffer[30+token_string_length] = '\0';
                    }
                    stackframe_element = NULL;
                    temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, _datatype, _int, scope_level);
                    if (temporary_storage_variable != NULL)
                    {
                      if (temporary_storage_variable->identifier != NULL)
                      {
                        stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, temporary_storage_variable);
                      }
                    }
                    if (stackframe_element != NULL)
                    {
                      code_section_assembly_language_output_buffer_max_length = 4096;
                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                      if (code_section_assembly_language_output_buffer != NULL)
                      {	
                        assembly_output_data_label++; // increment to next unused label
                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     lea rdx, .M%lld[rip]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_set_value@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element->stackframe_offset, assembly_output_data_label, stackframe_element->stackframe_offset);
                      }
                      if ((data_section_assembly_language_output_buffer != NULL) && (code_section_assembly_language_output_buffer != NULL))
                      {
                        //printf ("L%lld:\n", assembly_output_data_label);
                        //printf ("%s\n", data_section_assembly_language_output_buffer);
                        //printf ("%s\n", code_section_assembly_language_output_buffer);
                        assembler_statement  = malloc(sizeof(asmblr_node));
                        if (assembler_statement != NULL)
                        {
                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                          assembler_statement->abstract_syntax_tree  = NULL;
                          assembler_statement->label                 = assembly_output_data_label;
                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                          assembler_statement->data_section_contents = data_section_assembly_language_output_buffer;
                          assembler_statement->next                  = NULL;
                        }
                        if (assembler_program != NULL)
                        {
                          temp_assembler_element = assembler_program;
                          while (temp_assembler_element->next != NULL)
                          {
                            temp_assembler_element = temp_assembler_element->next;
                          }
                          temp_assembler_element->next = assembler_statement;
                        }
                        else
                        {
                          assembler_program = assembler_statement;
                        }
                      }
                      expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, stackframe_element);
                      temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                      temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                      state = 20;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                if ((token_type == TOKEN_PLUS)     || 
                    (token_type == TOKEN_MINUS)    || 
                    (token_type == TOKEN_ASTERISK) || 
                    (token_type == TOKEN_DIVIDE)   || 
                    (token_type == TOKEN_CARET)    || 
                    (token_type == TOKEN_MODULO))
                {
                  operand1 = NULL;
                  operand2 = NULL;
                  stackframe_element_operand1 = NULL;
                  stackframe_element_operand2 = NULL;
                  if (expression_stack != NULL)
                  {
                    if (expression_stack->token != NULL)
                    {
                      expression_stack_token = expression_stack->token;
                      if (expression_stack_token != NULL)
                      {
                        stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                        operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                        operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                        if (operand2 != NULL)
                        {
                          strncpy (operand2, expression_stack_token, operand2_string_length);
                        }
                      }
                    }
                    else
                    {
                      if (expression_stack->temporary_variable_identifier != NULL)
                      {
                        stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                        operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                        operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                        if (operand2 != NULL)
                        {
                          strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                        }
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                  }
                  if (expression_stack != NULL)
                  {
                    if (expression_stack->token != NULL)
                    {
                      expression_stack_token = expression_stack->token;
                      if (expression_stack_token != NULL)
                      {
                        stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                        operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                        operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                        if (operand1 != NULL)
                        {
                          strncpy (operand1, expression_stack_token, operand1_string_length);
                        }
                      }
                    }
                    else
                    {
                      if (expression_stack->temporary_variable_identifier != NULL)
                      {
                        stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                        operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                        operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                        if (operand1 != NULL)
                        {
                          strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                        }
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                  }
                  if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                  {
                    operand1_symbol_table_entry = stackframe_element_operand1->symbol_table_entry;
                    operand2_symbol_table_entry = stackframe_element_operand1->symbol_table_entry;
                    desired_datatype = _void;
                    if ((operand1_symbol_table_entry != NULL) && (operand2_symbol_table_entry != NULL))
                    {
                      if ((operand1_symbol_table_entry->attribute_type == _datatype) && (operand2_symbol_table_entry->attribute_type == _datatype))
                      {
                        if (operand1_symbol_table_entry->datatype == operand2_symbol_table_entry->datatype)
                        {
                          desired_datatype = operand1_symbol_table_entry->datatype;
                        }
                      }
                    }

                    temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, _datatype, desired_datatype, scope_level);
                    if (temporary_storage_variable != NULL)
                    {
                      if (temporary_storage_variable->identifier != NULL)
                      {

                        temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                        temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);



                        if (token_type == TOKEN_PLUS)
                        {
                          if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                          {
                            code_section_assembly_language_output_buffer_max_length = 4096;
                            code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                            if (code_section_assembly_language_output_buffer != NULL)
                            {
                              stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                              if (stackframe_element_target_variable != NULL)
                              {
                                snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_add@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                assembler_statement  = malloc(sizeof(asmblr_node));
                                if (assembler_statement != NULL)
                                {
                                  assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                  assembler_statement->abstract_syntax_tree  = NULL;
                                  assembler_statement->label                 = assembly_output_data_label;
                                  assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                  assembler_statement->data_section_contents = NULL;
                                  assembler_statement->next                  = NULL;
                                }
                                if (assembler_program != NULL)
                                {
                                  temp_assembler_element = assembler_program;
                                  while (temp_assembler_element->next != NULL)
                                  {
                                    temp_assembler_element = temp_assembler_element->next;
                                  }
                                  temp_assembler_element->next = assembler_statement;
                                }
                                else
                                {
                                  assembler_program = assembler_statement;
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          if (token_type == TOKEN_MINUS)
                          {
                            if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                            {
                              code_section_assembly_language_output_buffer_max_length = 4096;
                              code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                              if (code_section_assembly_language_output_buffer != NULL)
                              {
                                stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                if (stackframe_element_target_variable != NULL)
                                {
                                  snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_subtract@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                  assembler_statement  = malloc(sizeof(asmblr_node));
                                  if (assembler_statement != NULL)
                                  {
                                    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                    assembler_statement->abstract_syntax_tree  = NULL;
                                    assembler_statement->label                 = assembly_output_data_label;
                                    assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                    assembler_statement->data_section_contents = NULL;
                                    assembler_statement->next                  = NULL;
                                  }
                                  if (assembler_program != NULL)
                                  {
                                    temp_assembler_element = assembler_program;
                                    while (temp_assembler_element->next != NULL)
                                    {
                                      temp_assembler_element = temp_assembler_element->next;
                                    }
                                    temp_assembler_element->next = assembler_statement;
                                  }
                                  else
                                  {
                                    assembler_program = assembler_statement;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                            }
                            else
                            {
                              state = 99999;
                            }
                          }
                          else
                          {
                            if (token_type == TOKEN_ASTERISK)
                            {
                              if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                              {
                                code_section_assembly_language_output_buffer_max_length = 4096;
                                code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                if (code_section_assembly_language_output_buffer != NULL)
                                {
                                  stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                  if (stackframe_element_target_variable != NULL)
                                  {
                                    snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_multiply@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                    assembler_statement = malloc(sizeof(asmblr_node));
                                    if (assembler_statement != NULL)
                                    {
                                      assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                      assembler_statement->abstract_syntax_tree  = NULL;
                                      assembler_statement->label                 = assembly_output_data_label;
                                      assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                      assembler_statement->data_section_contents = NULL;
                                      assembler_statement->next                  = NULL;
                                    }
                                    if (assembler_program != NULL)
                                    {
                                      temp_assembler_element = assembler_program;
                                      while (temp_assembler_element->next != NULL)
                                      {
                                        temp_assembler_element = temp_assembler_element->next;
                                      }
                                      temp_assembler_element->next = assembler_statement;
                                    }
                                    else
                                    {
                                      assembler_program = assembler_statement;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                            else
                            {
                              if (token_type == TOKEN_DIVIDE)
                              {
                                if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                {
                                  code_section_assembly_language_output_buffer_max_length = 4096;
                                  code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                  if (code_section_assembly_language_output_buffer != NULL)
                                  {
                                    stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                    if (stackframe_element_target_variable != NULL)
                                    {
                                      snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_divide@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                      assembler_statement = malloc(sizeof(asmblr_node));
                                      if (assembler_statement != NULL)
                                      {
                                        assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                        assembler_statement->abstract_syntax_tree  = NULL;
                                        assembler_statement->label                 = assembly_output_data_label;
                                        assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                        assembler_statement->data_section_contents = NULL;
                                        assembler_statement->next                  = NULL;
                                      }
                                      if (assembler_program != NULL)
                                      {
                                        temp_assembler_element = assembler_program;
                                        while (temp_assembler_element->next != NULL)
                                        {
                                          temp_assembler_element = temp_assembler_element->next;
                                        }
                                        temp_assembler_element->next = assembler_statement;
                                      }
                                      else
                                      {
                                        assembler_program = assembler_statement;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                              else
                              {
                                if (token_type == TOKEN_CARET)
                                {
                                  //printf ("%s = stringint_power (%s, %s);\n", temporary_storage_variable->identifier, operand1, operand2);
                                }
                                else
                                {
                                  if (token_type == TOKEN_MODULO)
                                  {
                                    if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                    {
                                      code_section_assembly_language_output_buffer_max_length = 4096;
                                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                      if (code_section_assembly_language_output_buffer != NULL)
                                      {
                                        stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                        if (stackframe_element_target_variable != NULL)
                                        {
                                          snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_modulo@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                          assembler_statement = malloc(sizeof(asmblr_node));
                                          if (assembler_statement != NULL)
                                          {
                                            assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                            assembler_statement->abstract_syntax_tree  = NULL;
                                            assembler_statement->label                 = assembly_output_data_label;
                                            assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                            assembler_statement->data_section_contents = NULL;
                                            assembler_statement->next                  = NULL;
                                          }
                                          if (assembler_program != NULL)
                                          {
                                            temp_assembler_element = assembler_program;
                                            while (temp_assembler_element->next != NULL)
                                            {
                                              temp_assembler_element = temp_assembler_element->next;
                                            }
                                            temp_assembler_element->next = assembler_statement;
                                          }
                                          else
                                          {
                                            assembler_program = assembler_statement;
                                          }
                                        }
                                        else
                                        {
                                          state = 99999;
                                        }
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                        expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                        state = 20;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  if (token_type == TOKEN_ASSIGNMENT)
                  {
                    operand1 = NULL;
                    operand2 = NULL;
                    stackframe_element_operand1 = NULL;
                    stackframe_element_operand2 = NULL;
                    if (expression_stack != NULL)
                    {
                      if (expression_stack->token != NULL)
                      {
                        expression_stack_token = expression_stack->token;
                        if (expression_stack_token != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack_token, scope_level);
                          operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                          if (operand2 != NULL)
                          {
                            strncpy (operand2, expression_stack_token, operand2_string_length);
                          }
                        }
                      }
                      else
                      {
                        if (expression_stack->temporary_variable_identifier != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                          operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                          if (operand2 != NULL)
                          {
                            strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    if (expression_stack != NULL)
                    {
                      if (expression_stack->token != NULL)
                      {
                        expression_stack_token = expression_stack->token;
                        if (expression_stack_token != NULL)
                        {
                          stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack_token, scope_level);
                          operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                          if (operand1 != NULL)
                          {
                            strncpy (operand1, expression_stack_token, operand1_string_length);
                          }
                        }
                      }
                      else
                      {
                        if (expression_stack->temporary_variable_identifier != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                          operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                          if (operand1 != NULL)
                          {
                            strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                    {
                      code_section_assembly_language_output_buffer_max_length = 4096;
                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                      if (code_section_assembly_language_output_buffer != NULL)
                      {
                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_copy_number@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_operand1->stackframe_offset);
                        assembler_statement  = malloc(sizeof(asmblr_node));
                        if (assembler_statement != NULL)
                        {
                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                          assembler_statement->abstract_syntax_tree  = NULL;
                          assembler_statement->label                 = 0;  // The label is not used.
                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                          assembler_statement->data_section_contents = NULL;
                          assembler_statement->next                  = NULL;
                        }
                        if (assembler_program != NULL)
                        {
                          temp_assembler_element = assembler_program;
                          while (temp_assembler_element->next != NULL)
                          {
                            temp_assembler_element = temp_assembler_element->next;
                          }
                          temp_assembler_element->next = assembler_statement;
                        }
                        else
                        {
                          assembler_program = assembler_statement;
                        }
                        while (expression_stack != NULL) // empty the expression stack since we've evaluated the entire numerical expression.
                        {
                          expression_stack = pop_expression_stack (expression_stack);
                        }
// ***************************************************************************************
// * Now it's time to release memory for all temporary variables used in the evaluation. *
// ***************************************************************************************
                        while (temp_variables_used_stack != NULL)
                        {
                          if (temp_variables_used_stack->temporary_variable_identifier != NULL)
                          {
                            stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temp_variables_used_stack->temporary_variable_identifier, scope_level);
                            if (stackframe_element_operand1 != NULL)
                            {
// ********************************************************************************************************************************************
// * Check if the stackframe element is a pointer to a string integer. If it is, we must release the memory pointed at by the string integer. *
// * Other variables, such as Boolean are stored directly on stack frame. Thus, no special release of memory from heap is required.           *
// ********************************************************************************************************************************************
                              temporary_storage_variable = stackframe_element_operand1->symbol_table_entry;
                              if ((temporary_storage_variable->attribute_type == _datatype) && (temporary_storage_variable->datatype == _int))
                              {
                                code_section_assembly_language_output_buffer_max_length = 4096;
                                code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                if (code_section_assembly_language_output_buffer != NULL)
                                {
                                  snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     mov rdi, rax\n     call packed_string_integer_release_memory\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand1->stackframe_offset);
                                  assembler_statement  = malloc(sizeof(asmblr_node));
                                  if (assembler_statement != NULL)
                                  {
                                    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                    assembler_statement->abstract_syntax_tree  = NULL;
                                    assembler_statement->label                 = assembly_output_data_label;
                                    assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                    assembler_statement->data_section_contents = NULL;
                                    assembler_statement->next                  = NULL;
                                  }
                                  if (assembler_program != NULL)
                                  {
                                    temp_assembler_element = assembler_program;
                                    while (temp_assembler_element->next != NULL)
                                    {
                                      temp_assembler_element = temp_assembler_element->next;
                                    }
                                    temp_assembler_element->next = assembler_statement;
                                  }
                                  else
                                  {
                                    assembler_program = assembler_statement;
                                  }
                                }
                              }
                            }
                          }
                          temp_variables_used_stack = pop_expression_stack (temp_variables_used_stack);
                        }
                        state = 20;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                } 
              }
            }
          break;
          default:
          break;
        } 
      }
      else
      {
        state = 99999;
      }
      if (state != 99999)
      {
        ast_element = ast_element->sibling;
      }
    }
  }
  return assembler_program;
}




asmblr_node * create_assembler_output_set_statement_numerical_expression_float (asmblr_node *assembler_program, ast_node *abstract_syntax_tree, symtab_node *symbol_table, stackframe_node *stackframe_cross_reference_table)
{
  asmblr_node *assembler_statement, *temp_assembler_element;
  ast_node *ast_element;
  symtab_node *symbol_table_element, *temporary_storage_variable, *operand1_symbol_table_entry, *operand2_symbol_table_entry;
  expression_stack_node *expression_stack, *temp_variables_used_stack;
  stackframe_node *stackframe_element, *stackframe_element_operand1, *stackframe_element_operand2, *stackframe_element_target_variable;
  unsigned long long int scope_level, assembly_output_data_label, temp_jump_label1, temp_jump_label2, counter_for_new_variables;
  chaga_attribute_type attribute_type;
  chaga_attribute_datatype datatype, desired_datatype;
  int state, token_type;
  unsigned char *operand1, *operand2, *code_section_assembly_language_output_buffer, *data_section_assembly_language_output_buffer, new_variable[1024];
  size_t i, operand1_string_length, operand2_string_length, token_string_length, code_section_assembly_language_output_buffer_max_length, data_section_assembly_language_output_buffer_length;
  char *token, *expression_stack_token;

  expression_stack = NULL;
  temp_variables_used_stack = NULL;
  if (abstract_syntax_tree != NULL)
  {
    state = 0;
    expression_stack = NULL;
    ast_element = abstract_syntax_tree;
    while ((ast_element != NULL) && (state != 99999))
    {
      token = ast_element->token;
      token_type = ast_element->token_type;
      if (token != NULL)
      {
        //printf ("\nIn create_assembler_output_set_statement_numerical_expression_float: state = %d, ast_element->token = %s,\n", state, token);
        //printf ("EXPRESSION STACK FRAME:");
        //display_expression_stack (expression_stack);
        //putchar ('\n');
        switch (state)
        {
          case 0:
            if (token_type == TOKEN_IDENTIFIER)
            {
              symbol_table_element = ast_element->symbol_table_entry;
              if (symbol_table_element != NULL)
              {
                stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                if (stackframe_element != NULL)
                {
                  scope_level      = symbol_table_element->scope_level;
                  attribute_type   = symbol_table_element->attribute_type;
                  datatype         = symbol_table_element->datatype;              
                  expression_stack = push_expression_stack (expression_stack, token, token_type, NULL, stackframe_element);
                  symbol_table_set_status_to_available_unused_temporary_variables_for_numerical_expression_processing (symbol_table, scope_level);
                  assembly_output_data_label = retrieve_highest_label_number_from_assembly_output (assembler_program);
                  state = 20;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          break;
          case 20:
            if (token_type == TOKEN_IDENTIFIER)
            {
              symbol_table_element = ast_element->symbol_table_entry;
              if (symbol_table_element != NULL)
              {
                stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                if (stackframe_element != NULL)
                {
                  expression_stack = push_expression_stack (expression_stack, token, token_type, NULL, stackframe_element);
                  state = 20;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999; // NOT HERE
              }
            }
            else
            {
              if ((token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (token_type == TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT))
              {
                symbol_table_element = ast_element->symbol_table_entry;
                if (symbol_table_element != NULL)
                {
                  if (symbol_table_element->identifier != NULL)
                  {
                    token_string_length = strlen(token);
                    data_section_assembly_language_output_buffer_length = token_string_length + 31;
                    data_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char)*data_section_assembly_language_output_buffer_length); 
                    if (data_section_assembly_language_output_buffer != NULL)
                    {
                      data_section_assembly_language_output_buffer[0]  = ' ';
                      data_section_assembly_language_output_buffer[1]  = ' ';
                      data_section_assembly_language_output_buffer[2]  = ' ';
                      data_section_assembly_language_output_buffer[3]  = ' ';
                      data_section_assembly_language_output_buffer[4]  = ' ';
                      data_section_assembly_language_output_buffer[5]  = '.';
                      data_section_assembly_language_output_buffer[6]  = 's';
                      data_section_assembly_language_output_buffer[7]  = 't';
                      data_section_assembly_language_output_buffer[8]  = 'r';
                      data_section_assembly_language_output_buffer[9]  = 'i';
                      data_section_assembly_language_output_buffer[10] = 'n';
                      data_section_assembly_language_output_buffer[11] = 'g';
                      data_section_assembly_language_output_buffer[12] = ' ';
                      data_section_assembly_language_output_buffer[13] = '"';
                      for (i = 0; i < token_string_length; i++)
                      {
                        data_section_assembly_language_output_buffer[14+i] = token[i];
                      }
                      data_section_assembly_language_output_buffer[14+token_string_length] = '"';
                      data_section_assembly_language_output_buffer[15+token_string_length] = '\n';
                      data_section_assembly_language_output_buffer[16+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[17+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[18+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[19+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[20+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[21+token_string_length] = '.';
                      data_section_assembly_language_output_buffer[22+token_string_length] = 'a';
                      data_section_assembly_language_output_buffer[23+token_string_length] = 'l';
                      data_section_assembly_language_output_buffer[24+token_string_length] = 'i';
                      data_section_assembly_language_output_buffer[25+token_string_length] = 'g';
                      data_section_assembly_language_output_buffer[26+token_string_length] = 'n';
                      data_section_assembly_language_output_buffer[27+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[28+token_string_length] = '8';
                      data_section_assembly_language_output_buffer[29+token_string_length] = '\n';
                      data_section_assembly_language_output_buffer[30+token_string_length] = '\0';
                    }
                    stackframe_element = NULL;
                    temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, _datatype, _float, scope_level);
                    if (temporary_storage_variable != NULL)
                    {
                      if (temporary_storage_variable->identifier != NULL)
                      {
                        stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, temporary_storage_variable);
                      }
                    }
                    if (stackframe_element != NULL)
                    {
                      code_section_assembly_language_output_buffer_max_length = 4096;
                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                      if (code_section_assembly_language_output_buffer != NULL)
                      {	
                        assembly_output_data_label++; // increment to next unused label
                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     lea rdx, .M%lld[rip]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_float_set_value@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element->stackframe_offset, assembly_output_data_label, stackframe_element->stackframe_offset);
                      }
                      if ((data_section_assembly_language_output_buffer != NULL) && (code_section_assembly_language_output_buffer != NULL))
                      {
                        //printf ("L%lld:\n", assembly_output_data_label);
                        //printf ("%s\n", data_section_assembly_language_output_buffer);
                        //printf ("%s\n", code_section_assembly_language_output_buffer);
                        assembler_statement  = malloc(sizeof(asmblr_node));
                        if (assembler_statement != NULL)
                        {
                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                          assembler_statement->abstract_syntax_tree  = NULL;
                          assembler_statement->label                 = assembly_output_data_label;
                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                          assembler_statement->data_section_contents = data_section_assembly_language_output_buffer;
                          assembler_statement->next                  = NULL;
                        }
                        if (assembler_program != NULL)
                        {
                          temp_assembler_element = assembler_program;
                          while (temp_assembler_element->next != NULL)
                          {
                            temp_assembler_element = temp_assembler_element->next;
                          }
                          temp_assembler_element->next = assembler_statement;
                        }
                        else
                        {
                          assembler_program = assembler_statement;
                        }
                      }
                      expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, stackframe_element);
                      temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                      temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                      state = 20;
                    }
                    else
                    {
                      state = 99999; // NOT HERE
                    }
                  }
                  else
                  {
                    state = 99999; // NOT HERE
                  }
                }
                else
                {
                  state = 99999; // NOT HERE
                }
              }
              else
              {
                if ((token_type == TOKEN_PLUS)     || 
                    (token_type == TOKEN_MINUS)    || 
                    (token_type == TOKEN_ASTERISK) || 
                    (token_type == TOKEN_DIVIDE)   || 
                    (token_type == TOKEN_CARET))
                {
                  operand1 = NULL;
                  operand2 = NULL;
                  stackframe_element_operand1 = NULL;
                  stackframe_element_operand2 = NULL;
                  if (expression_stack != NULL)
                  {
                    if (expression_stack->token != NULL)
                    {
                      expression_stack_token = expression_stack->token;
                      if (expression_stack_token != NULL)
                      {
                        stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                        operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                        operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                        if (operand2 != NULL)
                        {
                          strncpy (operand2, expression_stack_token, operand2_string_length);
                        }
                      }
                    }
                    else
                    {
                      if (expression_stack->temporary_variable_identifier != NULL)
                      {
                        stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                        operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                        operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                        if (operand2 != NULL)
                        {
                          strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                        }
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                  }
                  if (expression_stack != NULL)
                  {
                    if (expression_stack->token != NULL)
                    {
                      expression_stack_token = expression_stack->token;
                      if (expression_stack_token != NULL)
                      {
                        stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                        operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                        operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                        if (operand1 != NULL)
                        {
                          strncpy (operand1, expression_stack_token, operand1_string_length);
                        }
                      }
                    }
                    else
                    {
                      if (expression_stack->temporary_variable_identifier != NULL)
                      {
                        stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                        operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                        operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                        if (operand1 != NULL)
                        {
                          strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                        }
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                  }
                  if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                  {
                    operand1_symbol_table_entry = stackframe_element_operand1->symbol_table_entry;
                    operand2_symbol_table_entry = stackframe_element_operand1->symbol_table_entry;
                    desired_datatype = _void;
                    if ((operand1_symbol_table_entry != NULL) && (operand2_symbol_table_entry != NULL))
                    {
                      if ((operand1_symbol_table_entry->attribute_type == _datatype) && (operand2_symbol_table_entry->attribute_type == _datatype))
                      {
                        if (operand1_symbol_table_entry->datatype == operand2_symbol_table_entry->datatype)
                        {
                          desired_datatype = operand1_symbol_table_entry->datatype;
                        }
                      }
                    }
                    temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, _datatype, desired_datatype, scope_level);
                    if (temporary_storage_variable != NULL)
                    {
                      if (temporary_storage_variable->identifier != NULL)
                      {
                        temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                        temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                        if (token_type == TOKEN_PLUS)
                        {
                          if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                          {
                            code_section_assembly_language_output_buffer_max_length = 4096;
                            code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                            if (code_section_assembly_language_output_buffer != NULL)
                            {
                              stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                              if (stackframe_element_target_variable != NULL)
                              {
                                snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_float_add@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                assembler_statement  = malloc(sizeof(asmblr_node));
                                if (assembler_statement != NULL)
                                {
                                  assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                  assembler_statement->abstract_syntax_tree  = NULL;
                                  assembler_statement->label                 = assembly_output_data_label;
                                  assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                  assembler_statement->data_section_contents = NULL;
                                  assembler_statement->next                  = NULL;
                                }
                                if (assembler_program != NULL)
                                {
                                  temp_assembler_element = assembler_program;
                                  while (temp_assembler_element->next != NULL)
                                  {
                                    temp_assembler_element = temp_assembler_element->next;
                                  }
                                  temp_assembler_element->next = assembler_statement;
                                }
                                else
                                {
                                  assembler_program = assembler_statement;
                                }
                              }
                              else
                              {
                                state = 99999; // NOT HERE
                              }
                            }
                          }
                          else
                          {
                            state = 99999; // NOT HERE
                          }
                        }
                        else
                        {
                          if (token_type == TOKEN_MINUS)
                          {
                            if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                            {
                              code_section_assembly_language_output_buffer_max_length = 4096;
                              code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                              if (code_section_assembly_language_output_buffer != NULL)
                              {
                                stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                if (stackframe_element_target_variable != NULL)
                                {
                                  snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_float_subtract@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                  assembler_statement  = malloc(sizeof(asmblr_node));
                                  if (assembler_statement != NULL)
                                  {
                                    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                    assembler_statement->abstract_syntax_tree  = NULL;
                                    assembler_statement->label                 = assembly_output_data_label;
                                    assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                    assembler_statement->data_section_contents = NULL;
                                    assembler_statement->next                  = NULL;
                                  }
                                  if (assembler_program != NULL)
                                  {
                                    temp_assembler_element = assembler_program;
                                    while (temp_assembler_element->next != NULL)
                                    {
                                      temp_assembler_element = temp_assembler_element->next;
                                    }
                                    temp_assembler_element->next = assembler_statement;
                                  }
                                  else
                                  {
                                    assembler_program = assembler_statement;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                            }
                            else
                            {
                              state = 99999;
                            }
                          }
                          else
                          {
                            if (token_type == TOKEN_ASTERISK)
                            {
                              if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                              {
                                code_section_assembly_language_output_buffer_max_length = 4096;
                                code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                if (code_section_assembly_language_output_buffer != NULL)
                                {
                                  stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                  if (stackframe_element_target_variable != NULL)
                                  {
                                    snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_float_multiply@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                    assembler_statement = malloc(sizeof(asmblr_node));
                                    if (assembler_statement != NULL)
                                    {
                                      assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                      assembler_statement->abstract_syntax_tree  = NULL;
                                      assembler_statement->label                 = assembly_output_data_label;
                                      assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                      assembler_statement->data_section_contents = NULL;
                                      assembler_statement->next                  = NULL;
                                    }
                                    if (assembler_program != NULL)
                                    {
                                      temp_assembler_element = assembler_program;
                                      while (temp_assembler_element->next != NULL)
                                      {
                                        temp_assembler_element = temp_assembler_element->next;
                                      }
                                      temp_assembler_element->next = assembler_statement;
                                    }
                                    else
                                    {
                                      assembler_program = assembler_statement;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                            else
                            {
                              if (token_type == TOKEN_DIVIDE)
                              {
                                if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                {
                                  code_section_assembly_language_output_buffer_max_length = 4096;
                                  code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                  if (code_section_assembly_language_output_buffer != NULL)
                                  {
                                    stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                    if (stackframe_element_target_variable != NULL)
                                    {
                                      snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rsi, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov ecx, 100\n     mov rdi, rax\n     call packed_string_float_divide@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                      assembler_statement = malloc(sizeof(asmblr_node));
                                      if (assembler_statement != NULL)
                                      {
                                        assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                        assembler_statement->abstract_syntax_tree  = NULL;
                                        assembler_statement->label                 = assembly_output_data_label;
                                        assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                        assembler_statement->data_section_contents = NULL;
                                        assembler_statement->next                  = NULL;
                                      }
                                      if (assembler_program != NULL)
                                      {
                                        temp_assembler_element = assembler_program;
                                        while (temp_assembler_element->next != NULL)
                                        {
                                          temp_assembler_element = temp_assembler_element->next;
                                        }
                                        temp_assembler_element->next = assembler_statement;
                                      }
                                      else
                                      {
                                        assembler_program = assembler_statement;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                              else
                              {
                                if (token_type == TOKEN_CARET)
                                {
                                  //printf ("%s = stringint_power (%s, %s);\n", temporary_storage_variable->identifier, operand1, operand2);
                                }
                              }
                            }
                          }
                        }
                        expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                        state = 20;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  if (token_type == TOKEN_ASSIGNMENT)
                  {
                    operand1 = NULL;
                    operand2 = NULL;
                    stackframe_element_operand1 = NULL;
                    stackframe_element_operand2 = NULL;
                    if (expression_stack != NULL)
                    {
                      if (expression_stack->token != NULL)
                      {
                        expression_stack_token = expression_stack->token;
                        if (expression_stack_token != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack_token, scope_level);
                          operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                          if (operand2 != NULL)
                          {
                            strncpy (operand2, expression_stack_token, operand2_string_length);
                          }
                        }
                      }
                      else
                      {
                        if (expression_stack->temporary_variable_identifier != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                          operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                          if (operand2 != NULL)
                          {
                            strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    if (expression_stack != NULL)
                    {
                      if (expression_stack->token != NULL)
                      {
                        expression_stack_token = expression_stack->token;
                        if (expression_stack_token != NULL)
                        {
                          stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack_token, scope_level);
                          operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                          if (operand1 != NULL)
                          {
                            strncpy (operand1, expression_stack_token, operand1_string_length);
                          }
                        }
                      }
                      else
                      {
                        if (expression_stack->temporary_variable_identifier != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                          operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                          if (operand1 != NULL)
                          {
                            strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                    {
                      code_section_assembly_language_output_buffer_max_length = 4096;
                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                      if (code_section_assembly_language_output_buffer != NULL)
                      {
                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_float_copy_number@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_operand1->stackframe_offset);
                        assembler_statement  = malloc(sizeof(asmblr_node));
                        if (assembler_statement != NULL)
                        {
                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                          assembler_statement->abstract_syntax_tree  = NULL;
                          assembler_statement->label                 = 0;  // The label is not used.
                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                          assembler_statement->data_section_contents = NULL;
                          assembler_statement->next                  = NULL;
                        }
                        if (assembler_program != NULL)
                        {
                          temp_assembler_element = assembler_program;
                          while (temp_assembler_element->next != NULL)
                          {
                            temp_assembler_element = temp_assembler_element->next;
                          }
                          temp_assembler_element->next = assembler_statement;
                        }
                        else
                        {
                          assembler_program = assembler_statement;
                        }
                        while (expression_stack != NULL) // empty the expression stack since we've evaluated the entire numerical expression.
                        {
                          expression_stack = pop_expression_stack (expression_stack);
                        }
// ***************************************************************************************
// * Now it's time to release memory for all temporary variables used in the evaluation. *
// ***************************************************************************************
                        while (temp_variables_used_stack != NULL)
                        {
                          if (temp_variables_used_stack->temporary_variable_identifier != NULL)
                          {
                            stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temp_variables_used_stack->temporary_variable_identifier, scope_level);
                            if (stackframe_element_operand1 != NULL)
                            {
// ****************************************************************************************************************************************
// * Check if the stackframe element is a pointer to a string float. If it is, we must release the memory pointed at by the string float. *
// * Other variables, such as Boolean are stored directly on stack frame. Thus, no special release of memory from heap is required.       *
// ****************************************************************************************************************************************
                              temporary_storage_variable = stackframe_element_operand1->symbol_table_entry;
                              if ((temporary_storage_variable->attribute_type == _datatype) && (temporary_storage_variable->datatype == _float))
                              {
                                code_section_assembly_language_output_buffer_max_length = 4096;
                                code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                if (code_section_assembly_language_output_buffer != NULL)
                                {
                                  snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     mov rdi, rax\n     call packed_string_float_release_memory\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand1->stackframe_offset);
                                  assembler_statement  = malloc(sizeof(asmblr_node));
                                  if (assembler_statement != NULL)
                                  {
                                    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                    assembler_statement->abstract_syntax_tree  = NULL;
                                    assembler_statement->label                 = assembly_output_data_label;
                                    assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                    assembler_statement->data_section_contents = NULL;
                                    assembler_statement->next                  = NULL;
                                  }
                                  if (assembler_program != NULL)
                                  {
                                    temp_assembler_element = assembler_program;
                                    while (temp_assembler_element->next != NULL)
                                    {
                                      temp_assembler_element = temp_assembler_element->next;
                                    }
                                    temp_assembler_element->next = assembler_statement;
                                  }
                                  else
                                  {
                                    assembler_program = assembler_statement;
                                  }
                                }
                              }
                            }
                          }
                          temp_variables_used_stack = pop_expression_stack (temp_variables_used_stack);
                        }
                        state = 20;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                } 
              }
            }
          break;
          default:
          break;
        } 
      }
      else
      {
        state = 99999;
      }
      if (state != 99999)
      {
        ast_element = ast_element->sibling;
      }
    }
  }
  return assembler_program;
}




asmblr_node * create_assembler_output_set_statement_boolean_expression (asmblr_node *assembler_program, ast_node *abstract_syntax_tree, symtab_node *symbol_table, stackframe_node *stackframe_cross_reference_table)
{
  asmblr_node *assembler_statement, *temp_assembler_element;
  ast_node *ast_element;
  symtab_node *symbol_table_element, *temporary_storage_variable, *operand1_symbol_table_entry, *operand2_symbol_table_entry;
  expression_stack_node *expression_stack, *temp_variables_used_stack;
  stackframe_node *stackframe_element, *stackframe_element_operand1, *stackframe_element_operand2, *stackframe_element_target_variable;
  unsigned long long int scope_level, assembly_output_data_label, temp_jump_label1, temp_jump_label2, counter_for_new_variables;
  chaga_attribute_type attribute_type;
  chaga_attribute_datatype datatype, desired_datatype;
  int state, token_type;
  unsigned char *operand1, *operand2, *code_section_assembly_language_output_buffer, *data_section_assembly_language_output_buffer, new_variable[1024];
  size_t i, operand1_string_length, operand2_string_length, token_string_length, code_section_assembly_language_output_buffer_max_length, data_section_assembly_language_output_buffer_length;
  char *token, *expression_stack_token;

  expression_stack = NULL;
  temp_variables_used_stack = NULL;
  if (abstract_syntax_tree != NULL)
  {
    state = 0;
    expression_stack = NULL;
    ast_element = abstract_syntax_tree;
    while ((ast_element != NULL) && (state != 99999))
    {
      token = ast_element->token;
      token_type = ast_element->token_type;
      if (token != NULL)
      {
        //printf ("\nIn create_assembler_output_set_statement_boolean_expression: state = %d, ast_element->token = %s,\n", state, token);
        //printf ("EXPRESSION STACK FRAME:");
        //display_expression_stack (expression_stack);
        //putchar ('\n');
        switch (state)
        {
          case 0:
            if (token_type == TOKEN_IDENTIFIER)
            {
              symbol_table_element = ast_element->symbol_table_entry;
              if (symbol_table_element != NULL)
              {
                stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                if (stackframe_element != NULL)
                {
                  scope_level      = symbol_table_element->scope_level;
                  attribute_type   = symbol_table_element->attribute_type;
                  datatype         = symbol_table_element->datatype;              
                  expression_stack = push_expression_stack (expression_stack, token, token_type, NULL, stackframe_element);
                  symbol_table_set_status_to_available_unused_temporary_variables_for_numerical_expression_processing (symbol_table, scope_level);
                  assembly_output_data_label = retrieve_highest_label_number_from_assembly_output (assembler_program);
                  state = 20;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          break;
          case 20:
            if (token_type == TOKEN_IDENTIFIER)
            {
              symbol_table_element = ast_element->symbol_table_entry;
              if (symbol_table_element != NULL)
              {
                stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                if (stackframe_element != NULL)
                {
                  expression_stack = push_expression_stack (expression_stack, token, token_type, NULL, stackframe_element);
                  state = 20;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT)
              {
                symbol_table_element = ast_element->symbol_table_entry;
                if (symbol_table_element != NULL)
                {
                  if (symbol_table_element->identifier != NULL)
                  {
                    token_string_length = strlen(token);
                    data_section_assembly_language_output_buffer_length = token_string_length + 31;
                    data_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char)*data_section_assembly_language_output_buffer_length); 
                    if (data_section_assembly_language_output_buffer != NULL)
                    {
                      data_section_assembly_language_output_buffer[0]  = ' ';
                      data_section_assembly_language_output_buffer[1]  = ' ';
                      data_section_assembly_language_output_buffer[2]  = ' ';
                      data_section_assembly_language_output_buffer[3]  = ' ';
                      data_section_assembly_language_output_buffer[4]  = ' ';
                      data_section_assembly_language_output_buffer[5]  = '.';
                      data_section_assembly_language_output_buffer[6]  = 's';
                      data_section_assembly_language_output_buffer[7]  = 't';
                      data_section_assembly_language_output_buffer[8]  = 'r';
                      data_section_assembly_language_output_buffer[9]  = 'i';
                      data_section_assembly_language_output_buffer[10] = 'n';
                      data_section_assembly_language_output_buffer[11] = 'g';
                      data_section_assembly_language_output_buffer[12] = ' ';
                      data_section_assembly_language_output_buffer[13] = '"';
                      for (i = 0; i < token_string_length; i++)
                      {
                        data_section_assembly_language_output_buffer[14+i] = token[i];
                      }
                      data_section_assembly_language_output_buffer[14+token_string_length] = '"';
                      data_section_assembly_language_output_buffer[15+token_string_length] = '\n';
                      data_section_assembly_language_output_buffer[16+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[17+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[18+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[19+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[20+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[21+token_string_length] = '.';
                      data_section_assembly_language_output_buffer[22+token_string_length] = 'a';
                      data_section_assembly_language_output_buffer[23+token_string_length] = 'l';
                      data_section_assembly_language_output_buffer[24+token_string_length] = 'i';
                      data_section_assembly_language_output_buffer[25+token_string_length] = 'g';
                      data_section_assembly_language_output_buffer[26+token_string_length] = 'n';
                      data_section_assembly_language_output_buffer[27+token_string_length] = ' ';
                      data_section_assembly_language_output_buffer[28+token_string_length] = '8';
                      data_section_assembly_language_output_buffer[29+token_string_length] = '\n';
                      data_section_assembly_language_output_buffer[30+token_string_length] = '\0';
                    }
                    stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                    if (stackframe_element != NULL)
                    {
                      code_section_assembly_language_output_buffer_max_length = 4096;
                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                      if (code_section_assembly_language_output_buffer != NULL)
                      {
                        assembly_output_data_label++; // increment to next unused label
                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     lea rdx, .M%lld[rip]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_set_value@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element->stackframe_offset, assembly_output_data_label, stackframe_element->stackframe_offset);
                      }
                      if ((data_section_assembly_language_output_buffer != NULL) && (code_section_assembly_language_output_buffer != NULL))
                      {
                        //printf ("L%lld:\n", assembly_output_data_label);
                        //printf ("%s\n", data_section_assembly_language_output_buffer);
                        //printf ("%s\n", code_section_assembly_language_output_buffer);
                        assembler_statement  = malloc(sizeof(asmblr_node));
                        if (assembler_statement != NULL)
                        {
                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                          assembler_statement->abstract_syntax_tree  = NULL;
                          assembler_statement->label                 = assembly_output_data_label;
                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                          assembler_statement->data_section_contents = data_section_assembly_language_output_buffer;
                          assembler_statement->next                  = NULL;
                        }
                        if (assembler_program != NULL)
                        {
                          temp_assembler_element = assembler_program;
                          while (temp_assembler_element->next != NULL)
                          {
                            temp_assembler_element = temp_assembler_element->next;
                          }
                          temp_assembler_element->next = assembler_statement;
                        }
                        else
                        {
                          assembler_program = assembler_statement;
                        }
                      }
                      expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, symbol_table_element->identifier, stackframe_element);
                      temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, symbol_table_element->identifier, NULL);
                      state = 20;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                if ((token_type == TOKEN_TRUE) || (token_type == TOKEN_FALSE))
                {
                  symbol_table_element = ast_element->symbol_table_entry;
                  if (symbol_table_element != NULL)
                  {
                    stackframe_element = retrieve_stackframe_offset (stackframe_cross_reference_table, symbol_table_element);
                    if (stackframe_element != NULL)
                    {
                      code_section_assembly_language_output_buffer_max_length = 4096;
                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                      if (code_section_assembly_language_output_buffer != NULL)
                      {
                        if (token_type == TOKEN_TRUE)
                        {
                          snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov BYTE PTR -%ld[rbp], 1\n", stackframe_element->stackframe_offset);
                        }
                        else
                        {
                          if (token_type == TOKEN_FALSE)
                          {
                            snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov BYTE PTR -%ld[rbp], 0\n", stackframe_element->stackframe_offset);
                          }
                        }
                      }
                      if (code_section_assembly_language_output_buffer != NULL)
                      {
                        //printf ("%s\n", code_section_assembly_language_output_buffer);
                        assembler_statement  = malloc(sizeof(asmblr_node));
                        if (assembler_statement != NULL)
                        {
                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program.
                          assembler_statement->abstract_syntax_tree  = NULL;
                          assembler_statement->label                 = 0;  // No label used.
                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                          assembler_statement->data_section_contents = NULL;
                          assembler_statement->next                  = NULL;
                        }
                        if (assembler_program != NULL)
                        {
                          temp_assembler_element = assembler_program;
                          while (temp_assembler_element->next != NULL)
                          {
                            temp_assembler_element = temp_assembler_element->next;
                          }
                          temp_assembler_element->next = assembler_statement;
                        }
                        else
                        {
                          assembler_program = assembler_statement;
                        }
                      }
                      expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, symbol_table_element->identifier, stackframe_element);
                      temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, symbol_table_element->identifier, NULL);
                      state = 20;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  if ((token_type == TOKEN_PLUS)     || 
                      (token_type == TOKEN_MINUS)    || 
                      (token_type == TOKEN_ASTERISK) || 
                      (token_type == TOKEN_DIVIDE)   || 
                      (token_type == TOKEN_CARET)    || 
                      (token_type == TOKEN_MODULO))
                  {
                    operand1 = NULL;
                    operand2 = NULL;
                    stackframe_element_operand1 = NULL;
                    stackframe_element_operand2 = NULL;
                    if (expression_stack != NULL)
                    {
                      if (expression_stack->token != NULL)
                      {
                        expression_stack_token = expression_stack->token;
                        if (expression_stack_token != NULL)
                        {
                          stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                          operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                          if (operand2 != NULL)
                          {
                            strncpy (operand2, expression_stack_token, operand2_string_length);
                          }
                        }
                      }
                      else
                      {
                        if (expression_stack->temporary_variable_identifier != NULL)
                        {
                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                          operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                          if (operand2 != NULL)
                          {
                            strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    if (expression_stack != NULL)
                    {
                      if (expression_stack->token != NULL)
                      {
                        expression_stack_token = expression_stack->token;
                        if (expression_stack_token != NULL)
                        {
                          stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                          operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                          if (operand1 != NULL)
                          {
                            strncpy (operand1, expression_stack_token, operand1_string_length);
                          }
                        }
                      }
                      else
                      {
                        if (expression_stack->temporary_variable_identifier != NULL)
                        {
                          stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                          operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                          if (operand1 != NULL)
                          {
                            strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                    {
                      operand1_symbol_table_entry = stackframe_element_operand1->symbol_table_entry;
                      operand2_symbol_table_entry = stackframe_element_operand1->symbol_table_entry;
                      desired_datatype = _void;
                      if ((operand1_symbol_table_entry != NULL) && (operand2_symbol_table_entry != NULL))
                      {
                        if ((operand1_symbol_table_entry->attribute_type == _datatype) && (operand2_symbol_table_entry->attribute_type == _datatype))
                        {
                          if (operand1_symbol_table_entry->datatype == operand2_symbol_table_entry->datatype)
                          {
                            desired_datatype = operand1_symbol_table_entry->datatype;
                          }
                        }
                      }
                      temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, _datatype, desired_datatype, scope_level);
                      if (temporary_storage_variable != NULL)
                      {
                        if (temporary_storage_variable->identifier != NULL)
                        {

                          temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                          temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                          if (token_type == TOKEN_PLUS)
                          {
                            if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                            {
                              code_section_assembly_language_output_buffer_max_length = 4096;
                              code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                              if (code_section_assembly_language_output_buffer != NULL)
                              {
                                stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                if (stackframe_element_target_variable != NULL)
                                {
                                  snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_add@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                  assembler_statement  = malloc(sizeof(asmblr_node));
                                  if (assembler_statement != NULL)
                                  {
                                    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                    assembler_statement->abstract_syntax_tree  = NULL;
                                    assembler_statement->label                 = assembly_output_data_label;
                                    assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                    assembler_statement->data_section_contents = NULL;
                                    assembler_statement->next                  = NULL;
                                  }
                                  if (assembler_program != NULL)
                                  {
                                    temp_assembler_element = assembler_program;
                                    while (temp_assembler_element->next != NULL)
                                    {
                                      temp_assembler_element = temp_assembler_element->next;
                                    }
                                    temp_assembler_element->next = assembler_statement;
                                  }
                                  else
                                  {
                                    assembler_program = assembler_statement;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                            }
                            else
                            {
                              state = 99999;
                            }
                          }
                          else
                          {
                            if (token_type == TOKEN_MINUS)
                            {
                              if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                              {
                                code_section_assembly_language_output_buffer_max_length = 4096;
                                code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                if (code_section_assembly_language_output_buffer != NULL)
                                {
                                  stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                  if (stackframe_element_target_variable != NULL)
                                  {
                                    snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_subtract@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                    assembler_statement  = malloc(sizeof(asmblr_node));
                                    if (assembler_statement != NULL)
                                    {
                                      assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                      assembler_statement->abstract_syntax_tree  = NULL;
                                      assembler_statement->label                 = assembly_output_data_label;
                                      assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                      assembler_statement->data_section_contents = NULL;
                                      assembler_statement->next                  = NULL;
                                    }
                                    if (assembler_program != NULL)
                                    {
                                      temp_assembler_element = assembler_program;
                                      while (temp_assembler_element->next != NULL)
                                      {
                                        temp_assembler_element = temp_assembler_element->next;
                                      }
                                      temp_assembler_element->next = assembler_statement;
                                    }
                                    else
                                    {
                                      assembler_program = assembler_statement;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                            else
                            {
                              if (token_type == TOKEN_ASTERISK)
                              {
                                if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                {
                                  code_section_assembly_language_output_buffer_max_length = 4096;
                                  code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                  if (code_section_assembly_language_output_buffer != NULL)
                                  {
                                    stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                    if (stackframe_element_target_variable != NULL)
                                    {
                                      snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_multiply@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                      assembler_statement = malloc(sizeof(asmblr_node));
                                      if (assembler_statement != NULL)
                                      {
                                        assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                        assembler_statement->abstract_syntax_tree  = NULL;
                                        assembler_statement->label                 = assembly_output_data_label;
                                        assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                        assembler_statement->data_section_contents = NULL;
                                        assembler_statement->next                  = NULL;
                                      }
                                      if (assembler_program != NULL)
                                      {
                                        temp_assembler_element = assembler_program;
                                        while (temp_assembler_element->next != NULL)
                                        {
                                          temp_assembler_element = temp_assembler_element->next;
                                        }
                                        temp_assembler_element->next = assembler_statement;
                                      }
                                      else
                                      {
                                        assembler_program = assembler_statement;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                              else
                              {
                                if (token_type == TOKEN_DIVIDE)
                                {
                                  if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                  {
                                    code_section_assembly_language_output_buffer_max_length = 4096;
                                    code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                    if (code_section_assembly_language_output_buffer != NULL)
                                    {
                                      stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                      if (stackframe_element_target_variable != NULL)
                                      {
                                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_divide@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                        assembler_statement = malloc(sizeof(asmblr_node));
                                        if (assembler_statement != NULL)
                                        {
                                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                          assembler_statement->abstract_syntax_tree  = NULL;
                                          assembler_statement->label                 = assembly_output_data_label;
                                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                          assembler_statement->data_section_contents = NULL;
                                          assembler_statement->next                  = NULL;
                                        }
                                        if (assembler_program != NULL)
                                        {
                                          temp_assembler_element = assembler_program;
                                          while (temp_assembler_element->next != NULL)
                                          {
                                            temp_assembler_element = temp_assembler_element->next;
                                          }
                                          temp_assembler_element->next = assembler_statement;
                                        }
                                        else
                                        {
                                          assembler_program = assembler_statement;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                                else
                                {
                                  if (token_type == TOKEN_CARET)
                                  {
                                    //printf ("%s = stringint_power (%s, %s);\n", temporary_storage_variable->identifier, operand1, operand2);
                                  }
                                  else
                                  {
                                    if (token_type == TOKEN_MODULO)
                                    {
                                      if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                      {
                                        code_section_assembly_language_output_buffer_max_length = 4096;
                                        code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                        if (code_section_assembly_language_output_buffer != NULL)
                                        {
                                          stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                          if (stackframe_element_target_variable != NULL)
                                          {
                                            snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rcx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rcx\n     mov rdi, rax\n     call packed_string_integer_modulo@PLT\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset, stackframe_element_target_variable->stackframe_offset);
                                            assembler_statement = malloc(sizeof(asmblr_node));
                                            if (assembler_statement != NULL)
                                            {
                                              assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                              assembler_statement->abstract_syntax_tree  = NULL;
                                              assembler_statement->label                 = assembly_output_data_label;
                                              assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                              assembler_statement->data_section_contents = NULL;
                                              assembler_statement->next                  = NULL;
                                            }
                                            if (assembler_program != NULL)
                                            {
                                              temp_assembler_element = assembler_program;
                                              while (temp_assembler_element->next != NULL)
                                              {
                                                temp_assembler_element = temp_assembler_element->next;
                                              }
                                              temp_assembler_element->next = assembler_statement;
                                            }
                                            else
                                            {
                                              assembler_program = assembler_statement;
                                            }
                                          }
                                          else
                                          {
                                            state = 99999;
                                          }
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                          expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                          state = 20;
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    if (token_type == TOKEN_AND)
                    {
                      operand1 = NULL;
                      operand2 = NULL;
                      stackframe_element_operand1 = NULL;
                      stackframe_element_operand2 = NULL;
                      if (expression_stack != NULL)
                      {
                        if (expression_stack->token != NULL)
                        {
                          expression_stack_token = expression_stack->token;
                          if (expression_stack_token != NULL)
                          {
                            stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                            operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                            operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                            if (operand2 != NULL)
                            {
                              strncpy (operand2, expression_stack_token, operand2_string_length);
                            }
                          }
                        }
                        else
                        {
                          if (expression_stack->temporary_variable_identifier != NULL)
                          {
                            stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                            operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                            operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                            if (operand2 != NULL)
                            {
                              strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                            }
                          }
                        }
                        expression_stack = pop_expression_stack (expression_stack);
                      }
                      if (expression_stack != NULL)
                      {
                        if (expression_stack->token != NULL)
                        {
                          expression_stack_token = expression_stack->token;
                          if (expression_stack_token != NULL)
                          {
                            stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                            operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                            operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                            if (operand1 != NULL)
                            {
                              strncpy (operand1, expression_stack_token, operand1_string_length);
                            }
                          }
                        }
                        else
                        {
                          if (expression_stack->temporary_variable_identifier != NULL)
                          {
                            stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                            operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                            operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                            if (operand1 != NULL)
                            {
                              strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                            }
                          }
                        }
                        expression_stack = pop_expression_stack (expression_stack);
                      }
                      if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                      {
                        temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                        if (temporary_storage_variable != NULL)
                        {
                          if (temporary_storage_variable->identifier != NULL)
                          {
                            temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                            temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                            if (token_type == TOKEN_AND)
                            {
                              if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                              {
                                code_section_assembly_language_output_buffer_max_length = 4096;
                                code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                if (code_section_assembly_language_output_buffer != NULL)
                                {
                                  stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                  if (stackframe_element_target_variable != NULL)
                                  {
                                    assembly_output_data_label++; // increment to next unused label
                                    temp_jump_label1 = assembly_output_data_label;
                                    assembly_output_data_label++; // increment to next unused label
                                    temp_jump_label2 = assembly_output_data_label;
                                    snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     cmp BYTE PTR -%ld[rbp], 0\n     je .M%llu\n     cmp BYTE PTR -%ld[rbp], 0\n     je .M%llu\n     mov eax, 1\n     jmp .M%llu\n.M%llu:\n     mov eax, 0\n.M%llu:\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand1->stackframe_offset, temp_jump_label1, stackframe_element_operand2->stackframe_offset, temp_jump_label1, temp_jump_label2, temp_jump_label1, temp_jump_label2, stackframe_element_target_variable->stackframe_offset); 
                                    //printf ("%s\n", code_section_assembly_language_output_buffer);
                                    assembler_statement  = malloc(sizeof(asmblr_node));
                                    if (assembler_statement != NULL)
                                    {
                                      assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                      assembler_statement->abstract_syntax_tree  = NULL;
                                      assembler_statement->label                 = assembly_output_data_label;
                                      assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                      assembler_statement->data_section_contents = NULL;
                                      assembler_statement->next                  = NULL;
                                    }
                                    if (assembler_program != NULL)
                                    {
                                      temp_assembler_element = assembler_program;
                                      while (temp_assembler_element->next != NULL)
                                      {
                                        temp_assembler_element = temp_assembler_element->next;
                                      }
                                      temp_assembler_element->next = assembler_statement;
                                    }
                                    else
                                    {
                                      assembler_program = assembler_statement;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                            expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                            state = 20;
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      if (token_type == TOKEN_OR)
                      {
                        operand1 = NULL;
                        operand2 = NULL;
                        stackframe_element_operand1 = NULL;
                        stackframe_element_operand2 = NULL;
                        if (expression_stack != NULL)
                        {
                          if (expression_stack->token != NULL)
                          {
                            expression_stack_token = expression_stack->token;
                            if (expression_stack_token != NULL)
                            {
                              stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                              operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                              operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                              if (operand2 != NULL)
                              {
                                strncpy (operand2, expression_stack_token, operand2_string_length);
                              }
                            }
                          }
                          else
                          {
                            if (expression_stack->temporary_variable_identifier != NULL)
                            {
                              stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                              operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                              operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                              if (operand2 != NULL)
                              {
                                strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                              }
                            }
                          }
                          expression_stack = pop_expression_stack (expression_stack);
                        }
                        if (expression_stack != NULL)
                        {
                          if (expression_stack->token != NULL)
                          {
                            expression_stack_token = expression_stack->token;
                            if (expression_stack_token != NULL)
                            {
                              stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                              operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                              operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                              if (operand1 != NULL)
                              {
                                strncpy (operand1, expression_stack_token, operand1_string_length);
                              }
                            }
                          }
                          else
                          {
                            if (expression_stack->temporary_variable_identifier != NULL)
                            {
                              stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                              operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                              operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                              if (operand1 != NULL)
                              {
                                strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                              }
                            }
                          }
                          expression_stack = pop_expression_stack (expression_stack);
                        }
                        if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                        {
                          temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                          if (temporary_storage_variable != NULL)
                          {
                            if (temporary_storage_variable->identifier != NULL)
                            {
                              temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                              temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                              if (token_type == TOKEN_OR)
                              {
                                if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                {
                                  code_section_assembly_language_output_buffer_max_length = 4096;
                                  code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                  if (code_section_assembly_language_output_buffer != NULL)
                                  {
                                    stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                    if (stackframe_element_target_variable != NULL)
                                    {
                                      assembly_output_data_label++; // increment to next unused label
                                      temp_jump_label1 = assembly_output_data_label;
                                      assembly_output_data_label++; // increment to next unused label
                                      temp_jump_label2 = assembly_output_data_label;
                                      snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     cmp BYTE PTR -%ld[rbp], 1\n     je .M%llu\n     cmp BYTE PTR -%ld[rbp], 1\n     je .M%llu\n     mov eax, 0\n     jmp .M%llu\n.M%llu:\n     mov eax, 1\n.M%llu:\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand1->stackframe_offset, temp_jump_label1, stackframe_element_operand2->stackframe_offset, temp_jump_label1, temp_jump_label2, temp_jump_label1, temp_jump_label2, stackframe_element_target_variable->stackframe_offset); 
                                      //printf ("%s\n", code_section_assembly_language_output_buffer);
                                      assembler_statement  = malloc(sizeof(asmblr_node));
                                      if (assembler_statement != NULL)
                                      {
                                        assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                        assembler_statement->abstract_syntax_tree  = NULL;
                                        assembler_statement->label                 = assembly_output_data_label;
                                        assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                        assembler_statement->data_section_contents = NULL;
                                        assembler_statement->next                  = NULL;
                                      }
                                      if (assembler_program != NULL)
                                      {
                                        temp_assembler_element = assembler_program;
                                        while (temp_assembler_element->next != NULL)
                                        {
                                          temp_assembler_element = temp_assembler_element->next;
                                        }
                                        temp_assembler_element->next = assembler_statement;
                                      }
                                      else
                                      {
                                        assembler_program = assembler_statement;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                              expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                              state = 20;
                            }
                            else
                            {
                              state = 99999;
                            }
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        if (token_type == TOKEN_UNARY_NOT)
                        {
                          operand1 = NULL;
                          operand2 = NULL;
                          stackframe_element_operand1 = NULL;
                          stackframe_element_operand2 = NULL;
                          if (expression_stack != NULL)
                          {
                            if (expression_stack->token != NULL)
                            {
                              expression_stack_token = expression_stack->token;
                              if (expression_stack_token != NULL)
                              {
                                stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                if (operand1 != NULL)
                                {
                                  strncpy (operand1, expression_stack_token, operand1_string_length);
                                }
                              }
                            }
                            else
                            {
                              if (expression_stack->temporary_variable_identifier != NULL)
                              {
                                stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                if (operand1 != NULL)
                                {
                                  strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                }
                              }
                            }
                            expression_stack = pop_expression_stack (expression_stack);
                          }
                          if ((operand1 != NULL) && (stackframe_element_operand1 != NULL))
                          {
                            temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                            if (temporary_storage_variable != NULL)
                            {
                              if (temporary_storage_variable->identifier != NULL)
                              {
                                temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                if (stackframe_element_operand1 != NULL) 
                                {
                                  code_section_assembly_language_output_buffer_max_length = 4096;
                                  code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                  if (code_section_assembly_language_output_buffer != NULL)
                                  {
                                    stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                    if (stackframe_element_target_variable != NULL)
                                    {
                                      assembly_output_data_label++; // increment to next unused label
                                      temp_jump_label1 = assembly_output_data_label;
                                      assembly_output_data_label++; // increment to next unused label
                                      temp_jump_label2 = assembly_output_data_label;
                                      snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     cmp BYTE PTR -%ld[rbp], 0\n     je .M%llu\n     mov eax, 0\n     jmp .M%llu\n.M%llu:\n     mov eax, 1\n.M%llu:\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand1->stackframe_offset, temp_jump_label1, temp_jump_label2, temp_jump_label1, temp_jump_label2, stackframe_element_target_variable->stackframe_offset); 
                                      //printf ("%s\n", code_section_assembly_language_output_buffer);
                                      assembler_statement  = malloc(sizeof(asmblr_node));
                                      if (assembler_statement != NULL)
                                      {
                                        assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                        assembler_statement->abstract_syntax_tree  = NULL;
                                        assembler_statement->label                 = assembly_output_data_label;
                                        assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                        assembler_statement->data_section_contents = NULL;
                                        assembler_statement->next                  = NULL;
                                      }
                                      if (assembler_program != NULL)
                                      {
                                        temp_assembler_element = assembler_program;
                                        while (temp_assembler_element->next != NULL)
                                        {
                                          temp_assembler_element = temp_assembler_element->next;
                                        }
                                        temp_assembler_element->next = assembler_statement;
                                      }
                                      else
                                      {
                                        assembler_program = assembler_statement;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                                expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                state = 20;
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                            else
                            {
                              state = 99999;
                            }
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          if (token_type == TOKEN_EQUAL)
                          {
                            operand1 = NULL;
                            operand2 = NULL;
                            stackframe_element_operand1 = NULL;
                            stackframe_element_operand2 = NULL;
                            if (expression_stack != NULL)
                            {
                              if (expression_stack->token != NULL)
                              {
                                expression_stack_token = expression_stack->token;
                                if (expression_stack_token != NULL)
                                {
                                  stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                                  operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                  operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                  if (operand2 != NULL)
                                  {
                                    strncpy (operand2, expression_stack_token, operand2_string_length);
                                  }
                                }
                              }
                              else
                              {
                                if (expression_stack->temporary_variable_identifier != NULL)
                                {
                                  stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                  operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                  operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                  if (operand2 != NULL)
                                  {
                                    strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                  }
                                }
                              }
                              expression_stack = pop_expression_stack (expression_stack);
                            }
                            if (expression_stack != NULL)
                            {
                              if (expression_stack->token != NULL)
                              {
                                expression_stack_token = expression_stack->token;
                                if (expression_stack_token != NULL)
                                {
                                  stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                  operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                  operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                  if (operand1 != NULL)
                                  {
                                    strncpy (operand1, expression_stack_token, operand1_string_length);
                                  }
                                }
                              }
                              else
                              {
                                if (expression_stack->temporary_variable_identifier != NULL)
                                {
                                  stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                  operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                  operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                  if (operand1 != NULL)
                                  {
                                    strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                  }
                                }
                              }
                              expression_stack = pop_expression_stack (expression_stack);
                            }
                            if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                            {
                              temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                              if (temporary_storage_variable != NULL)
                              {
                                if (temporary_storage_variable->identifier != NULL)
                                {
                                  temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                  temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                  if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                  {
                                    code_section_assembly_language_output_buffer_max_length = 4096;
                                    code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                    if (code_section_assembly_language_output_buffer != NULL)
                                    {
                                      stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                      if (stackframe_element_target_variable != NULL)
                                      {
                                        snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_equal@PLT\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset); 
                                        //printf ("%s\n", code_section_assembly_language_output_buffer);
                                        assembler_statement  = malloc(sizeof(asmblr_node));
                                        if (assembler_statement != NULL)
                                        {
                                          assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                          assembler_statement->abstract_syntax_tree  = NULL;
                                          assembler_statement->label                 = assembly_output_data_label;
                                          assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                          assembler_statement->data_section_contents = NULL;
                                          assembler_statement->next                  = NULL;
                                        }
                                        if (assembler_program != NULL)
                                        {
                                          temp_assembler_element = assembler_program;
                                          while (temp_assembler_element->next != NULL)
                                          {
                                            temp_assembler_element = temp_assembler_element->next;
                                          }
                                          temp_assembler_element->next = assembler_statement;
                                        }
                                        else
                                        {
                                          assembler_program = assembler_statement;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                  expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                  state = 20;
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }
                            else
                            {
                              state = 99999;
                            }
                          }   
                          else
                          {
                            if (token_type == TOKEN_NOT_EQUAL)
                            {
                              operand1 = NULL;
                              operand2 = NULL;
                              stackframe_element_operand1 = NULL;
                              stackframe_element_operand2 = NULL;
                              if (expression_stack != NULL)
                              {
                                if (expression_stack->token != NULL)
                                {
                                  expression_stack_token = expression_stack->token;
                                  if (expression_stack_token != NULL)
                                  {
                                    stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                                    operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                    operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                    if (operand2 != NULL)
                                    {
                                      strncpy (operand2, expression_stack_token, operand2_string_length);
                                    }
                                  }
                                }
                                else
                                {
                                  if (expression_stack->temporary_variable_identifier != NULL)
                                  {
                                    stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                    operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                    operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                    if (operand2 != NULL)
                                    {
                                      strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                    }
                                  }
                                }
                                expression_stack = pop_expression_stack (expression_stack);
                              }
                              if (expression_stack != NULL)
                              {
                                if (expression_stack->token != NULL)
                                {
                                  expression_stack_token = expression_stack->token;
                                  if (expression_stack_token != NULL)
                                  {
                                    stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                    operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                    operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                    if (operand1 != NULL)
                                    {
                                      strncpy (operand1, expression_stack_token, operand1_string_length);
                                    }
                                  }
                                }
                                else
                                {
                                  if (expression_stack->temporary_variable_identifier != NULL)
                                  {
                                    stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                    operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                    operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                    if (operand1 != NULL)
                                    {
                                      strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                    }
                                  }
                                }
                                expression_stack = pop_expression_stack (expression_stack);
                              }
                              if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                              {
                                temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                                if (temporary_storage_variable != NULL)
                                {
                                  if (temporary_storage_variable->identifier != NULL)
                                  {
                                    temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                    temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                    if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                    {
                                      code_section_assembly_language_output_buffer_max_length = 4096;
                                      code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                      if (code_section_assembly_language_output_buffer != NULL)
                                      {
                                        stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                        if (stackframe_element_target_variable != NULL)
                                        {
                                          snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "    mov rdx, QWORD PTR -%ld[rbp]\n    mov rax, QWORD PTR -%ld[rbp]\n    mov rsi, rdx\n    mov rdi, rax\n    call packed_string_integer_not_equal@PLT\n    mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand2->stackframe_offset, stackframe_element_target_variable->stackframe_offset); 
                                          //printf ("%s\n", code_section_assembly_language_output_buffer);
                                          assembler_statement  = malloc(sizeof(asmblr_node));
                                          if (assembler_statement != NULL)
                                          {
                                            assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                            assembler_statement->abstract_syntax_tree  = NULL;
                                            assembler_statement->label                 = assembly_output_data_label;
                                            assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                            assembler_statement->data_section_contents = NULL;
                                            assembler_statement->next                  = NULL;
                                          }
                                          if (assembler_program != NULL)
                                          {
                                            temp_assembler_element = assembler_program;
                                            while (temp_assembler_element->next != NULL)
                                            {
                                              temp_assembler_element = temp_assembler_element->next;
                                            }
                                            temp_assembler_element->next = assembler_statement;
                                          }
                                          else
                                          {
                                            assembler_program = assembler_statement;
                                          }
                                        }
                                        else
                                        {
                                          state = 99999;
                                        }
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                    expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                    state = 20;
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }
                              else
                              {
                                state = 99999;
                              }
                            }   
                            else
                            {
                              if (token_type == TOKEN_GREATER_THAN)
                              {
                                operand1 = NULL;
                                operand2 = NULL;
                                stackframe_element_operand1 = NULL;
                                stackframe_element_operand2 = NULL;
                                if (expression_stack != NULL)
                                {
                                  if (expression_stack->token != NULL)
                                  {
                                    expression_stack_token = expression_stack->token;
                                    if (expression_stack_token != NULL)
                                    {
                                      stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                                      operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                      operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                      if (operand2 != NULL)
                                      {
                                        strncpy (operand2, expression_stack_token, operand2_string_length);
                                      }
                                    }
                                  }
                                  else
                                  {
                                    if (expression_stack->temporary_variable_identifier != NULL)
                                    {
                                      stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                      operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                      operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                      if (operand2 != NULL)
                                      {
                                        strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                      }
                                    }
                                  }
                                  expression_stack = pop_expression_stack (expression_stack);
                                }
                                if (expression_stack != NULL)
                                {
                                  if (expression_stack->token != NULL)
                                  {
                                    expression_stack_token = expression_stack->token;
                                    if (expression_stack_token != NULL)
                                    {
                                      stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                      operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                      operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                      if (operand1 != NULL)
                                      {
                                        strncpy (operand1, expression_stack_token, operand1_string_length);
                                      }
                                    }
                                  }
                                  else
                                  {
                                    if (expression_stack->temporary_variable_identifier != NULL)
                                    {
                                      stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                      operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                      operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                      if (operand1 != NULL)
                                      {
                                        strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                      }
                                    }
                                  }
                                  expression_stack = pop_expression_stack (expression_stack);
                                }
                                if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                {
                                  temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                                  if (temporary_storage_variable != NULL)
                                  {
                                    if (temporary_storage_variable->identifier != NULL)
                                    {
                                      temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                      temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                      if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                      {
                                        code_section_assembly_language_output_buffer_max_length = 4096;
                                        code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                        if (code_section_assembly_language_output_buffer != NULL)
                                        {
                                          stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                          if (stackframe_element_target_variable != NULL)
                                          {
                                            snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_greater_than@PLT\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset); 
                                            //printf ("%s\n", code_section_assembly_language_output_buffer);
                                            assembler_statement  = malloc(sizeof(asmblr_node));
                                            if (assembler_statement != NULL)
                                            {
                                              assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                              assembler_statement->abstract_syntax_tree  = NULL;
                                              assembler_statement->label                 = assembly_output_data_label;
                                              assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                              assembler_statement->data_section_contents = NULL;
                                              assembler_statement->next                  = NULL;
                                            }
                                            if (assembler_program != NULL)
                                            {
                                              temp_assembler_element = assembler_program;
                                              while (temp_assembler_element->next != NULL)
                                              {
                                                temp_assembler_element = temp_assembler_element->next;
                                              }
                                              temp_assembler_element->next = assembler_statement;
                                            }
                                            else
                                            {
                                              assembler_program = assembler_statement;
                                            }
                                          }
                                          else
                                          {
                                            state = 99999;
                                          }
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                      expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                      state = 20;
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                }
                              }   
                              else
                              {
                                if (token_type == TOKEN_GREATER_THAN_OR_EQUAL)
                                {
                                  operand1 = NULL;
                                  operand2 = NULL;
                                  stackframe_element_operand1 = NULL;
                                  stackframe_element_operand2 = NULL;
                                  if (expression_stack != NULL)
                                  {
                                    if (expression_stack->token != NULL)
                                    {
                                      expression_stack_token = expression_stack->token;
                                      if (expression_stack_token != NULL)
                                      {
                                        stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                                        operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                        operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                        if (operand2 != NULL)
                                        {
                                          strncpy (operand2, expression_stack_token, operand2_string_length);
                                        }
                                      }
                                    }
                                    else
                                    {
                                      if (expression_stack->temporary_variable_identifier != NULL)
                                      {
                                        stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                        operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                        operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                        if (operand2 != NULL)
                                        {
                                          strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                        }
                                      }
                                    }
                                    expression_stack = pop_expression_stack (expression_stack);
                                  }
                                  if (expression_stack != NULL)
                                  {
                                    if (expression_stack->token != NULL)
                                    {
                                      expression_stack_token = expression_stack->token;
                                      if (expression_stack_token != NULL)
                                      {
                                        stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                        operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                        operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                        if (operand1 != NULL)
                                        {
                                          strncpy (operand1, expression_stack_token, operand1_string_length);
                                        }
                                      }
                                    }
                                    else
                                    {
                                      if (expression_stack->temporary_variable_identifier != NULL)
                                      {
                                        stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                        operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                        operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                        if (operand1 != NULL)
                                        {
                                          strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                        }
                                      }
                                    }
                                    expression_stack = pop_expression_stack (expression_stack);
                                  }
                                  if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                  {
                                    temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                                    if (temporary_storage_variable != NULL)
                                    {
                                      if (temporary_storage_variable->identifier != NULL)
                                      {
                                        temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                        temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                        if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                        {
                                          code_section_assembly_language_output_buffer_max_length = 4096;
                                          code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                          if (code_section_assembly_language_output_buffer != NULL)
                                          {
                                            stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                            if (stackframe_element_target_variable != NULL)
                                            {
                                              snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_greater_than_or_equal@PLT\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset); 
                                              //printf ("%s\n", code_section_assembly_language_output_buffer);
                                              assembler_statement  = malloc(sizeof(asmblr_node));
                                              if (assembler_statement != NULL)
                                              {
                                                assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                                assembler_statement->abstract_syntax_tree  = NULL;
                                                assembler_statement->label                 = assembly_output_data_label;
                                                assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                                assembler_statement->data_section_contents = NULL;
                                                assembler_statement->next                  = NULL;
                                              }
                                              if (assembler_program != NULL)
                                              {
                                                temp_assembler_element = assembler_program;
                                                while (temp_assembler_element->next != NULL)
                                                {
                                                  temp_assembler_element = temp_assembler_element->next;
                                                }
                                                temp_assembler_element->next = assembler_statement;
                                              }
                                              else
                                              {
                                                assembler_program = assembler_statement;
                                              }
                                            }
                                            else
                                            {
                                              state = 99999;
                                            }
                                          }
                                        }
                                        else
                                        {
                                          state = 99999;
                                        }
                                        expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                        state = 20;
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                  }
                                }   
                                else
                                { 
                                  if (token_type == TOKEN_LESS_THAN)
                                  {
                                    operand1 = NULL;
                                    operand2 = NULL;
                                    stackframe_element_operand1 = NULL;
                                    stackframe_element_operand2 = NULL;
                                    if (expression_stack != NULL)
                                    {
                                      if (expression_stack->token != NULL)
                                      {
                                        expression_stack_token = expression_stack->token;
                                        if (expression_stack_token != NULL)
                                        {
                                          stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                                          operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                          if (operand2 != NULL)
                                          {
                                            strncpy (operand2, expression_stack_token, operand2_string_length);
                                          }
                                        }
                                      }
                                      else
                                      {
                                        if (expression_stack->temporary_variable_identifier != NULL)
                                        {
                                          stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                          operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                          operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                          if (operand2 != NULL)
                                          {
                                            strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                          }
                                        }
                                      }
                                      expression_stack = pop_expression_stack (expression_stack);
                                    }
                                    if (expression_stack != NULL)
                                    {
                                      if (expression_stack->token != NULL)
                                      {
                                        expression_stack_token = expression_stack->token;
                                        if (expression_stack_token != NULL)
                                        {
                                          stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                          operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                          if (operand1 != NULL)
                                          {
                                            strncpy (operand1, expression_stack_token, operand1_string_length);
                                          }
                                        }
                                      }
                                      else
                                      {
                                        if (expression_stack->temporary_variable_identifier != NULL)
                                        {
                                          stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                          operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                          operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                          if (operand1 != NULL)
                                          {
                                            strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                          }
                                        }
                                      }
                                      expression_stack = pop_expression_stack (expression_stack);
                                    }
                                    if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                    {
                                      temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                                      if (temporary_storage_variable != NULL)
                                      {
                                        if (temporary_storage_variable->identifier != NULL)
                                        {
                                          temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                          temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                          if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                          {
                                            code_section_assembly_language_output_buffer_max_length = 4096;
                                            code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                            if (code_section_assembly_language_output_buffer != NULL)
                                            {
                                              stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                              if (stackframe_element_target_variable != NULL)
                                              {
                                                snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_less_than@PLT\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset); 
                                                //printf ("%s\n", code_section_assembly_language_output_buffer);
                                                assembler_statement  = malloc(sizeof(asmblr_node));
                                                if (assembler_statement != NULL)
                                                {
                                                  assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                                  assembler_statement->abstract_syntax_tree  = NULL;
                                                  assembler_statement->label                 = assembly_output_data_label;
                                                  assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                                  assembler_statement->data_section_contents = NULL;
                                                  assembler_statement->next                  = NULL;
                                                }
                                                if (assembler_program != NULL)
                                                {
                                                  temp_assembler_element = assembler_program;
                                                  while (temp_assembler_element->next != NULL)
                                                  {
                                                    temp_assembler_element = temp_assembler_element->next;
                                                  }
                                                  temp_assembler_element->next = assembler_statement;
                                                }
                                                else
                                                {
                                                  assembler_program = assembler_statement;
                                                }
                                              }
                                              else
                                              {
                                                state = 99999;
                                              }
                                            }
                                          }
                                          else
                                          {
                                            state = 99999;
                                          }
                                          expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                          state = 20;
                                        }
                                        else
                                        {
                                          state = 99999;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                    }
                                  }   
                                  else
                                  {
                                    if (token_type == TOKEN_LESS_THAN_OR_EQUAL)
                                    {
                                      operand1 = NULL;
                                      operand2 = NULL;
                                      stackframe_element_operand1 = NULL;
                                      stackframe_element_operand2 = NULL;
                                      if (expression_stack != NULL)
                                      {
                                        if (expression_stack->token != NULL)
                                        {
                                          expression_stack_token = expression_stack->token;
                                          if (expression_stack_token != NULL)
                                          {
                                            stackframe_element_operand2 = expression_stack->stackframe_table_entry;
                                            operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                            operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                            if (operand2 != NULL)
                                            {
                                              strncpy (operand2, expression_stack_token, operand2_string_length);
                                            }
                                          }
                                        }
                                        else
                                        {
                                          if (expression_stack->temporary_variable_identifier != NULL)
                                          {
                                            stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                            operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                            operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                            if (operand2 != NULL)
                                            {
                                              strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                            }
                                          }
                                        }
                                        expression_stack = pop_expression_stack (expression_stack);
                                      }
                                      if (expression_stack != NULL)
                                      {
                                        if (expression_stack->token != NULL)
                                        {
                                          expression_stack_token = expression_stack->token;
                                          if (expression_stack_token != NULL)
                                          {
                                            stackframe_element_operand1 = expression_stack->stackframe_table_entry;
                                            operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                            operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                            if (operand1 != NULL)
                                            {
                                              strncpy (operand1, expression_stack_token, operand1_string_length);
                                            }
                                          }
                                        }
                                        else
                                        {
                                          if (expression_stack->temporary_variable_identifier != NULL)
                                          {
                                            stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                            operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                            operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                            if (operand1 != NULL)
                                            {
                                              strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                            }
                                          }
                                        }
                                        expression_stack = pop_expression_stack (expression_stack);
                                      }
                                      if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                      {
                                        temporary_storage_variable = retrieve_unused_temporary_variable_for_numerical_expression_processing (symbol_table, attribute_type, datatype, scope_level);
                                        if (temporary_storage_variable != NULL)
                                        {
                                          if (temporary_storage_variable->identifier != NULL)
                                          {
                                            temporary_storage_variable->internal_use_only_variable_is_available = FALSE;
                                            temp_variables_used_stack = push_expression_stack (temp_variables_used_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                            if ((stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                            {
                                              code_section_assembly_language_output_buffer_max_length = 4096;
                                              code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                              if (code_section_assembly_language_output_buffer != NULL)
                                              {
                                                stackframe_element_target_variable = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temporary_storage_variable->identifier, scope_level);
                                                if (stackframe_element_target_variable != NULL)
                                                {
                                                  snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rdx, QWORD PTR -%ld[rbp]\n     mov rax, QWORD PTR -%ld[rbp]\n     mov rsi, rdx\n     mov rdi, rax\n     call packed_string_integer_less_than_or_equal@PLT\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset, stackframe_element_target_variable->stackframe_offset); 
                                                  //printf ("%s\n", code_section_assembly_language_output_buffer);
                                                  assembler_statement  = malloc(sizeof(asmblr_node));
                                                  if (assembler_statement != NULL)
                                                  {
                                                    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                                    assembler_statement->abstract_syntax_tree  = NULL;
                                                    assembler_statement->label                 = assembly_output_data_label;
                                                    assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                                    assembler_statement->data_section_contents = NULL;
                                                    assembler_statement->next                  = NULL;
                                                  }
                                                  if (assembler_program != NULL)
                                                  {
                                                    temp_assembler_element = assembler_program;
                                                    while (temp_assembler_element->next != NULL)
                                                    {
                                                      temp_assembler_element = temp_assembler_element->next;
                                                    }
                                                    temp_assembler_element->next = assembler_statement;
                                                  }
                                                  else
                                                  {
                                                    assembler_program = assembler_statement;
                                                  }
                                                }
                                                else
                                                {
                                                  state = 99999;
                                                }
                                              }
                                            }
                                            else
                                            {
                                              state = 99999;
                                            }
                                            expression_stack = push_expression_stack (expression_stack, NULL, TOKEN_UNKNOWN, temporary_storage_variable->identifier, NULL);
                                            state = 20;
                                          }
                                          else
                                          {
                                            state = 99999;
                                          }
                                        }
                                        else
                                        {
                                          state = 99999;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    }   
                                    else
                                    {
                                      if (token_type == TOKEN_ASSIGNMENT)
                                      {
                                        operand1 = NULL;
                                        operand2 = NULL;
                                        stackframe_element_operand1 = NULL;
                                        stackframe_element_operand2 = NULL;
                                        if (expression_stack != NULL)
                                        {
                                          if (expression_stack->token != NULL)
                                          {
                                            expression_stack_token = expression_stack->token;
                                            if (expression_stack_token != NULL)
                                            {
                                              stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack_token, scope_level);
                                              operand2_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                              operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                              if (operand2 != NULL)
                                              {
                                                strncpy (operand2, expression_stack_token, operand2_string_length);
                                              }
                                            }
                                          }
                                          else
                                          {
                                            if (expression_stack->temporary_variable_identifier != NULL)
                                            {
                                              stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                              operand2_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                              operand2 = (unsigned char *) malloc(sizeof(char) * (operand2_string_length));
                                              if (operand2 != NULL)
                                              {
                                                strncpy (operand2, expression_stack->temporary_variable_identifier, operand2_string_length);
                                              }
                                            }
                                          }
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        if (expression_stack != NULL)
                                        {
                                          if (expression_stack->token != NULL)
                                          {
                                            expression_stack_token = expression_stack->token;
                                            if (expression_stack_token != NULL)
                                            {
                                              stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack_token, scope_level);
                                              operand1_string_length = strlen(expression_stack_token) + 1; // allocate one extra byte for NULL byte.
                                              operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                              if (operand1 != NULL)
                                              {
                                                strncpy (operand1, expression_stack_token, operand1_string_length);
                                              }
                                            }
                                          }
                                          else
                                          {
                                            if (expression_stack->temporary_variable_identifier != NULL)
                                            {
                                              stackframe_element_operand2 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, expression_stack->temporary_variable_identifier, scope_level);
                                              operand1_string_length = strlen(expression_stack->temporary_variable_identifier) + 1; // allocate one extra byte for NULL byte.
                                              operand1 = (unsigned char *) malloc(sizeof(char) * (operand1_string_length));
                                              if (operand1 != NULL)
                                              {
                                                strncpy (operand1, expression_stack->temporary_variable_identifier, operand1_string_length);
                                              }
                                            }
                                          }
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        if ((operand1 != NULL) && (operand2 != NULL) && (stackframe_element_operand1 != NULL) && (stackframe_element_operand2 != NULL))
                                        {
                                          code_section_assembly_language_output_buffer_max_length = 4096;
                                          code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                          if (code_section_assembly_language_output_buffer != NULL)
                                          {
                                            snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     movzx eax, BYTE PTR -%ld[rbp]\n     mov BYTE PTR -%ld[rbp], al\n", stackframe_element_operand2->stackframe_offset, stackframe_element_operand1->stackframe_offset);
                                            //printf ("%s\n", code_section_assembly_language_output_buffer);
                                            assembler_statement  = malloc(sizeof(asmblr_node));
                                            if (assembler_statement != NULL)
                                            {
                                              assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                              assembler_statement->abstract_syntax_tree  = NULL;
                                              assembler_statement->label                 = 0;  // The label is not used.
                                              assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                              assembler_statement->data_section_contents = NULL;
                                              assembler_statement->next                  = NULL;
                                            }
                                            if (assembler_program != NULL)
                                            {
                                              temp_assembler_element = assembler_program;
                                              while (temp_assembler_element->next != NULL)
                                              {
                                                temp_assembler_element = temp_assembler_element->next;
                                              }
                                              temp_assembler_element->next = assembler_statement;
                                            }
                                            else
                                            {
                                              assembler_program = assembler_statement;
                                            }
                                            while (expression_stack != NULL) // empty the expression stack since we've evaluated the entire numerical expression.
                                            {
                                              expression_stack = pop_expression_stack (expression_stack);
                                            }
// ***************************************************************************************
// * Now it's time to release memory for all temporary variables used in the evaluation. *
// ***************************************************************************************
                                            while (temp_variables_used_stack != NULL)
                                            {
                                              if (temp_variables_used_stack->temporary_variable_identifier != NULL)
                                              {
                                                stackframe_element_operand1 = retrieve_stackframe_offset_for_input_datatype_identifier_name_and_scope (stackframe_cross_reference_table, temp_variables_used_stack->temporary_variable_identifier, scope_level);
                                                if (stackframe_element_operand1 != NULL)
                                                {
// ********************************************************************************************************************************************
// * Check if the stackframe element is a pointer to a string integer. If it is, we must release the memory pointed at by the string integer. *
// * Other variables, such as Boolean are stored directly on stack frame. Thus, no special release of memory from heap is required.           *
// ********************************************************************************************************************************************
                                                  temporary_storage_variable = stackframe_element_operand1->symbol_table_entry;
                                                  if ((temporary_storage_variable->attribute_type == _datatype) && (temporary_storage_variable->datatype == _int))
                                                  {
                                                    code_section_assembly_language_output_buffer_max_length = 4096;
                                                    code_section_assembly_language_output_buffer = (unsigned char *) malloc(sizeof(char) * code_section_assembly_language_output_buffer_max_length);
                                                    if (code_section_assembly_language_output_buffer != NULL)
                                                    {
                                                      snprintf (code_section_assembly_language_output_buffer, code_section_assembly_language_output_buffer_max_length, "     mov rax, QWORD PTR -%ld[rbp]\n     mov rdi, rax\n     call packed_string_integer_release_memory\n     mov QWORD PTR -%ld[rbp], rax\n", stackframe_element_operand1->stackframe_offset, stackframe_element_operand1->stackframe_offset);
                                                      assembler_statement  = malloc(sizeof(asmblr_node));
                                                      if (assembler_statement != NULL)
                                                      {
                                                        assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
                                                        assembler_statement->abstract_syntax_tree  = NULL;
                                                        assembler_statement->label                 = assembly_output_data_label;
                                                        assembler_statement->code_section_contents = code_section_assembly_language_output_buffer;       
                                                        assembler_statement->data_section_contents = NULL;
                                                        assembler_statement->next                  = NULL;
                                                      }
                                                      if (assembler_program != NULL)
                                                      {
                                                        temp_assembler_element = assembler_program;
                                                        while (temp_assembler_element->next != NULL)
                                                        {
                                                          temp_assembler_element = temp_assembler_element->next;
                                                        }
                                                        temp_assembler_element->next = assembler_statement;
                                                      }
                                                      else
                                                      {
                                                        assembler_program = assembler_statement;
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                              temp_variables_used_stack = pop_expression_stack (temp_variables_used_stack);
                                            }
                                            state = 20;
                                          }
                                          else
                                          {
                                            state = 99999;
                                          }
                                        }
                                        else
                                        {
                                          state = 99999;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                      }
                                    } 
                                  }
                                }
                              }
                            } 
                          } 
                        }
                      }
                    } 
                  }
                } 
              }
            }
          break;
          default:
          break;
        } 
      }
      else
      {
        state = 99999;
      }
      if (state != 99999)
      {
        ast_element = ast_element->sibling;
      }
    }
  }
  return assembler_program;
}




asmblr_node * create_assembler_output_exit_main_function (asmblr_node *assembler_program)
{
  asmblr_node *assembler_statement, *assembler_element, *temp_assembler_element;
  size_t code_section_buffer_size;

  assembler_statement  = malloc(sizeof(asmblr_node));
  if (assembler_statement != NULL)
  {
    assembler_statement->program_section       = 1;  // HARDCODED to indicate this is in main program 
    assembler_statement->abstract_syntax_tree  = NULL;
    assembler_statement->label                 = 0;
    assembler_statement->code_section_contents = NULL;       
    assembler_statement->data_section_contents = NULL;       
    assembler_statement->next                  = NULL;
    code_section_buffer_size = 4096;
    assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * code_section_buffer_size);
    if (assembler_statement->code_section_contents != NULL)
    {
      snprintf (assembler_statement->code_section_contents, code_section_buffer_size, "     leave\n     ret\n");
    }
    if (assembler_program != NULL)
    {
      temp_assembler_element = assembler_program;
      while (temp_assembler_element->next != NULL)
      {
        temp_assembler_element = temp_assembler_element->next;
      }
      temp_assembler_element->next = assembler_statement;
    }
    else
    {
      assembler_program = assembler_statement;
    }
  }
  return assembler_program;
}




asmblr_node * create_assembler_output_for_internal_chaga_input_output_library (asmblr_node *assembler_program)
{
  asmblr_node *assembler_statement, *assembler_element, *temp_assembler_element;
  size_t token_string_length, buffer_size, num_datatype_declarations, i; 
  unsigned char temp_buffer[64];

  assembler_statement = malloc(sizeof(asmblr_node));
  if (assembler_statement != NULL)
  {
    assembler_statement->program_section       = 0;  // indicates this is an internal library used by the Chaga compiler
    assembler_statement->label                 = 0;
    assembler_statement->data_section_contents = NULL;       
    assembler_statement->next                  = NULL;
    buffer_size = 1024;
    assembler_statement->code_section_contents = (unsigned char *) malloc(sizeof(char) * buffer_size);
    if (assembler_statement->code_section_contents != NULL)
    {
      strncpy (assembler_statement->code_section_contents, "        .section .rodata\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .text\n", buffer_size);
      strncat (assembler_statement->code_section_contents, ".IO0:\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .string \"FALSE\"\n", buffer_size);
      strncat (assembler_statement->code_section_contents, ".IO1:\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .string \"TRUE\"\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .text\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .globl bool_display\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .type bool_display, @function\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        bool_display:\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        endbr64\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        push rbp\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov rbp, rsp\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        sub rsp, 16\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov eax, edi\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov BYTE PTR -4[rbp], al\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        movzx eax, BYTE PTR -4[rbp]\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        test eax, eax\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        je .IO2\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        cmp eax, 1\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        je .IO3\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        jmp .IO5\n", buffer_size);
      strncat (assembler_statement->code_section_contents, ".IO2:\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        lea rax, .IO0[rip]\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov rdi, rax\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov eax, 0\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        call printf@PLT\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        jmp .IO5\n", buffer_size);
      strncat (assembler_statement->code_section_contents, ".IO3:\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        lea rax, .IO1[rip]\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov rdi, rax\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        mov eax, 0\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        call printf@PLT\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        nop\n", buffer_size);
      strncat (assembler_statement->code_section_contents, ".IO5:\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        leave\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        ret\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "        .size bool_display, .-bool_display\n", buffer_size);
      strncat (assembler_statement->code_section_contents, "\n\n", buffer_size);
    }
    if (assembler_program != NULL)
    {
      assembler_statement->next = assembler_program;
      assembler_program = assembler_statement;
    }
    else
    {
      assembler_program = assembler_statement;
    }
  }
  return assembler_program;
}




void write_assembler_output_to_file (FILE *fp, asmblr_node *assembler_program)
{
  asmblr_node *assembler_program_element;
  int output_data_section, output_main_program_section;

// *************************************************************
// * Begin assembly output with ALL data section declarations. *
// *************************************************************
  if (assembler_program != NULL)
  {
    fprintf (fp, "     .intel_syntax noprefix\n\n");
  }
// ************************************************************************************************************
// * Next print assembly output for internal Chaga programming language management such as STRINGINT library. *
// ************************************************************************************************************
  assembler_program_element = assembler_program;
  while (assembler_program_element != NULL)  
  {
    if (assembler_program_element->program_section == 0) // internal Chaga programming language library?
    {
      if (assembler_program_element->code_section_contents != NULL)
      {
        fprintf (fp, "%s", assembler_program_element->code_section_contents);
      }
    }
    assembler_program_element = assembler_program_element->next;
  }
// ********************************************************************
// * Next display assembly output for main subroutine's data section. *
// ********************************************************************
  output_data_section = FALSE;
  assembler_program_element = assembler_program;
  while ((assembler_program_element != NULL) && (!output_data_section))
  {
    if (assembler_program_element->program_section == 1) // main program?
    {
      if (assembler_program_element->data_section_contents != NULL)
      {
        output_data_section = TRUE;
      }
    }
    assembler_program_element = assembler_program_element->next;
  }
  if (output_data_section)
  {
    fprintf (fp, "     .section .rodata\n");
    assembler_program_element = assembler_program;
    while (assembler_program_element != NULL)
    {
      if (assembler_program_element->program_section == 1) // main program?
      {
        if (assembler_program_element->data_section_contents != NULL)
        {
          fprintf (fp, ".M%llu:\n%s\n", assembler_program_element->label, assembler_program_element->data_section_contents);
        }
      }
      assembler_program_element = assembler_program_element->next;
    }
  }
// ***********************************************
// * Next, output the main function declaration. *
// ***********************************************
  assembler_program_element = assembler_program;
  while (assembler_program_element != NULL) 
  {
    if (assembler_program_element->program_section == 1) // main program 
    {
      if (assembler_program_element->code_section_contents != NULL)
      {
        fprintf (fp, "%s", assembler_program_element->code_section_contents);
      }
    }  
    assembler_program_element = assembler_program_element->next;
  }
}




void create_executable_output_file_from_x86_assembler_file (char *assembler_input_filename, char *assembler_object_filename, char *executable_filename)
{
  int executable_file_creation_status, object_file_creation_status, delete_files_status;
  char shell_command[65536];

  snprintf (&shell_command[0], sizeof(shell_command), "/usr/bin/as %s -o %s", assembler_input_filename, assembler_object_filename);
  object_file_creation_status = system (&shell_command[0]);
  if (object_file_creation_status != -1)
  {
    snprintf (&shell_command[0], sizeof(shell_command), "/usr/bin/gcc %s -lchaga -o %s", assembler_object_filename, executable_filename);
    executable_file_creation_status = system (&shell_command[0]);
    if (executable_file_creation_status != -1)
    {
// ******************************************************************
// * Now clean up by deleting temporary assembler and object files. *
// ******************************************************************
      snprintf (&shell_command[0], sizeof(shell_command), "/usr/bin/rm %s", assembler_input_filename);
      delete_files_status = system (&shell_command[0]);
      snprintf (&shell_command[0], sizeof(shell_command), "/usr/bin/rm %s", assembler_object_filename);
      delete_files_status = system (&shell_command[0]);
    }
    else
    {
      printf ("/usr/bin/ld failed to create executable file for object file: %s", assembler_object_filename);
    }
  }
  else
  {
    printf ("/usr/bin/as failed to create object file for assembler file: %s", assembler_input_filename);
  }
}




size_t symbol_table_count_number_of_datatype_declarations_for_given_scope_level_excluding_argv_argc_in_main (symtab_node *symbol_table, unsigned long long int scope_level)
{
  symtab_node *symbol_table_element;
  size_t num_datatype_declarations;

  num_datatype_declarations = 0;
  symbol_table_element = symbol_table;
  while (symbol_table_element != NULL)
  {
    if (symbol_table_element->identifier != NULL)
    {
      if (strncmp(symbol_table_element->identifier, "argc", 4) != 0)
      {
        if (strncmp(symbol_table_element->identifier, "argv", 4) != 0)
        {
          if (symbol_table_element->attribute_type == _datatype)
          {
            if (symbol_table_element->scope_level == scope_level)
            {
              num_datatype_declarations++;
            }
          }
        }
      }
      symbol_table_element = symbol_table_element->next;
    }
  }
  return num_datatype_declarations;
}





// *********************************************************************************************************************
// * retrieve_highest_label_number_from_assembly_output                                                                *
// *                                                                                                                   *
// * Assembler output contains labels to reference data such as strings from a printf statement. The label pointing to *
// * each string in the data section MUST be unique. The easiest way to do that is to report the highest number label  *
// * currently used. Then in calling program, increment that value by one to get a new unused label.                   * 
// *********************************************************************************************************************
unsigned long long int retrieve_highest_label_number_from_assembly_output (asmblr_node *assembler_program)
{
  unsigned long long int highest_label_number;
  asmblr_node *assembler_element;

  highest_label_number = 0;
  assembler_element = assembler_program;
  while (assembler_element != NULL)
  {
    if (assembler_element->label > highest_label_number)
    {
      highest_label_number = assembler_element->label;
    }
    assembler_element = assembler_element->next;
  }
  return highest_label_number;
}




// ************************************************************************************************************************************
// * determine_stackframe_storage_size_for_all_locally_defined_variables_in_main                                                      *
// *                                                                                                                                  *
// * This function counts the storage size requirements (in bytes) for all the locally-defined variables (except argc/arc) in main.   *
// * We must perform this task to determine how much storage space on the stack frame is required to store main variables. The amount *
// * of storage space is first computed. Next, I determine how much stack space is required on increments of 16 bytes storage space.  *
// *                                                                                                                                  *
// * If the computed storage space is 24 bytes, I would then return 32 bytes for the stack since the stack must be on 16-byte         *
// * increments. 32 bytes of storage will obviously hold 24 bytes that are required.                                                  *
// ************************************************************************************************************************************
size_t determine_stackframe_storage_size_for_all_locally_defined_variables_in_main (stackframe_node *stackframe_cross_reference_table, symtab_node *symbol_table)
{
  stackframe_node *stackframe_element;
  symtab_node *symbol_table_element;
  size_t total_stackframe_storage_size_required_for_locally_defined_variables, storage_space_for_all_locally_defined_variables_in_bytes;
  unsigned long long int scope_level_for_main;
  int found;

  storage_space_for_all_locally_defined_variables_in_bytes = 0; 
  total_stackframe_storage_size_required_for_locally_defined_variables = 0;
// *********************************************************************************************
// * Retrieve the scope_level for the main function declaration. This is necessary so that we  *
// * can determine what variables are declared under main. We don't know what scope_level main *
// * is associated with.                                                                       *
// *********************************************************************************************
  found = FALSE;
  symbol_table_element = symbol_table;
  while ((symbol_table_element != NULL) && (!found))
  {
    if (symbol_table_element->identifier != NULL)
    {
      if (strncmp(symbol_table_element->identifier, "main", 4) == 0)
      {
        if ((symbol_table_element->attribute_type == _function) || (symbol_table_element->attribute_type == _procedure))
        {
          scope_level_for_main = symbol_table_element->scope_level;
          found = TRUE;
        }
      }
      if (!found)
      {
        symbol_table_element = symbol_table_element->next;
      }
    }
  }
  if (found)
  {
    stackframe_element = stackframe_cross_reference_table;
    while (stackframe_element != NULL)
    {
      symbol_table_element = stackframe_element->symbol_table_entry;
      if (symbol_table_element != NULL)
      {
        if (symbol_table_element->scope_level == scope_level_for_main)
        {
          if (symbol_table_element->attribute_type == _datatype)
          {
            if (symbol_table_element->identifier != NULL)
            {
              if (strncmp(symbol_table_element->identifier, "argc", 4) != 0) // avoid the argc element since it does not require stack frame stoage ever.
              {
                storage_space_for_all_locally_defined_variables_in_bytes = storage_space_for_all_locally_defined_variables_in_bytes + stackframe_element->storage_size_in_bytes;
              }
            }
          }
        }
      }
      stackframe_element = stackframe_element->next;
    }
  }
  if (storage_space_for_all_locally_defined_variables_in_bytes > 0)
  {
    if ((storage_space_for_all_locally_defined_variables_in_bytes % 16) == 0)
    {
      total_stackframe_storage_size_required_for_locally_defined_variables = storage_space_for_all_locally_defined_variables_in_bytes;
    }
    else
    {
      total_stackframe_storage_size_required_for_locally_defined_variables = (storage_space_for_all_locally_defined_variables_in_bytes / 16) * 16 + 16;
    }
  }
// *************************************************************
// * Add an addition protective layer beyond what is required. *
// *************************************************************
  total_stackframe_storage_size_required_for_locally_defined_variables = total_stackframe_storage_size_required_for_locally_defined_variables + 16;
  return total_stackframe_storage_size_required_for_locally_defined_variables;
}




// ********************************************************************************************************************************
// * escape_quotes_inside_text                                                                                                    *
// *                                                                                                                              *
// * This subroutine replaces all double quotes for input text. Failing to escape double quotes will cause the assembler to fail. *
// *                                                                                                                              *
// * EXAMPLES:                                                                                                                    *
// *                                                                                                                              *
// * INPUT:   This is some "quoted text"                                                                                          *
// * OUTPUT:  This is some \"quoted text\"                                                                                        *
// *                                                                                                                              *
// * INPUT:   This is some \"escaped \" quoted text while this "quoted text" is not escaped.                                      *
// * OUTPUT:  This is some \"escaped \" quoted text while this \"quoted text\" is not escaped.                                    *
// ********************************************************************************************************************************
char * escape_double_quotes_inside_text (char *input_text)
{
  char byte, *escaped_text;
  size_t input_text_length, escaped_text_length, i, j;
  int state;

  escaped_text = NULL;
  if (input_text != NULL)
  {
    input_text_length = strlen (input_text); 
    escaped_text_length = 0;
    i = 0;
    state = 0;
    while (i < input_text_length)
    {
      switch (state)
      {
        case 0:
          if (input_text[i] == '\\')
          {
            escaped_text_length++;
            state = 1;
          }
          else
          {
            if (input_text[i] == '"')
            {
              escaped_text_length = escaped_text_length + 2; // each non-escaped quote requiries the following two bytes: \"
            }
            else
            {
              escaped_text_length++;
            }
          }
        break;
        case 1:
          escaped_text_length++;
          state = 0; // skip over this byte because it was escaped by previous byte.
        break; 
      }
      i++;
    }
    if (escaped_text_length > 0)
    {
      escaped_text = (char *) malloc(sizeof(char)*(escaped_text_length + 1)); // add one for NULL terminator.
      if (escaped_text != NULL)
      {
        memset (escaped_text, 0, escaped_text_length + 1); // Clear the buffer and NULL-terminate it.
        i = 0;
        j = 0;
        state = 0;
        while (i < input_text_length)
        {
          switch (state)
          {
            case 0:
              if (input_text[i] == '\\')
              {
                if (j < escaped_text_length)
                {
                  escaped_text[j] = '\\';
                  j++;
                }
                state = 1;
              }
              else
              {
                if (input_text[i] == '"')
                {
                  if (j < escaped_text_length)
                  {
                    escaped_text[j] = '\\';
                    j++;
                  }
                  if (j < escaped_text_length)
                  {
                    escaped_text[j] = '"';
                    j++;
                  }
                }
                else
                {
                  if (j < escaped_text_length)
                  {
                    escaped_text[j] = input_text[i];
                    j++;
                  }
                }
              }
            break;
            case 1:
              if (j < escaped_text_length)
              {
                escaped_text[j] = input_text[i]; // copy over this byte because it was escaped by previous byte.
                j++;
              }
              state = 0;
            break; 
          }
          i++;
        }
      }
    }
  }
  return escaped_text;
}
