/**************************************************************************************
 * 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;
  symtab_node  *symbol_table_element;
  size_t       token_string_length;
  int           state, finished, current_token_type, stack_token_type;
  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;

  state                = 0;
  scope_level          = 0;
  abstract_syntax_tree = NULL;
  last_ast_element     = NULL;
  cst_element = concrete_syntax_tree;
  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);
                  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);
                  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;
              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);
                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);
            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;
        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)
                  {
                    state = 12000;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL);
                    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;
                    }
                  }
                break;
                case 3:
                  if (strncmp(current_token, "set", 3) == 0)
                  {
                    //set_statement_only_contains_integer_constants_in_numerical_expression = cst_element->cst_optimization_flags & 0x01;
                    //if (set_statement_only_contains_integer_constants_in_numerical_expression == 1)
                    //{
                    //  printf ("COMPUTE RESULT IMMEDIATELY IN AST...\n");
                    //}

                    state = 11000;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL);
                    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;
                    }
                  }
                break;
                case 4:
                  if (strncmp(current_token, "else", 4) == 0)
                  {
                    state = 13000;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _else, cst_element->token_entry, NULL);
                    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;
                    }
                  }
                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);
                    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 = 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);
              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);
                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);
                  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);
            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);
                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)
              {
// **************************************************************************************************************************************************************
// * Examine the datatype of the target variable (the one receiving the assignment statement). If the target variable is a BOOL datatype, I should evaluate any *
// * expressions with a mixture of numerical and Boolean operators. If the target variable is an INT datatype, I should evaluate any expressions as strictly    *
// * numerical. This differentiation is important when converting from infix notation to postfix notation using the Shunting Yard algorithm.                    *
// **************************************************************************************************************************************************************
                if (symbol_table_element->attribute_type == _datatype) 
                {
                  if (symbol_table_element->datatype == _int)
                  {
                    state = 11010; // evaluate expressions as numerical only with no Boolean operands (i.e. AND, OR, NOT, >=, >, <, <=, !=, etc.)
                  }
                  else
                  {
                    if (symbol_table_element->datatype == _float)
                    {
                      state = 11200; // evaluate expressions as numerical only with no Boolean operands (i.e. AND, OR, NOT, >=, >, <, <=, !=, etc.)
                    }
                    else
                    {
                      if (symbol_table_element->datatype == _bool)
                      {
                        state = 11500; // evaluate expressions as mixed numerical and Boolean. 
                      }
                      else
                      {
                        state = 99999;
                      }
                    }
                  }
                }
                else
                {
                  state = 99999;
                }
                new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element);
                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
              {
                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 an integer datatype.                                                                                           *
// *                                                                                                                                      *
// * When processing numerical expressions to the right of the assignment operator, use the Dijkstra's Shunting Yard algorithm to convert *
// * the expression from infix notation into postfix notation. Converting the expression to postfix notation makes it immensely easier to *
// * evaluate the expression once it is implemented in in assembly language.                                                              *
// ****************************************************************************************************************************************
        case 11010:
          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 = 11010;
              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);
                  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
              {
                if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT))
                {
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element);
                  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
                {
                  if (current_token_type == TOKEN_TRUE)
                  {
// *********************************************************************************************
// * Substitute a one for Boolean TRUE to simplify run-time processing of Boolean expressions. *
// *********************************************************************************************
                    new_ast_element = add_element_to_abstract_syntax_tree ("1", TOKEN_IDENTIFIER_INTEGER_CONSTANT, _set, cst_element->token_entry, symbol_table_element);
                    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
                  {
// ***********************************************************************************************
// * Substitute a zero for Boolean FALSE to simplify run-time processing of Boolean expressions. *
// ***********************************************************************************************
                    new_ast_element = add_element_to_abstract_syntax_tree ("0", TOKEN_IDENTIFIER_INTEGER_CONSTANT, _set, cst_element->token_entry, symbol_table_element);
                    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 = 11010;
                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 = 11010;
                  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, _set, cst_element->token_entry, NULL);
                    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_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 = 11010;
                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                    }
                  }
                  else
                  {
                    if ((current_token_type == TOKEN_PLUS) || (current_token_type == TOKEN_MINUS)) 
                    {
                      state = 11010;
                      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_PLUS)     || 
                                (stack_token_type == TOKEN_MINUS)    ||
                                (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, _set, cst_element->token_entry, NULL);
                              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 = 11010;
                        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_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, _set, cst_element->token_entry, NULL);
                                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
                          {
                            expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                            finished = TRUE;
                          }
                        }
                      }
                      else
                      {
                        if (current_token_type == TOKEN_ASSIGNMENT)
                        {
                          state = 11010;
                          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_PLUS)     || 
                                    (stack_token_type == TOKEN_MINUS)    || 
                                    (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, _set, cst_element->token_entry, NULL);
                                  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;
                        }
                      }
                    }
                  }
                }
                else
                {
                  if (current_token_type == TOKEN_SEMICOLON)
                  {
                    state = 4000;
                    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);
                        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;
                  }
                }
              }
            }
          }
        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.                                                                                          *
// ************************************************************************************************************************************
        case 11200:
          if (current_token_type == TOKEN_ASSIGNMENT)
          {
            if (current_token != NULL)
            {
              state = 11300;
              expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
            }
          }
          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);
              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)
                  {
                    state = 11300;
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, NULL);
                    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;
                default:
                  state = 99999;
                break;
              }
            }
            else
            {
              state = 99999;
            }
          }
          else
          {
            state = 99999;
          }
        break;       
// ****************************************************************************************************************************************
// * set <IDENTIFIER>                                                                                                                     *
// *                                                                                                                                      *
// * Note: <IDENTIFIER> is a float datatype. The expression below is meant ONLY for float datatypes as the target variable (the variable  *
// * being assigned a value) was already declared as a float datatype.                                                                    *
// *                                                                                                                                      *
// * When processing numerical expressions to the right of the assignment operator, use the Dijkstra's Shunting Yard algorithm to convert *
// * the expression from infix notation into postfix notation. Converting the expression to postfix notation makes it immensely easier to *
// * evaluate the expression once it is implemented in in assembly language.                                                              *
// ****************************************************************************************************************************************
        case 11300:
          if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT) ||
              (current_token_type == TOKEN_IDENTIFIER))
          {
            if (current_token != NULL)
            {
              state = 11300;
              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)
                {
                  if (symbol_table_element->datatype == _float)
                  { 
                    new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element);
                    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\" was not declared as a float datatatype. Automatic datatype conversion is not fully functional yet for mixed datatype expressions.\n", token_element->line_number, current_token);
                    }
                    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
              {
                if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT))
                {
                  new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _set, cst_element->token_entry, symbol_table_element);
                  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
          {
            if (current_token_type == TOKEN_LEFT_PARENTHESIS)
            {
              if (current_token != NULL)
              {
                state = 11300;
                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 = 11300;
                  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, _set, cst_element->token_entry, NULL);
                    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_PLUS)     || (current_token_type == TOKEN_MINUS)       || 
                    (current_token_type == TOKEN_ASTERISK) || (current_token_type == TOKEN_DIVIDE)      || 
                    (current_token_type == TOKEN_ASSIGNMENT))
                {
                  if (expression_stack == NULL)
                  {
                    if (current_token != NULL)
                    {
                      state = 11300;
                      expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                    }
                  }
                  else
                  {
                    if ((current_token_type == TOKEN_PLUS) || (current_token_type == TOKEN_MINUS)) 
                    {
                      state = 11300;
                      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_PLUS)     || 
                                (stack_token_type == TOKEN_MINUS)    ||
                                (stack_token_type == TOKEN_ASTERISK) || 
                                (stack_token_type == TOKEN_DIVIDE))
                            {
                              new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _set, cst_element->token_entry, NULL);
                              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))
                      {
                        state = 11300;
                        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_ASTERISK) || 
                                  (stack_token_type == TOKEN_DIVIDE))
                              {
                                new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _set, cst_element->token_entry, NULL);
                                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
                          {
                            expression_stack = push_expression_stack (expression_stack, current_token, current_token_type, NULL, NULL);
                            finished = TRUE;
                          }
                        }
                      }
                      else
                      {
                        if (current_token_type == TOKEN_ASSIGNMENT)
                        {
                          state = 11300;
                          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_PLUS)     || 
                                    (stack_token_type == TOKEN_MINUS)    || 
                                    (stack_token_type == TOKEN_ASTERISK) || 
                                    (stack_token_type == TOKEN_DIVIDE))
                                {
                                  new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _set, cst_element->token_entry, NULL);
                                  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;
                        }
                      }
                    }
                  }
                }
                else
                {
                  if (current_token_type == TOKEN_SEMICOLON)
                  {
                    state = 4000;
                    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);
                        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;
                  }
                }
              }
            }
          }
        break;



























// *******************************************************************************************************************************************
// * set <IDENTIFIER>                                                                                                                        *
// *                                                                                                                                         *
// * Note: <IDENTIFIER> is a Boolean datatype.                                                                                               *
// *                                                                                                                                         *
// * 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) ||
              (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, _if, cst_element->token_entry, symbol_table_element);
                  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);
                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)
                  {
                    new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL);
                    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_UNARY_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_UNARY_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);
                                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_UNARY_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);
                                  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_UNARY_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);
                                    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_UNARY_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);
                                      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_UNARY_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);
                                        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_UNARY_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);
                                          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_ASSIGNMENT)
                  {
                    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_GREATER_THAN)          || (stack_token_type == TOKEN_LESS_THAN)          || 
                              (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL) || (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || 
                              (stack_token_type == TOKEN_EQUAL)                 || (stack_token_type == TOKEN_NOT_EQUAL)          || 
                              (stack_token_type == TOKEN_AND)                   || (stack_token_type == TOKEN_OR)                 || 
                              (stack_token_type == TOKEN_UNARY_NOT)             || (stack_token_type == TOKEN_MODULO)             ||
                              (stack_token_type == TOKEN_PLUS)                  || (stack_token_type == TOKEN_MINUS)              || 
                              (stack_token_type == TOKEN_ASTERISK)              || (stack_token_type == TOKEN_DIVIDE))
                          {
                            new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL);
                            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;
                                finished = TRUE;
                              }
                              expression_stack = pop_expression_stack (expression_stack);
                            }
                            else
                            {
                              state = 99999;
                              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_SEMICOLON)
                    {
                      state = 4000;
                      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);
                          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;
                    }
                  }
                }
              }
            }
          }
        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 ( <BOOLEAN EXPRESSION> *
// *****************************
        case 12010:
          if ((current_token_type == TOKEN_IDENTIFIER_INTEGER_CONSTANT) || (current_token_type == TOKEN_IDENTIFIER))
          {
            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);
                  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);
                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);
                    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_UNARY_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 = 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_UNARY_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_UNARY_NOT)
                              {
                                new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL);
                                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_UNARY_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);
                                  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_UNARY_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);
                                    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_UNARY_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);
                                      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_UNARY_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);
                                        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_UNARY_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);
                                          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_ASSIGNMENT)
                  {
                    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_GREATER_THAN)          || (stack_token_type == TOKEN_LESS_THAN)          || 
                              (stack_token_type == TOKEN_GREATER_THAN_OR_EQUAL) || (stack_token_type == TOKEN_LESS_THAN_OR_EQUAL) || 
                              (stack_token_type == TOKEN_EQUAL)                 || (stack_token_type == TOKEN_NOT_EQUAL)          || 
                              (stack_token_type == TOKEN_AND)                   || (stack_token_type == TOKEN_OR)                 || 
                              (stack_token_type == TOKEN_UNARY_NOT)             || (stack_token_type == TOKEN_MODULO)             ||
                              (stack_token_type == TOKEN_PLUS)                  || (stack_token_type == TOKEN_MINUS)              || 
                              (stack_token_type == TOKEN_ASTERISK)              || (stack_token_type == TOKEN_DIVIDE))
                          {
                            new_ast_element = add_element_to_abstract_syntax_tree (stack_token, stack_token_type, _if, cst_element->token_entry, NULL);
                            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;
                                finished = TRUE;
                              }
                              expression_stack = pop_expression_stack (expression_stack);
                            }
                            else
                            {
                              state = 99999;
                              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++;
                      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, _if, cst_element->token_entry, NULL);
                          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);
                      }
                      new_ast_element = add_element_to_abstract_syntax_tree (current_token, current_token_type, _left_curly_brace, cst_element->token_entry, NULL);
                      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;
                      }
                    }
                    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);
            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;
        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;
}
