/**************************************************************************************
 * 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 <stddef.h>
#include <string.h>
#include "./include/chaga_compiler-constants.h"
#include "./include/chaga_compiler-data_structures.h"
#include "./include/chaga_compiler-abstract_syntax_tree.h"

ast_node * create_abstract_syntax_tree (cst_node *concrete_syntax_tree, symtab_node *symbol_table, expression_stack_node *expression_stack)
{
  token_node    *token_element;
  ast_node      *abstract_syntax_tree, *new_ast_element, *last_ast_element, *temp_ast_element;
  cst_node      *cst_element, *temp_cst_element;
  symtab_node   *symbol_table_element;
  param_node    *parameter_list_element;
  size_t        token_string_length;
  int           state, finished, current_token_type, stack_token_type, match;
  char          *current_token, *stack_token;
  unsigned char set_statement_only_contains_integer_constants_in_numerical_expression;
  unsigned long long int scope_level, num_left_curly_braces, num_right_curly_braces, num_parameters_being_sent_to_procedure, num_parameters_defined_in_procedure;
  unsigned long long int num_left_parenthesis, num_right_parenthesis, num_operands;
  
  state                = 0;
  scope_level          = 0;
  abstract_syntax_tree = NULL;
  last_ast_element     = NULL;
  cst_element = concrete_syntax_tree;
  num_left_curly_braces = 0;
  num_right_curly_braces = 0;
  while ((cst_element != NULL) && (state < 99999))
  {
    current_token = cst_element->token;
    current_token_type = cst_element->token_type;
    if (current_token != NULL)
    {
      //printf ("IN CREATE_ABSTRACT_SYNTAX_TREE. state: %d, token: %s\n", state, current_token);
      switch (state)
      {
        case 0:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            token_string_length = strlen (current_token);
            switch (token_string_length)
            {
              case 6:
                if (strncmp(current_token, "define", 6) == 0)
                {
                  state = 50;
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _define, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      last_ast_element->child = new_ast_element;
                      last_ast_element = last_ast_element->child;
                    }
                    else
                    {
                      abstract_syntax_tree = new_ast_element;
                      last_ast_element = abstract_syntax_tree;
                    }
                  }
                  else
                  {
                    state = 999999;
                  }
                }
                else
                {
                  state = 99999;
                }
              break;
              case 7:
                if (strncmp(current_token, "declare", 7) == 0)
                {
                  state = 100;
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _declare, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      last_ast_element->child = new_ast_element;
                      last_ast_element = last_ast_element->child;
                    }
                    else
                    {
                      abstract_syntax_tree = new_ast_element;
                      last_ast_element = abstract_syntax_tree;
                    }
                  }
                  else
                  {
                    state = 999999;
                  }
                }
                else
                {
                  state = 999999;
                }
              break;
              default:
              break;
            }
          }
          else
          {
            state = 99999;
          }
        break;
        case 50:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            token_string_length = strlen (current_token);
            switch (token_string_length)
            {
              case 8:
                if (strncmp(current_token, "function", 8) == 0)
                {
                  state = 2000;
                }
                else
                {
                  state = 99999;
                }
              break;
              case 9:
                if (strncmp(current_token, "procedure", 9) == 0)
                {
                  state = 3000;
                }
                else
                {
                  state = 99999;
                }
              break;
              default:
                state = 99999;
              break;
            }             
          }
          else
          {
            state = 99999;
          }
        break;
        case 100:
          state = 99999;
        break;
        case 2000:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
              symbol_table_element = retrieve_symbol_table_element_for_function_or_procedure_name (symbol_table, current_token, _function);
              if (symbol_table_element != NULL)
              {
                scope_level = symbol_table_element->scope_level;
                state = 2010;
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _define, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
        case 2010:
          if (current_token_type == TOKEN_LEFT_CURLY_BRACE)
          {
            num_left_curly_braces = 1;
            num_right_curly_braces = 0;
            state = 4000;
            new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
            if (new_ast_element != NULL)
            {
              if (last_ast_element != NULL)
              {
                last_ast_element->child = new_ast_element;
                last_ast_element = last_ast_element->child;
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 2010;
          }           
        break;
// ************************
// * define procedure ... *
// ************************
        case 3000:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
              symbol_table_element = retrieve_symbol_table_element_for_function_or_procedure_name (symbol_table, current_token, _procedure);
              if (symbol_table_element != NULL)
              {
                scope_level = symbol_table_element->scope_level;
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _define, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                    state = 3010;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 3000; // Skip over parameter lists for now since I'm not utilizing them yet. Besides, the variables are in the symbol table.
          }
        break;
        case 3010:
          if (current_token_type == TOKEN_LEFT_CURLY_BRACE)
          {
            num_left_curly_braces = 1;
            num_right_curly_braces = 0;
            state = 4000;
            new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
            if (new_ast_element != NULL)
            {
              if (last_ast_element != NULL)
              { 
                last_ast_element->child = new_ast_element;
                last_ast_element = last_ast_element->child;
              }
              else
              { 
                state = 99999;
              }
            }
            else
            { 
              state = 99999;
            }
          }
          else
          {
            state = 3010; // Skip over the local declarations in the procedure definition since they were already in the symbol table.
          }
        break;
        case 4000:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
              token_string_length = strlen (current_token);
              switch (token_string_length)
              {
                case 2:
                  if (strncmp(current_token, "if", 2) == 0)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->child = new_ast_element;
                        last_ast_element = last_ast_element->child;
// ***********************************************************************************************
// * Preventative measure: Make sure expression stack is empty before evaluating the expression! *
// ***********************************************************************************************
                        while (expression_stack != NULL)
                        {
                          expression_stack = pop_expression_stack (expression_stack);
                        }
                        state = 12000;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                break;
                case 3:
                  if (strncmp(current_token, "set", 3) == 0)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->child = new_ast_element;
                        last_ast_element = last_ast_element->child;
// ***********************************************************************************************
// * Preventative measure: Make sure expression stack is empty before evaluating the expression! *
// ***********************************************************************************************
                        while (expression_stack != NULL)
                        {
                          expression_stack = pop_expression_stack (expression_stack);
                        }
                        state = 11000;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                break;
                case 4:
                  if (strncmp(current_token, "else", 4) == 0)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _else, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->child = new_ast_element;
                        last_ast_element = last_ast_element->child;
                        state = 13000;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    if (strncmp(current_token, "call", 4) == 0)
                    {
                      new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                      if (new_ast_element != NULL)
                      {
                        if (last_ast_element != NULL)
                        {
                          last_ast_element->child = new_ast_element;
                          last_ast_element = last_ast_element->child;
                          state = 15000;
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                break;
                case 5:
                  if (strncmp(current_token, "print", 5) == 0)
                  {
                    state = 5000;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _print, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->child = new_ast_element;
                        last_ast_element = last_ast_element->child;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    if (strncmp(current_token, "while", 5) == 0)
                    {
                      new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                      if (new_ast_element != NULL)
                      {
                        if (last_ast_element != NULL)
                        {
                          last_ast_element->child = new_ast_element;
                          last_ast_element = last_ast_element->child;
// ***********************************************************************************************
// * Preventative measure: Make sure expression stack is empty before evaluating the expression! *
// ***********************************************************************************************
                          while (expression_stack != NULL)
                          {
                            expression_stack = pop_expression_stack (expression_stack);
                          }
                          state = 14000;
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                break;
                case 7:
                  if (strncmp(current_token, "declare", 7) == 0)
                  {
                    state = 10000;
                  }
                  else
                  {
                    state = 99999;
                  }
                break;
                default:
                break;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            if (current_token_type == TOKEN_LEFT_CURLY_BRACE)
            {
              num_left_curly_braces++;
              new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
              if (new_ast_element != NULL)
              {
                if (last_ast_element != NULL)
                {
                  last_ast_element->child = new_ast_element;
                  last_ast_element = last_ast_element->child;
                  state = 4000;
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (current_token_type == TOKEN_RIGHT_CURLY_BRACE)
              {
                num_right_curly_braces++;
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _right_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->child = new_ast_element;
                    last_ast_element = last_ast_element->child;
                    if (num_left_curly_braces == num_right_curly_braces)
                    {
                      state = 0;
                    }
                    else
                    {
                      if (num_left_curly_braces > num_right_curly_braces)
                      {
                        state = 4000;
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              } 
              else
              {
                state = 99999;
              }
            }
          }
        break;
// *************
// * print ... *
// *************
        case 5000:
          if (current_token_type == TOKEN_LEFT_PARENTHESIS)
          {
            state = 5010;
          }
          else
          {
            state = 99999;
          }
        break;
// ***************
// * print ( ... *
// ***************
        case 5010:
          if ((current_token_type == TOKEN_SINGLE_QUOTE) ||
              (current_token_type == TOKEN_DOUBLE_QUOTE))
          {
            state = 5020;
          }
          else
          {
            if (current_token_type == TOKEN_IDENTIFIER)
            {
              if (current_token != NULL)
              {
                symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype , scope_level);
                if (symbol_table_element != NULL)
                {
                  state = 5040;
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _print, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      last_ast_element->sibling = new_ast_element;
                      last_ast_element = last_ast_element->sibling;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
        break;
        case 5020:
          if (current_token_type == TOKEN_STRING)
          {
            state = 5030;
            new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _print, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
            if (new_ast_element != NULL)
            {
              if (last_ast_element != NULL)
              {
                last_ast_element->sibling = new_ast_element;
                last_ast_element = last_ast_element->sibling;
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
        break;
        case 5030:
          if ((current_token_type == TOKEN_SINGLE_QUOTE) ||
              (current_token_type == TOKEN_DOUBLE_QUOTE))
          {
            state = 5040;
          }
          else
          {
            state = 99999;
          }
        break;
        case 5040:
          if (current_token_type == TOKEN_RIGHT_PARENTHESIS)
          {
            state = 5050;
          }
          else
          {
            if (current_token_type == TOKEN_COMMA)
            {
              state = 5060;
            }
            else
            {
              state = 99999;
            }
          }
        break;
        case 5050:
          if (current_token_type == TOKEN_SEMICOLON)
          {
            state = 4000;
          } 
          else
          {
            state = 99999;
          }
        break;
        case 5060:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
              symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype , scope_level);
              if (symbol_table_element != NULL)
              {
                state = 5040;
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _print, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
              else
              {
                token_element = cst_element->token_entry;
                if (token_element != NULL)
                {
                  printf ("Error on line %lld: \"%s\" is not declared as a variable.\n", token_element->line_number, current_token);
                }
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            if ((current_token_type == TOKEN_SINGLE_QUOTE) ||
                (current_token_type == TOKEN_DOUBLE_QUOTE))
            {
              state = 5020;
            }
            else
            {
              state = 99999;
            }
          }
        break;
// ********************************************************************************************************************************************
// * Note: I don't add the DECLARE statement to the Abstract Syntax Tree (AST) because it's effectively a non-operation. Instead, I use the   *
// * symbol table which has already listed the locally-defined variables for a given function or procedure. I will use the symbol table to    *
// * set-up my stack frame for defined variables within a given scope. Here, I merely iterate over the tokens until I reach the semicolon and *
// * terminate the declare statement.                                                                                                         *
// ********************************************************************************************************************************************
        case 10000:
          if (current_token_type == TOKEN_SEMICOLON)
          {
            state = 4000;
          }
        break;
// *******
// * set *
// *******
        case 11000:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
              symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype, scope_level);
              if (symbol_table_element != NULL)
              {
                if (symbol_table_element->attribute_type == _datatype) 
                {
                  if (symbol_table_element->datatype == _int)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->sibling = new_ast_element;
                        last_ast_element = last_ast_element->sibling;
                        state = 11490; // evaluate expressions as mixed numerical and Boolean. At runtime it will automatically convert to INT datatype.
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  else
                  {
                    if (symbol_table_element->datatype == _real)
                    {
                      new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                      if (new_ast_element != NULL)
                      {
                        if (last_ast_element != NULL)
                        {
                          last_ast_element->sibling = new_ast_element;
                          last_ast_element = last_ast_element->sibling;
                          state = 11200; // The float variable could have a .SCALE attribute therefore, I need to check for the presence of the SCALE attribute.
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      if (symbol_table_element->datatype == _bool)
                      {
                        new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                        if (new_ast_element != NULL)
                        {
                          if (last_ast_element != NULL)
                          {
                            last_ast_element->sibling = new_ast_element;
                            last_ast_element = last_ast_element->sibling;
                            state = 11490;
                          }
                          else
                          {
                            state = 99999;
                          }
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                token_element = cst_element->token_entry;
                if (token_element != NULL)
                {
                  printf ("Error on line %lld: \"%s\" is not declared as a variable.\n", token_element->line_number, current_token);
                }
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
// *********************************************************************************************************************************
// * set <IDENTIFIER>                                                                                                              *
// *                                                                                                                               *
// * Note: <IDENTIFIER> is a float datatype.                                                                                       *
// *                                                                                                                               *
// * At this point, it is possible the next token is a period because floats support the ".scale" attribute to indicate the number *
// * of digits to truncate to RIGHT of DECIMAL.                                                                                    *
// *                                                                                                                               *
// * TODO: POTENTIAL BUG I NEED TO FIX: At runtime, the float datatype will evaluate a mixed Boolean and/or numerical expression   *
// *       by converting it to numerical. However, if the SCALE attribute is being referenced instead, I must notify the run-time  *
// *       expression engine to return a non-negative INTEGER datatpe result instead of a float datatype result because SCALE      *
// *       attribute expects a non-negative INTEGER result.                                                                        *
// *********************************************************************************************************************************
        case 11200:
          if (current_token_type == TOKEN_ASSIGNMENT)
          {
            if (current_token != NULL)
            {

              new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
              if (new_ast_element != NULL)
              {
                if (last_ast_element != NULL)
                {
                  last_ast_element->sibling = new_ast_element;
                  last_ast_element = last_ast_element->sibling;
// ***********************************************************************************************
// * Preventative measure: Make sure expression stack is empty before evaluating the expression! *
// ***********************************************************************************************
                  while (expression_stack != NULL)
                  {
                    expression_stack = pop_expression_stack (expression_stack);
                  }
                  state = 11500; // evaluate expressions as mixed numerical and Boolean. At runtime, it will automatically convert to Boolean datatype.
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                state = 99999;
              }
            }
          }
          else
          {
            if (current_token_type == TOKEN_PERIOD)
            {
              state = 11210;
              new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
              if (new_ast_element != NULL)
              {
                if (last_ast_element != NULL)
                { 
                  last_ast_element->sibling = new_ast_element;
                  last_ast_element = last_ast_element->sibling;
                }
                else
                { 
                  state = 99999;
                }
              }
              else
              { 
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
        break;
// ********************************************
// * set <IDENTIFIER> <PERIOD> ...            *
// *                                          *
// * Note: <IDENTIFIER> is a float datatype.  *
// ********************************************
        case 11210:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
              token_string_length = strlen (current_token);
              switch (token_string_length)
              {
                case 5:
                  if (strncmp(current_token, "scale", 5) == 0)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->sibling = new_ast_element;
                        last_ast_element = last_ast_element->sibling;
// ***********************************************************************************************
// * Preventative measure: Make sure expression stack is empty before evaluating the expression! *
// ***********************************************************************************************
                        while (expression_stack != NULL)
                        {
                          expression_stack = pop_expression_stack (expression_stack);
                        }
                        state = 11500; // evaluate expressions as mixed numerical and Boolean. 
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                break;
                default:
                  state = 99999;
                break;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;       
// ****************************
// * set <IDENTIFIER> <EQUAL> * 
// ****************************
        case 11490:
          if (current_token_type == TOKEN_ASSIGNMENT)
          {
            new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
            if (new_ast_element != NULL)
            {
              if (last_ast_element != NULL)
              {
                last_ast_element->sibling = new_ast_element;
                last_ast_element = last_ast_element->sibling;
// ***********************************************************************************************
// * Preventative measure: Make sure expression stack is empty before evaluating the expression! *
// ***********************************************************************************************
                while (expression_stack != NULL)
                {
                  expression_stack = pop_expression_stack (expression_stack);
                }
                state = 11500; // evaluate expressions as mixed numerical and Boolean. 
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
// *******************************************************************************************************************************************
// * set <IDENTIFIER>                                                                                                                        *
// *                                                                                                                                         *
// * This version of the set command is for evaluating mixed Boolean and numerical expressions that ultimately evaluate to a Boolean result. *
// *******************************************************************************************************************************************
        case 11500:
          if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT) ||
              (current_token_type == TOKEN_IDENTIFIER)                  || (current_token_type == TOKEN_TRUE)                               || 
              (current_token_type == TOKEN_FALSE))
          {
            if (current_token != NULL)
            {
              state = 11500;
              symbol_table_element = NULL;
              if (current_token_type == TOKEN_IDENTIFIER)
              {
                symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype, scope_level);
                if (symbol_table_element != NULL)
                {
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      last_ast_element->sibling = new_ast_element;
                      last_ast_element = last_ast_element->sibling;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                }
                else
                {
                  token_element = cst_element->token_entry;
                  if (token_element != NULL)
                  {
                    printf ("Error on line %lld: \"%s\" is not declared as a variable.\n", token_element->line_number, current_token);
                  }
                  state = 99999;
                }
              }
              else
              {
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            if (current_token_type == TOKEN_LEFT_PARENTHESIS)
            {
              if (current_token != NULL)
              {
                state = 11500;
                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (current_token_type == TOKEN_RIGHT_PARENTHESIS)
              {
                if (expression_stack != NULL)
                {
                  state = 11500;
                  stack_token = expression_stack->token;
                  stack_token_type = expression_stack->token_type;
                  while ((stack_token_type != TOKEN_LEFT_PARENTHESIS) && (state != 99999))
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->sibling = new_ast_element;
                        last_ast_element = last_ast_element->sibling;
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                    if (expression_stack != NULL)
                    {
                      stack_token = expression_stack->token;
                      stack_token_type = expression_stack->token_type;
                      match = stack_token_type == TOKEN_LEFT_PARENTHESIS;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                  expression_stack = pop_expression_stack (expression_stack);
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)             || 
                    (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)          || 
                    (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL) || 
                    (current_token_type == TOKEN_AND)                || (current_token_type == TOKEN_OR)                    || 
                    (current_token_type == TOKEN_XOR)                || (current_token_type == TOKEN_NOT)                   || 
                    (current_token_type == TOKEN_PLUS)               || (current_token_type == TOKEN_MINUS)                 || 
                    (current_token_type == TOKEN_ASTERISK)           || (current_token_type == TOKEN_DIVIDE)                || 
                    (current_token_type == TOKEN_MODULO)             || (current_token_type == TOKEN_ASSIGNMENT))
                {
                  if (expression_stack == NULL)
                  {
                    if (current_token != NULL)
                    {
                      state = 11500;
                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                    }
                  }
                  else
                  {
                    if (expression_stack->token_type == TOKEN_LEFT_PARENTHESIS)
                    {
                      if (current_token != NULL)
                      {
                        state = 11500;
                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                      }
                    }
                    else
                    {
                      if (current_token_type == TOKEN_NOT)
                      {
                        finished = FALSE;
                        while (!finished)
                        {
                          if (expression_stack != NULL)
                          {
                            stack_token = expression_stack->token;
                            stack_token_type = expression_stack->token_type;
                            if (stack_token != NULL)
                            {
                              if (stack_token_type == TOKEN_NOT)
                              {
                                new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                if (new_ast_element != NULL)
                                {
                                  if (last_ast_element != NULL)
                                  {
                                    last_ast_element->sibling = new_ast_element;
                                    last_ast_element = last_ast_element->sibling;
                                  }
                                  expression_stack = pop_expression_stack (expression_stack);
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                            else
                            {
                              state = 99999;
                              finished = TRUE;
                            }
                          }
                          else
                          {
                            expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                            finished = TRUE;
                          }
                        }
                      }
                      else
                      {
                        if ((current_token_type == TOKEN_ASTERISK) || (current_token_type == TOKEN_DIVIDE) || (current_token_type == TOKEN_MODULO))
                        {
                          state = 11500;
                          finished = FALSE;
                          while (!finished)
                          {
                            if (expression_stack != NULL)
                            {                         
                              stack_token = expression_stack->token;
                              stack_token_type = expression_stack->token_type;
                              if (stack_token != NULL)
                              {
                                if ((stack_token_type == TOKEN_NOT)       || 
                                    (stack_token_type == TOKEN_ASTERISK)  || 
                                    (stack_token_type == TOKEN_DIVIDE)    || 
                                    (stack_token_type == TOKEN_MODULO))
                                {
                                  new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                  if (new_ast_element != NULL)
                                  {
                                    if (last_ast_element != NULL)
                                    {
                                      last_ast_element->sibling = new_ast_element;
                                      last_ast_element = last_ast_element->sibling;
                                    }
                                    expression_stack = pop_expression_stack (expression_stack);
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                              finished = TRUE;
                            }
                          }
                        }
                        else
                        {
                          if ((current_token_type == TOKEN_PLUS) || (current_token_type == TOKEN_MINUS))
                          {
                            state = 11500;
                            finished = FALSE;
                            while (!finished)
                            {
                              if (expression_stack != NULL)
                              {                         
                                stack_token = expression_stack->token;
                                stack_token_type = expression_stack->token_type;
                                if (stack_token != NULL)
                                {
                                  if ((stack_token_type == TOKEN_NOT)       || (stack_token_type == TOKEN_ASTERISK) || 
                                      (stack_token_type == TOKEN_DIVIDE)    || (stack_token_type == TOKEN_MODULO)   || 
                                      (stack_token_type == TOKEN_PLUS)      || (stack_token_type == TOKEN_MINUS))
                                  {
                                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                    if (new_ast_element != NULL)
                                    {
                                      if (last_ast_element != NULL)
                                      {
                                        last_ast_element->sibling = new_ast_element;
                                        last_ast_element = last_ast_element->sibling;
                                      }
                                      expression_stack = pop_expression_stack (expression_stack);
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                  finished = TRUE;
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                          }
                          else
                          {
                            if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)              ||
                                (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)           ||
                                (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                            {
                              state = 11500;
                              finished = FALSE;
                              while (!finished)
                              {
                                if (expression_stack != NULL)
                                {                         
                                  stack_token = expression_stack->token;
                                  stack_token_type = expression_stack->token_type;
                                  if (stack_token != NULL)
                                  {
                                    if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                        (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                        (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                        (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                        (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                                    {
                                      new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                      if (new_ast_element != NULL)
                                      {
                                        if (last_ast_element != NULL)
                                        {
                                          last_ast_element->sibling = new_ast_element;
                                          last_ast_element = last_ast_element->sibling;
                                        }
                                        expression_stack = pop_expression_stack (expression_stack);
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              if (current_token_type == TOKEN_AND)
                              {
                                state = 11500;
                                finished = FALSE;
                                while (!finished)
                                {
                                  if (expression_stack != NULL)
                                  {                         
                                    stack_token = expression_stack->token;
                                    stack_token_type = expression_stack->token_type;
                                    if (stack_token != NULL)
                                    {
                                      if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                          (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                          (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                          (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                          (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                          (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                          (stack_token_type == TOKEN_AND))
                                      {
                                        new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                        if (new_ast_element != NULL)
                                        {
                                          if (last_ast_element != NULL)
                                          {
                                            last_ast_element->sibling = new_ast_element;
                                            last_ast_element = last_ast_element->sibling;
                                          }
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        else
                                        {
                                          state = 99999;
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                              }
                              else
                              {
                                if (current_token_type == TOKEN_OR)
                                {
                                  state = 11500;
                                  finished = FALSE;
                                  while (!finished)
                                  {
                                    if (expression_stack != NULL)
                                    {                         
                                      stack_token = expression_stack->token;
                                      stack_token_type = expression_stack->token_type;
                                      if (stack_token != NULL)
                                      {
                                        if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                            (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                            (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                            (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                            (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                            (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                            (stack_token_type == TOKEN_AND)                || (stack_token_type == TOKEN_OR))
                                        {
                                          new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                          if (new_ast_element != NULL)
                                          {
                                            if (last_ast_element != NULL)
                                            {
                                              last_ast_element->sibling = new_ast_element;
                                              last_ast_element = last_ast_element->sibling;
                                            }
                                            expression_stack = pop_expression_stack (expression_stack);
                                          }
                                          else
                                          {
                                            state = 99999;
                                            finished = TRUE;
                                          }
                                        }
                                        else
                                        {
                                          expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        // ********************************************************************
                                        // * Clear the expression stack because an unexpected error occurred. *
                                        // ********************************************************************
                                        while (expression_stack != NULL)
                                        {
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        finished = TRUE;
                                        state = 99999;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                else
                {
                  if (current_token_type == TOKEN_SEMICOLON)
                  {
                    while (expression_stack != NULL)
                    {
                      stack_token = expression_stack->token;
                      stack_token_type = expression_stack->token_type;
                      if (stack_token != NULL)
                      {
                        new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _set, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                        if (new_ast_element != NULL)
                        {
                          if (last_ast_element != NULL)
                          {
                            last_ast_element->sibling = new_ast_element;
                            last_ast_element = last_ast_element->sibling;
                          }
                        }
                      }
                      expression_stack = pop_expression_stack (expression_stack);
                    }
                    state = 4000;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
            }
          }
        break;
// **********
// * if ... *
// **********
        case 12000:
          if (current_token_type == TOKEN_LEFT_PARENTHESIS)
          {
            if (current_token != NULL)
            {
              state = 12010;
              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
// *********************
// * if ( <EXPRESSION> *
// *********************
        case 12010:
          if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER) ||
              (current_token_type == TOKEN_TRUE)                        || (current_token_type == TOKEN_FALSE))
          {
            if (current_token != NULL)
            {
              state = 12010;
              symbol_table_element = NULL;
              if (current_token_type == TOKEN_IDENTIFIER)
              {
                symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype, scope_level);
                if (symbol_table_element != NULL)
                {
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _if, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      last_ast_element->sibling = new_ast_element;
                      last_ast_element = last_ast_element->sibling;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                }
                else
                {
                  token_element = cst_element->token_entry;
                  if (token_element != NULL)
                  {
                    printf ("Error on line %lld: \"%s\" is not declared as a variable.\n", token_element->line_number, current_token);
                  }
                  state = 99999;
                }
              }
              else
              {
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _if, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            if (current_token_type == TOKEN_LEFT_PARENTHESIS)
            {
              if (current_token != NULL)
              {
                state = 12010;
                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (current_token_type == TOKEN_RIGHT_PARENTHESIS)
              {
                if (expression_stack != NULL)
                {
                  state = 12010;
                  stack_token = expression_stack->token;
                  stack_token_type = expression_stack->token_type;
                  while (stack_token_type != TOKEN_LEFT_PARENTHESIS)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->sibling = new_ast_element;
                        last_ast_element = last_ast_element->sibling;
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                    stack_token = expression_stack->token;
                    stack_token_type = expression_stack->token_type;
                  }
                  expression_stack = pop_expression_stack (expression_stack);
                }
              }
              else
              {
                if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)             || 
                    (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)          || 
                    (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL) || 
                    (current_token_type == TOKEN_AND)                || (current_token_type == TOKEN_OR)                    || 
                    (current_token_type == TOKEN_NOT)                || (current_token_type == TOKEN_PLUS)                  || 
                    (current_token_type == TOKEN_MINUS)              || (current_token_type == TOKEN_ASTERISK)              || 
                    (current_token_type == TOKEN_DIVIDE)             || (current_token_type == TOKEN_MODULO))
                {
                  if (expression_stack == NULL)
                  {
                    if (current_token != NULL)
                    {
                      state = 12010;
                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                    }
                  }
                  else
                  {
                    if (expression_stack->token_type == TOKEN_LEFT_PARENTHESIS)
                    {
                      if (current_token != NULL)
                      {
                        state = 12010;
                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                      }
                    }
                    else
                    {
                      if (current_token_type == TOKEN_NOT)
                      {
                        finished = FALSE;
                        while (!finished)
                        {
                          if (expression_stack != NULL)
                          {
                            stack_token = expression_stack->token;
                            stack_token_type = expression_stack->token_type;
                            if (stack_token != NULL)
                            {
                              if (stack_token_type == TOKEN_NOT)
                              {
                                new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                if (new_ast_element != NULL)
                                {
                                  if (last_ast_element != NULL)
                                  {
                                    last_ast_element->sibling = new_ast_element;
                                    last_ast_element = last_ast_element->sibling;
                                  }
                                  expression_stack = pop_expression_stack (expression_stack);
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                            else
                            {
                              state = 99999;
                              finished = TRUE;
                            }
                          }
                          else
                          {
                            expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                            finished = TRUE;
                          }
                        }
                      }
                      else
                      {
                        if ((current_token_type == TOKEN_ASTERISK) || (current_token_type == TOKEN_DIVIDE) || (current_token_type == TOKEN_MODULO))
                        {
                          state = 12010;
                          finished = FALSE;
                          while (!finished)
                          {
                            if (expression_stack != NULL)
                            {                         
                              stack_token = expression_stack->token;
                              stack_token_type = expression_stack->token_type;
                              if (stack_token != NULL)
                              {
                                if ((stack_token_type == TOKEN_NOT)      || 
                                    (stack_token_type == TOKEN_ASTERISK) || 
                                    (stack_token_type == TOKEN_DIVIDE)   || 
                                    (stack_token_type == TOKEN_MODULO))
                                {
                                  new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                  if (new_ast_element != NULL)
                                  {
                                    if (last_ast_element != NULL)
                                    {
                                      last_ast_element->sibling = new_ast_element;
                                      last_ast_element = last_ast_element->sibling;
                                    }
                                    expression_stack = pop_expression_stack (expression_stack);
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                              finished = TRUE;
                            }
                          }
                        }
                        else
                        {
                          if ((current_token_type == TOKEN_PLUS) || (current_token_type == TOKEN_MINUS))
                          {
                            state = 12010;
                            finished = FALSE;
                            while (!finished)
                            {
                              if (expression_stack != NULL)
                              {                         
                                stack_token = expression_stack->token;
                                stack_token_type = expression_stack->token_type;
                                if (stack_token != NULL)
                                {
                                  if ((stack_token_type == TOKEN_NOT)       || (stack_token_type == TOKEN_ASTERISK) || 
                                      (stack_token_type == TOKEN_DIVIDE)    || (stack_token_type == TOKEN_MODULO)   || 
                                      (stack_token_type == TOKEN_PLUS)      || (stack_token_type == TOKEN_MINUS))
                                  {
                                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                    if (new_ast_element != NULL)
                                    {
                                      if (last_ast_element != NULL)
                                      {
                                        last_ast_element->sibling = new_ast_element;
                                        last_ast_element = last_ast_element->sibling;
                                      }
                                      expression_stack = pop_expression_stack (expression_stack);
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                  finished = TRUE;
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                          }
                          else
                          {
                            if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)              ||
                                (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)           ||
                                (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                            {
                              state = 12010;
                              finished = FALSE;
                              while (!finished)
                              {
                                if (expression_stack != NULL)
                                {                         
                                  stack_token = expression_stack->token;
                                  stack_token_type = expression_stack->token_type;
                                  if (stack_token != NULL)
                                  {
                                    if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                        (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                        (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                        (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                        (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                                    {
                                      new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                      if (new_ast_element != NULL)
                                      {
                                        if (last_ast_element != NULL)
                                        {
                                          last_ast_element->sibling = new_ast_element;
                                          last_ast_element = last_ast_element->sibling;
                                        }
                                        expression_stack = pop_expression_stack (expression_stack);
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              if (current_token_type == TOKEN_AND)
                              {
                                state = 12010;
                                finished = FALSE;
                                while (!finished)
                                {
                                  if (expression_stack != NULL)
                                  {                         
                                    stack_token = expression_stack->token;
                                    stack_token_type = expression_stack->token_type;
                                    if (stack_token != NULL)
                                    {
                                      if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                          (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                          (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                          (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                          (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                          (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                          (stack_token_type == TOKEN_AND))
                                      {
                                        new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                        if (new_ast_element != NULL)
                                        {
                                          if (last_ast_element != NULL)
                                          {
                                            last_ast_element->sibling = new_ast_element;
                                            last_ast_element = last_ast_element->sibling;
                                          }
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        else
                                        {
                                          state = 99999;
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                              }
                              else
                              {
                                if (current_token_type == TOKEN_OR)
                                {
                                  state = 12010;
                                  finished = FALSE;
                                  while (!finished)
                                  {
                                    if (expression_stack != NULL)
                                    {                         
                                      stack_token = expression_stack->token;
                                      stack_token_type = expression_stack->token_type;
                                      if (stack_token != NULL)
                                      {
                                        if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                            (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                            (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                            (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                            (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                            (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                            (stack_token_type == TOKEN_AND)                || (stack_token_type == TOKEN_OR))
                                        {
                                          new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                          if (new_ast_element != NULL)
                                          {
                                            if (last_ast_element != NULL)
                                            {
                                              last_ast_element->sibling = new_ast_element;
                                              last_ast_element = last_ast_element->sibling;
                                            }
                                            expression_stack = pop_expression_stack (expression_stack);
                                          }
                                          else
                                          {
                                            state = 99999;
                                            finished = TRUE;
                                          }
                                        }
                                        else
                                        {
                                          expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                else
                {
                  if (current_token_type == TOKEN_LEFT_CURLY_BRACE)
                  {
                    num_left_curly_braces++;
                    state = 4000;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->child = new_ast_element;
                        last_ast_element = last_ast_element->child;
                      }
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
            }
          }
        break;
// ************
// * else ... *
// ************
        case 13000:
          if (current_token_type == TOKEN_LEFT_CURLY_BRACE)
          {
            num_left_curly_braces++;
            new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
            if (new_ast_element != NULL)
            {
              if (last_ast_element != NULL)
              {
                state = 4000;
                last_ast_element->child = new_ast_element;
                last_ast_element = last_ast_element->child;
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
        break;
// *************
// * while ... *
// *************
        case 14000:
          if (current_token_type == TOKEN_LEFT_PARENTHESIS)
          {
            if (current_token != NULL)
            {
              state = 14010;
              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
// ************************
// * while ( <EXPRESSION> *
// ************************
        case 14010:
          if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER) ||
              (current_token_type == TOKEN_TRUE)                        || (current_token_type == TOKEN_FALSE))
          {
            if (current_token != NULL)
            {
              state = 14010;
              symbol_table_element = NULL;
              if (current_token_type == TOKEN_IDENTIFIER)
              {
                symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype, scope_level);
                if (symbol_table_element != NULL)
                {
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _while, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      last_ast_element->sibling = new_ast_element;
                      last_ast_element = last_ast_element->sibling;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                }
                else
                {
                  token_element = cst_element->token_entry;
                  if (token_element != NULL)
                  {
                    printf ("Error on line %lld: \"%s\" is not declared as a variable.\n", token_element->line_number, current_token);
                  }
                  state = 99999;
                }
              }
              else
              {
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _while, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            if (current_token_type == TOKEN_LEFT_PARENTHESIS)
            {
              if (current_token != NULL)
              {
                state = 14010;
                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (current_token_type == TOKEN_RIGHT_PARENTHESIS)
              {
                if (expression_stack != NULL)
                {
                  state = 14010;
                  stack_token = expression_stack->token;
                  stack_token_type = expression_stack->token_type;
                  while (stack_token_type != TOKEN_LEFT_PARENTHESIS)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->sibling = new_ast_element;
                        last_ast_element = last_ast_element->sibling;
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                    stack_token = expression_stack->token;
                    stack_token_type = expression_stack->token_type;
                  }
                  expression_stack = pop_expression_stack (expression_stack);
                }
              }
              else
              {
                if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)             || 
                    (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)          || 
                    (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL) || 
                    (current_token_type == TOKEN_AND)                || (current_token_type == TOKEN_OR)                    || 
                    (current_token_type == TOKEN_NOT)                || (current_token_type == TOKEN_PLUS)                  || 
                    (current_token_type == TOKEN_MINUS)              || (current_token_type == TOKEN_ASTERISK)              || 
                    (current_token_type == TOKEN_DIVIDE)             || (current_token_type == TOKEN_MODULO))
                {
                  if (expression_stack == NULL)
                  {
                    if (current_token != NULL)
                    {
                      state = 14010;
                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                    }
                  }
                  else
                  {
                    if (expression_stack->token_type == TOKEN_LEFT_PARENTHESIS)
                    {
                      if (current_token != NULL)
                      {
                        state = 14010;
                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                      }
                    }
                    else
                    {
                      if (current_token_type == TOKEN_NOT)
                      {
                        finished = FALSE;
                        while (!finished)
                        {
                          if (expression_stack != NULL)
                          {
                            stack_token = expression_stack->token;
                            stack_token_type = expression_stack->token_type;
                            if (stack_token != NULL)
                            {
                              if (stack_token_type == TOKEN_NOT)
                              {
                                new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                if (new_ast_element != NULL)
                                {
                                  if (last_ast_element != NULL)
                                  {
                                    last_ast_element->sibling = new_ast_element;
                                    last_ast_element = last_ast_element->sibling;
                                  }
                                  expression_stack = pop_expression_stack (expression_stack);
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                            else
                            {
                              state = 99999;
                              finished = TRUE;
                            }
                          }
                          else
                          {
                            expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                            finished = TRUE;
                          }
                        }
                      }
                      else
                      {
                        if ((current_token_type == TOKEN_ASTERISK) || (current_token_type == TOKEN_DIVIDE) || (current_token_type == TOKEN_MODULO))
                        {
                          state = 14010;
                          finished = FALSE;
                          while (!finished)
                          {
                            if (expression_stack != NULL)
                            {                         
                              stack_token = expression_stack->token;
                              stack_token_type = expression_stack->token_type;
                              if (stack_token != NULL)
                              {
                                if ((stack_token_type == TOKEN_NOT)       || 
                                    (stack_token_type == TOKEN_ASTERISK)  || 
                                    (stack_token_type == TOKEN_DIVIDE)    || 
                                    (stack_token_type == TOKEN_MODULO))
                                {
                                  new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                  if (new_ast_element != NULL)
                                  {
                                    if (last_ast_element != NULL)
                                    {
                                      last_ast_element->sibling = new_ast_element;
                                      last_ast_element = last_ast_element->sibling;
                                    }
                                    expression_stack = pop_expression_stack (expression_stack);
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                              finished = TRUE;
                            }
                          }
                        }
                        else
                        {
                          if ((current_token_type == TOKEN_PLUS) || (current_token_type == TOKEN_MINUS))
                          {
                            state = 14010;
                            finished = FALSE;
                            while (!finished)
                            {
                              if (expression_stack != NULL)
                              {                         
                                stack_token = expression_stack->token;
                                stack_token_type = expression_stack->token_type;
                                if (stack_token != NULL)
                                {
                                  if ((stack_token_type == TOKEN_NOT)       || (stack_token_type == TOKEN_ASTERISK) || 
                                      (stack_token_type == TOKEN_DIVIDE)    || (stack_token_type == TOKEN_MODULO)   || 
                                      (stack_token_type == TOKEN_PLUS)      || (stack_token_type == TOKEN_MINUS))
                                  {
                                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                    if (new_ast_element != NULL)
                                    {
                                      if (last_ast_element != NULL)
                                      {
                                        last_ast_element->sibling = new_ast_element;
                                        last_ast_element = last_ast_element->sibling;
                                      }
                                      expression_stack = pop_expression_stack (expression_stack);
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                  finished = TRUE;
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                          }
                          else
                          {
                            if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)              ||
                                (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)           ||
                                (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                            {
                              state = 14010;
                              finished = FALSE;
                              while (!finished)
                              {
                                if (expression_stack != NULL)
                                {                         
                                  stack_token = expression_stack->token;
                                  stack_token_type = expression_stack->token_type;
                                  if (stack_token != NULL)
                                  {
                                    if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                        (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                        (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                        (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                        (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                                    {
                                      new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                      if (new_ast_element != NULL)
                                      {
                                        if (last_ast_element != NULL)
                                        {
                                          last_ast_element->sibling = new_ast_element;
                                          last_ast_element = last_ast_element->sibling;
                                        }
                                        expression_stack = pop_expression_stack (expression_stack);
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              if (current_token_type == TOKEN_AND)
                              {
                                state = 14010;
                                finished = FALSE;
                                while (!finished)
                                {
                                  if (expression_stack != NULL)
                                  {                         
                                    stack_token = expression_stack->token;
                                    stack_token_type = expression_stack->token_type;
                                    if (stack_token != NULL)
                                    {
                                      if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                          (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                          (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                          (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                          (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                          (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                          (stack_token_type == TOKEN_AND))
                                      {
                                        new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                        if (new_ast_element != NULL)
                                        {
                                          if (last_ast_element != NULL)
                                          {
                                            last_ast_element->sibling = new_ast_element;
                                            last_ast_element = last_ast_element->sibling;
                                          }
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        else
                                        {
                                          state = 99999;
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                              }
                              else
                              {
                                if (current_token_type == TOKEN_OR)
                                {
                                  state = 14010;
                                  finished = FALSE;
                                  while (!finished)
                                  {
                                    if (expression_stack != NULL)
                                    {                         
                                      stack_token = expression_stack->token;
                                      stack_token_type = expression_stack->token_type;
                                      if (stack_token != NULL)
                                      {
                                        if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                            (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                            (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                            (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                            (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                            (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                            (stack_token_type == TOKEN_AND)                || (stack_token_type == TOKEN_OR))
                                        {
                                          new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _while, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                          if (new_ast_element != NULL)
                                          {
                                            if (last_ast_element != NULL)
                                            {
                                              last_ast_element->sibling = new_ast_element;
                                              last_ast_element = last_ast_element->sibling;
                                            }
                                            expression_stack = pop_expression_stack (expression_stack);
                                          }
                                          else
                                          {
                                            state = 99999;
                                            finished = TRUE;
                                          }
                                        }
                                        else
                                        {
                                          expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                else
                {
                  if (current_token_type == TOKEN_LEFT_CURLY_BRACE)
                  {
                    num_left_curly_braces++;
                    state = 4000;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->child = new_ast_element;
                        last_ast_element = last_ast_element->child;
                      }
                    }
                  }
                  else
                  {
                    state = 99999;
                  }
                }
              }
            }
          }
        break;
// ************
// * call ... *
// ************
        case 15000:
          if (current_token_type == TOKEN_IDENTIFIER)
          {
            if (current_token != NULL)
            {
// ***************************************************************************************************************************************
// * Note: I already know the IDENTIFIER must be a procedure since this is a CALL statement. If this statement began as a SET statement, *
// * then I would know any call is expected to return a value (i.e. a function call rather than a procedure call).                       *
// ***************************************************************************************************************************************
              symbol_table_element = retrieve_symbol_table_element_for_function_or_procedure_name (symbol_table, current_token, _procedure);
              if (symbol_table_element != NULL)
              {
                num_left_parenthesis = 0;
                num_right_parenthesis = 0;
                num_operands = 0;
                num_parameters_being_sent_to_procedure = 0;
                num_parameters_defined_in_procedure = 0;
// ***************************************************************************************************************************************
// * Count the number of parameters defined in the procedure. Once the expression is evaluated, I will compare the number of parameters  *
// * inside the procedure declaration with the number of parameters actually sent to the procedure. That later step will be counted when *
// * I convert expression to postfix (See state 16000 below).                                                                            *
// ***************************************************************************************************************************************
                parameter_list_element = symbol_table_element->parameter_list;
                while (parameter_list_element != NULL)
                {
                  num_parameters_defined_in_procedure++;
                  parameter_list_element = parameter_list_element->next;
                }
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _call, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                    state = 15010;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                token_element = cst_element->token_entry;
                if (token_element != NULL)
                {
                  printf ("Error on line %lld: \"%s\" is not declared as the name of a procedure.\n", token_element->line_number, current_token);
                }
                state = 99999;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            printf ("Error on line %lld near \"%s\".\n", token_element->line_number, current_token);
            state = 99999;
          }
        break;
// *************************
// * call <IDENTIFIER> ... *
// *************************
        case 15010:
          if (current_token_type == TOKEN_LEFT_PARENTHESIS)
          {
            if (current_token != NULL)
            {
              state = 16000;
              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
// ************************************
// * call <IDENTIFIER> ( <EXPRESSION> *
// ************************************
        case 16000:
          if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER) ||
              (current_token_type == TOKEN_TRUE)                        || (current_token_type == TOKEN_FALSE))
          {
            if (current_token != NULL)
            {
              symbol_table_element = NULL;
              if (current_token_type == TOKEN_IDENTIFIER)
              {
                symbol_table_element = retrieve_symbol_table_element (symbol_table, current_token, _datatype, scope_level);
                if (symbol_table_element != NULL)
                {
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _call, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                  if (new_ast_element != NULL)
                  {
                    if (last_ast_element != NULL)
                    {
                      num_operands++;
                      state = 16000;
                      last_ast_element->sibling = new_ast_element;
                      last_ast_element = last_ast_element->sibling;
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                }
                else
                {
                  token_element = cst_element->token_entry;
                  if (token_element != NULL)
                  {
                    printf ("Error on line %lld: \"%s\" is not declared as a variable.\n", token_element->line_number, current_token);
                  }
                  state = 99999;
                }
              }
              else
              {
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _call, cst_element->token_entry, symbol_table_element, num_left_curly_braces, num_right_curly_braces);
                if (new_ast_element != NULL)
                {
                  if (last_ast_element != NULL)
                  {
                    num_operands++;
                    state = 16000;
                    last_ast_element->sibling = new_ast_element;
                    last_ast_element = last_ast_element->sibling;
                  }
                  else
                  {
                    state = 99999;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            if (current_token_type == TOKEN_LEFT_PARENTHESIS)
            {
              if (current_token != NULL)
              {
                state = 16000;
                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
              }
              else
              {
                state = 99999;
              }
            }
            else
            {
              if (current_token_type == TOKEN_RIGHT_PARENTHESIS)
              {
                if (expression_stack != NULL)
                {
                  stack_token = expression_stack->token;
                  stack_token_type = expression_stack->token_type;
                  while (stack_token_type != TOKEN_LEFT_PARENTHESIS)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                    if (new_ast_element != NULL)
                    {
                      if (last_ast_element != NULL)
                      {
                        last_ast_element->sibling = new_ast_element;
                        last_ast_element = last_ast_element->sibling;
                      }
                    }
                    expression_stack = pop_expression_stack (expression_stack);
                    stack_token = expression_stack->token;
                    stack_token_type = expression_stack->token_type;
                  }
                  expression_stack = pop_expression_stack (expression_stack);
                  if (expression_stack == NULL)
                  {
                    state = 16020;
                  }
                  else
                  {
                    state = 16000;
                  }
                }
                else
                {
                  state = 99999;
                }
              }
              else
              {
                if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)             || 
                    (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)          || 
                    (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL) || 
                    (current_token_type == TOKEN_AND)                || (current_token_type == TOKEN_OR)                    || 
                    (current_token_type == TOKEN_NOT)                || (current_token_type == TOKEN_PLUS)                  || 
                    (current_token_type == TOKEN_MINUS)              || (current_token_type == TOKEN_ASTERISK)              || 
                    (current_token_type == TOKEN_DIVIDE)             || (current_token_type == TOKEN_MODULO))
                {
                  if (expression_stack == NULL)
                  {
                    if (current_token != NULL)
                    {
                      state = 16000;
                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                    }
                  }
                  else
                  {
                    if (expression_stack->token_type == TOKEN_LEFT_PARENTHESIS)
                    {
                      if (current_token != NULL)
                      {
                        state = 16000;
                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                      }
                    }
                    else
                    {
                      if (current_token_type == TOKEN_NOT)
                      {
                        finished = FALSE;
                        while (!finished)
                        {
                          if (expression_stack != NULL)
                          {
                            stack_token = expression_stack->token;
                            stack_token_type = expression_stack->token_type;
                            if (stack_token != NULL)
                            {
                              if (stack_token_type == TOKEN_NOT)
                              {
                                new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                if (new_ast_element != NULL)
                                {
                                  if (last_ast_element != NULL)
                                  {
                                    last_ast_element->sibling = new_ast_element;
                                    last_ast_element = last_ast_element->sibling;
                                  }
                                  expression_stack = pop_expression_stack (expression_stack);
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                            else
                            {
                              state = 99999;
                              finished = TRUE;
                            }
                          }
                          else
                          {
                            expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                            finished = TRUE;
                          }
                        }
                      }
                      else
                      {
                        if ((current_token_type == TOKEN_ASTERISK) || (current_token_type == TOKEN_DIVIDE) || (current_token_type == TOKEN_MODULO))
                        {
                          state = 16000;
                          finished = FALSE;
                          while (!finished)
                          {
                            if (expression_stack != NULL)
                            {                         
                              stack_token = expression_stack->token;
                              stack_token_type = expression_stack->token_type;
                              if (stack_token != NULL)
                              {
                                if ((stack_token_type == TOKEN_NOT)       || 
                                    (stack_token_type == TOKEN_ASTERISK)  || 
                                    (stack_token_type == TOKEN_DIVIDE)    || 
                                    (stack_token_type == TOKEN_MODULO))
                                {
                                  new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                  if (new_ast_element != NULL)
                                  {
                                    if (last_ast_element != NULL)
                                    {
                                      last_ast_element->sibling = new_ast_element;
                                      last_ast_element = last_ast_element->sibling;
                                    }
                                    expression_stack = pop_expression_stack (expression_stack);
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                              finished = TRUE;
                            }
                          }
                        }
                        else
                        {
                          if ((current_token_type == TOKEN_PLUS) || (current_token_type == TOKEN_MINUS))
                          {
                            state = 16000;
                            finished = FALSE;
                            while (!finished)
                            {
                              if (expression_stack != NULL)
                              {                         
                                stack_token = expression_stack->token;
                                stack_token_type = expression_stack->token_type;
                                if (stack_token != NULL)
                                {
                                  if ((stack_token_type == TOKEN_NOT)       || (stack_token_type == TOKEN_ASTERISK) || 
                                      (stack_token_type == TOKEN_DIVIDE)    || (stack_token_type == TOKEN_MODULO)   || 
                                      (stack_token_type == TOKEN_PLUS)      || (stack_token_type == TOKEN_MINUS))
                                  {
                                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                    if (new_ast_element != NULL)
                                    {
                                      if (last_ast_element != NULL)
                                      {
                                        last_ast_element->sibling = new_ast_element;
                                        last_ast_element = last_ast_element->sibling;
                                      }
                                      expression_stack = pop_expression_stack (expression_stack);
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  state = 99999;
                                  finished = TRUE;
                                }
                              }
                              else
                              {
                                expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                finished = TRUE;
                              }
                            }
                          }
                          else
                          {
                            if ((current_token_type == TOKEN_EQUAL)              || (current_token_type == TOKEN_NOT_EQUAL)              ||
                                (current_token_type == TOKEN_LESS_THAN)          || (current_token_type == TOKEN_GREATER_THAN)           ||
                                (current_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (current_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                            {
                              state = 16000;
                              finished = FALSE;
                              while (!finished)
                              {
                                if (expression_stack != NULL)
                                {                         
                                  stack_token = expression_stack->token;
                                  stack_token_type = expression_stack->token_type;
                                  if (stack_token != NULL)
                                  {
                                    if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                        (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                        (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                        (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                        (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL))
                                    {
                                      new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                      if (new_ast_element != NULL)
                                      {
                                        if (last_ast_element != NULL)
                                        {
                                          last_ast_element->sibling = new_ast_element;
                                          last_ast_element = last_ast_element->sibling;
                                        }
                                        expression_stack = pop_expression_stack (expression_stack);
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    state = 99999;
                                    finished = TRUE;
                                  }
                                }
                                else
                                {
                                  expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                  finished = TRUE;
                                }
                              }
                            }
                            else
                            {
                              if (current_token_type == TOKEN_AND)
                              {
                                state = 16000;
                                finished = FALSE;
                                while (!finished)
                                {
                                  if (expression_stack != NULL)
                                  {                         
                                    stack_token = expression_stack->token;
                                    stack_token_type = expression_stack->token_type;
                                    if (stack_token != NULL)
                                    {
                                      if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                          (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                          (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                          (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                          (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                          (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                          (stack_token_type == TOKEN_AND))
                                      {
                                        new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                        if (new_ast_element != NULL)
                                        {
                                          if (last_ast_element != NULL)
                                          {
                                            last_ast_element->sibling = new_ast_element;
                                            last_ast_element = last_ast_element->sibling;
                                          }
                                          expression_stack = pop_expression_stack (expression_stack);
                                        }
                                        else
                                        {
                                          state = 99999;
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      state = 99999;
                                      finished = TRUE;
                                    }
                                  }
                                  else
                                  {
                                    expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                    finished = TRUE;
                                  }
                                }
                              }
                              else
                              {
                                if (current_token_type == TOKEN_OR)
                                {
                                  state = 16000;
                                  finished = FALSE;
                                  while (!finished)
                                  {
                                    if (expression_stack != NULL)
                                    {                         
                                      stack_token = expression_stack->token;
                                      stack_token_type = expression_stack->token_type;
                                      if (stack_token != NULL)
                                      {
                                        if ((stack_token_type == TOKEN_NOT)                || (stack_token_type == TOKEN_ASTERISK)               || 
                                            (stack_token_type == TOKEN_DIVIDE)             || (stack_token_type == TOKEN_MODULO)                 || 
                                            (stack_token_type == TOKEN_PLUS)               || (stack_token_type == TOKEN_MINUS)                  || 
                                            (stack_token_type == TOKEN_EQUAL)              || (stack_token_type == TOKEN_NOT_EQUAL)              || 
                                            (stack_token_type == TOKEN_LESS_THAN)          || (stack_token_type == TOKEN_GREATER_THAN)           || 
                                            (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL)  || 
                                            (stack_token_type == TOKEN_AND)                || (stack_token_type == TOKEN_OR))
                                        {
                                          new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                                          if (new_ast_element != NULL)
                                          {
                                            if (last_ast_element != NULL)
                                            {
                                              last_ast_element->sibling = new_ast_element;
                                              last_ast_element = last_ast_element->sibling;
                                            }
                                            expression_stack = pop_expression_stack (expression_stack);
                                          }
                                          else
                                          {
                                            state = 99999;
                                            finished = TRUE;
                                          }
                                        }
                                        else
                                        {
                                          expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                          finished = TRUE;
                                        }
                                      }
                                      else
                                      {
                                        state = 99999;
                                        finished = TRUE;
                                      }
                                    }
                                    else
                                    {
                                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                                      finished = TRUE;
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                else
                {
                  if (current_token_type == TOKEN_COMMA)
                  {
                    if (num_operands > 0)
                    {
                      if (expression_stack != NULL)
                      {
                        state = 16020;
                        stack_token = expression_stack->token;
                        stack_token_type = expression_stack->token_type;
                        while (stack_token_type != TOKEN_LEFT_PARENTHESIS)
                        {
                          new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                          if (new_ast_element != NULL)
                          {
                            if (last_ast_element != NULL)
                            {
                              last_ast_element->sibling = new_ast_element;
                              last_ast_element = last_ast_element->sibling;
                            }
                          }
                          expression_stack = pop_expression_stack (expression_stack);
                          stack_token = expression_stack->token;
                          stack_token_type = expression_stack->token_type;
                        }
                        new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _call, cst_element->token_entry, NULL, num_left_curly_braces, num_right_curly_braces);
                        if (new_ast_element != NULL)
                        {
                          if (last_ast_element != NULL)
                          {
                            num_parameters_being_sent_to_procedure++;
                            num_operands = 0;
                            state = 16000;
                            last_ast_element->sibling = new_ast_element;
                            last_ast_element = last_ast_element->sibling;
                          }
                          else
                          {
                            state = 99999;
                          } 
                        }
                        else
                        {
                          state = 99999;
                        }
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                    else
                    {
                      printf ("Error on line %lld: expected at least one operand before last comma.\n", token_element->line_number);
                      state = 99999;
                    }
                  }
                  else
                  {
                    if (current_token_type == TOKEN_SEMICOLON)
                    {
                      if (num_operands > 0)
                      {
                        num_parameters_being_sent_to_procedure++;
                      }
                      //printf ("num_operands = %llu\n", num_operands);
                      //printf ("num_parameters_being_sent_to_procedure = %llu\n", num_parameters_being_sent_to_procedure);
                      //printf ("num_parameters_defined_in_procedure    = %llu\n", num_parameters_defined_in_procedure);
                      if (num_parameters_being_sent_to_procedure == num_parameters_defined_in_procedure)
                      {
                        state = 4000;
                      }
                      else
                      {
                        if (cst_element->token_entry != NULL)
                        {
                          printf ("Error on line %lld: number of parameters in call statement does not match the number of parameters defined in procedure.\n", cst_element->token_entry->line_number);
                        }
                        state = 99999;
                      }
                    }
                    else
                    {
                      state = 99999;
                    }
                  }
                }
              }
            }
          }
        break;
// **************************************
// * call <IDENTIFIER> ( <EXPRESSION> ) *
// **************************************
        case 16020:
          if (current_token_type == TOKEN_SEMICOLON)
          {
            if (num_operands > 0)
            {
              num_parameters_being_sent_to_procedure++;
            }
            //printf ("num_operands = %llu\n", num_operands);
            //printf ("num_parameters_being_sent_to_procedure = %llu\n", num_parameters_being_sent_to_procedure);
            //printf ("num_parameters_defined_in_procedure    = %llu\n", num_parameters_defined_in_procedure);
            if (num_parameters_being_sent_to_procedure == num_parameters_defined_in_procedure)
            {
              state = 4000;
            }
            else
            {
              if (cst_element->token_entry != NULL)
              {
                printf ("Error on line %lld: number of parameters in call statement does not match the number of parameters defined in procedure.\n", cst_element->token_entry->line_number);
              }
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;
        default:
        break;
      }
    }
    if (state != 99999)
    {
      if (cst_element->sibling != NULL)
      {
        cst_element = cst_element->sibling;
      }
      else
      {
        cst_element = cst_element->child;
      }
    }
  }
  if (state == 99999)
  {
    while (abstract_syntax_tree != NULL)
    {
      temp_ast_element = abstract_syntax_tree;
      if (abstract_syntax_tree->sibling != NULL)
      {
        abstract_syntax_tree = abstract_syntax_tree->sibling;
      }
      else
      {
        abstract_syntax_tree = abstract_syntax_tree->child;
      }
      if (temp_ast_element->token != NULL)
      {
        free (temp_ast_element->token);
      }
      free (temp_ast_element);
    }
  }
  return abstract_syntax_tree;
}
