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

token_node * tokenize_input_file (char *file_buffer, size_t file_buffer_size)
{
  token_node *token_list, *last_token_element, *new_token_element, *token_element;
  string_node *string_list, *string_element;
  size_t i, token_string_length, j;
  int state, ok_to_advance_to_next_byte, found_newline, token_is_boolean_true, token_is_boolean_false;
  char byte;
  unsigned long long line_number;
  unsigned char temporary_token_string[6];

  token_list = NULL;
  string_list = NULL;
  last_token_element = NULL;
  if (file_buffer != NULL)
  {
    state = 0;
    i = 0;
    line_number = 1;
    found_newline = FALSE;
    if (i < file_buffer_size)
    {
      if (file_buffer[i] == '\n')
      { 
        found_newline = TRUE;
      }
    }
    while ((i < file_buffer_size) && (found_newline == TRUE))
    {
      found_newline = FALSE;
      if (file_buffer[i] == '\n')
      {
        found_newline = TRUE;
        i++;
        line_number++;
      }
    }
    while ((i < file_buffer_size) && (state < 9999))
    {
      byte = file_buffer[i];
      //if ((byte > 31) && (byte < 127))
      //{
      //  printf ("state = %4d, byte = %02x (%c), line_number = %lld\n", state, byte, byte, line_number);
      //}
      //else
      //{
      //  printf ("state = %4d, byte = 0x%02x, line_number = %lld\n", state, byte, line_number);
      //}
      switch (state)
      {
        case 0:
          if (((byte >= 'A') && (byte <= 'Z')) || ((byte >= 'a') && (byte <= 'z')) || (byte == '_'))
          {
            string_list = delete_string (string_list);
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 2000;
          }
          else         
          {
            if ((byte >= '0') && (byte <= '9'))
            {
              string_list = delete_string (string_list);
              string_list = append_to_string (string_list, byte);
              ok_to_advance_to_next_byte = TRUE;
              state = 2100;
            }
            else
            {
              if (byte == '[')
              {
                string_list = delete_string (string_list);
                string_list = append_to_string (string_list, byte);
                new_token_element = add_token_element (string_list, TOKEN_LEFT_BRACKET, line_number);
                if (new_token_element != NULL)
                {
                  ok_to_advance_to_next_byte = TRUE;
                  state = 0;
                  if (last_token_element != NULL)
                  {
                    last_token_element->next = new_token_element;
                    last_token_element = last_token_element->next;
                  }
                  else
                  {
                    token_list = new_token_element;
                    last_token_element = new_token_element;
                  }
                }
                else
                {
                  state = 9999;
                }
              }
              else
              {
                if (byte == ']')
                {
                  string_list = delete_string (string_list);
                  string_list = append_to_string (string_list, byte);
                  new_token_element = add_token_element (string_list, TOKEN_RIGHT_BRACKET, line_number);
                  if (new_token_element != NULL)
                  {
                    ok_to_advance_to_next_byte = TRUE;
                    state = 0;
                    if (last_token_element != NULL)
                    {
                      last_token_element->next = new_token_element;
                      last_token_element = last_token_element->next;
                    }
                    else
                    {
                      token_list = new_token_element;
                      last_token_element = new_token_element;
                    }
                  }
                  else
                  {
                    state = 9999;
                  }
                }
                else
                {
                  if (byte == '+')
                  {
                    string_list = delete_string (string_list);
                    string_list = append_to_string (string_list, byte);
// **************************************************************************************************
// * Now determine if the plus is a UNARY-OPERATOR or an OPERATOR. If the pls is a UNARY-OPERATOR,  *
// * I attach it to whatever token follows the plus sign (i.e. presuming an INTEGER or IDENTIFIER). *
// **************************************************************************************************
                    if (last_token_element != NULL)
                    {
                      if ((last_token_element->token_type == TOKEN_PLUS)     ||
                          (last_token_element->token_type == TOKEN_MINUS)    ||
                          (last_token_element->token_type == TOKEN_ASTERISK) ||
                          (last_token_element->token_type == TOKEN_DIVIDE)   ||
                          (last_token_element->token_type == TOKEN_MODULO)   ||
                          (last_token_element->token_type == TOKEN_CARET))
                      {
// *******************************************
// * It looks like the plus is a UNARY-PLUS. *
// *******************************************
                        ok_to_advance_to_next_byte = TRUE;
                        state = 105;
                      }
                      else
                      {
                        new_token_element = add_token_element (string_list, TOKEN_PLUS, line_number);
                        if (new_token_element != NULL)
                        {
                          ok_to_advance_to_next_byte = TRUE;
                          state = 0;
                          if (last_token_element != NULL)
                          {
                            last_token_element->next = new_token_element;
                            last_token_element = last_token_element->next;
                          }
                          else
                          {
                            token_list = new_token_element;
                            last_token_element = new_token_element;
                          }
                        }
                        else
                        { 
                          state = 9999;
                        }
                      }
                    }
                    else
                    {
// *********************************************************
// * Since no token precedes the plus, it is a UNARY-PLUS. *
// *********************************************************
                      ok_to_advance_to_next_byte = TRUE;
                      state = 105;
                    }
                  }
                  else
                  {
                    if (byte == '-')
                    {
                      string_list = delete_string (string_list);
                      string_list = append_to_string (string_list, byte);
// ****************************************************************************************************
// * Now determine if the minus is a UNARY-OPERATOR or an OPERATOR. If the minus is a UNARY-OPERATOR, *
// * I attach it to whatever token follows the minus sign (i.e. presuming an INTEGER or IDENTIFIER).  *
// ****************************************************************************************************
                      if (last_token_element != NULL)
                      {
                        if ((last_token_element->token_type == TOKEN_PLUS)     ||
                            (last_token_element->token_type == TOKEN_MINUS)    ||
                            (last_token_element->token_type == TOKEN_ASTERISK) ||
                            (last_token_element->token_type == TOKEN_DIVIDE)   ||
                            (last_token_element->token_type == TOKEN_MODULO)   ||
                            (last_token_element->token_type == TOKEN_CARET))
                        {
// *********************************************
// * It looks like the minus is a UNARY-MINUS. *
// *********************************************
                          ok_to_advance_to_next_byte = TRUE;
                          state = 100;
                        }
                        else
                        {
                          new_token_element = add_token_element (string_list, TOKEN_MINUS, line_number);
                          if (new_token_element != NULL)
                          {
                            ok_to_advance_to_next_byte = TRUE;
                            state = 0;
                            if (last_token_element != NULL)
                            {
                              last_token_element->next = new_token_element;
                              last_token_element = last_token_element->next;
                            }
                            else
                            {
                              token_list = new_token_element;
                              last_token_element = new_token_element;
                            }
                          }
                          else
                          { 
                            state = 9999;
                          }
                        }
                      }
                      else
                      {
// ***********************************************************
// * Since no token precedes the minus, it is a UNARY-MINUS. *
// ***********************************************************
                        ok_to_advance_to_next_byte = TRUE;
                        state = 100;
                      }
                    }
                    else
                    {
                      if (byte == '\'')
                      {
                        string_list = delete_string (string_list);
                        string_list = append_to_string (string_list, byte);
                        new_token_element = add_token_element (string_list, TOKEN_SINGLE_QUOTE, line_number);
                        if (new_token_element != NULL)
                        {
                          ok_to_advance_to_next_byte = TRUE;
                          state = 110;
                          if (last_token_element != NULL)
                          {
                            last_token_element->next = new_token_element;
                            last_token_element = last_token_element->next;
                          }
                          else
                          {
                            token_list = new_token_element;
                            last_token_element = new_token_element;
                          }
                        }
                        else
                        { 
                          state = 9999;
                        }
                      }
                      else
                      {
                        if (byte == '"')
                        {
                          string_list = delete_string (string_list);
                          string_list = append_to_string (string_list, byte);
                          new_token_element = add_token_element (string_list, TOKEN_DOUBLE_QUOTE, line_number);
                          if (new_token_element != NULL)
                          {
                            ok_to_advance_to_next_byte = TRUE;
                            state = 130;
                            if (last_token_element != NULL)
                            {
                              last_token_element->next = new_token_element;
                              last_token_element = last_token_element->next;
                            }
                            else
                            {
                              token_list = new_token_element;
                              last_token_element = new_token_element;
                            }
                          }
                          else
                          { 
                            state = 9999;
                          }
                        }
                        else
                        {
                          if (byte == ',')
                          {
                            string_list = delete_string (string_list);
                            string_list = append_to_string (string_list, byte);
                            new_token_element = add_token_element (string_list, TOKEN_COMMA, line_number);
                            if (new_token_element != NULL)
                            {
                              ok_to_advance_to_next_byte = TRUE;
                              state = 0;
                              if (last_token_element != NULL)
                              {
                                last_token_element->next = new_token_element;
                                last_token_element = last_token_element->next;
                              }
                              else
                              {
                                token_list = new_token_element;
                                last_token_element = new_token_element;
                              }
                            }
                            else
                            {
                              state = 9999;
                            }
                          }
                          else
                          {
                            if (byte == '*')
                            {
                              string_list = delete_string (string_list);
                              string_list = append_to_string (string_list, byte);
                              new_token_element = add_token_element (string_list, TOKEN_ASTERISK, line_number);
                              if (new_token_element != NULL)
                              {
                                ok_to_advance_to_next_byte = TRUE;
                                state = 0;
                                if (last_token_element != NULL)
                                {
                                  last_token_element->next = new_token_element;
                                  last_token_element = last_token_element->next;
                                }
                                else
                                {
                                  token_list = new_token_element;
                                  last_token_element = new_token_element;
                                }
                              }
                              else
                              { 
                                state = 9999;
                              }
                            }
                            else
                            {
                              if (byte == '/')
                              {
                                string_list = delete_string (string_list);
                                string_list = append_to_string (string_list, byte);
                                new_token_element = add_token_element (string_list, TOKEN_DIVIDE, line_number);
                                if (new_token_element != NULL)
                                {
                                  ok_to_advance_to_next_byte = TRUE;
                                  state = 0;
                                  if (last_token_element != NULL)
                                  {
                                    last_token_element->next = new_token_element;
                                    last_token_element = last_token_element->next;
                                  }
                                  else
                                  {
                                    token_list = new_token_element;
                                    last_token_element = new_token_element;
                                  }
                                }
                                else
                                { 
                                  state = 9999;
                                }
                              }
                              else
                              {
                                if (byte == '%')
                                {
                                  string_list = delete_string (string_list);
                                  string_list = append_to_string (string_list, byte);
                                  new_token_element = add_token_element (string_list, TOKEN_MODULO, line_number);
                                  if (new_token_element != NULL)
                                  {
                                    ok_to_advance_to_next_byte = TRUE;
                                    state = 0;
                                    if (last_token_element != NULL)
                                    {
                                      last_token_element->next = new_token_element;
                                      last_token_element = last_token_element->next;
                                    }
                                    else
                                    {
                                      token_list = new_token_element;
                                      last_token_element = new_token_element;
                                    }
                                  }
                                  else
                                  { 
                                    state = 9999;
                                  }
                                }
                                else
                                {
                                  if (byte == '<')
                                  {
                                    string_list = delete_string (string_list);
                                    string_list = append_to_string (string_list, byte);
                                    ok_to_advance_to_next_byte = TRUE;
                                    state = 500;
                                  }
                                  else
                                  {
                                    if (byte == '>')
                                    {
                                      string_list = delete_string (string_list);
                                      string_list = append_to_string (string_list, byte);
                                      ok_to_advance_to_next_byte = TRUE;
                                      state = 600;
                                    }
                                    else
                                    {
                                      if (byte == '=')
                                      {
                                        string_list = delete_string (string_list);
                                        string_list = append_to_string (string_list, byte);
                                        ok_to_advance_to_next_byte = TRUE;
                                        state = 700;
                                      }
                                      else
                                      {
                                        if (byte == '!')
                                        {
                                          string_list = delete_string (string_list);
                                          string_list = append_to_string (string_list, byte);
                                          ok_to_advance_to_next_byte = TRUE;
                                          state = 800;
                                        }
                                        else
                                        {
                                          if (byte == '|')
                                          {
                                            string_list = delete_string (string_list);
                                            string_list = append_to_string (string_list, byte);
                                            ok_to_advance_to_next_byte = TRUE;
                                            state = 900;
                                          }
                                          else
                                          {
                                            if (byte == '&')
                                            {
                                              string_list = delete_string (string_list);
                                              string_list = append_to_string (string_list, byte);
                                              ok_to_advance_to_next_byte = TRUE;
                                              state = 1000;
                                            }
                                            else
                                            {
                                              if (byte == '(')
                                              {
                                                string_list = delete_string (string_list);
                                                string_list = append_to_string (string_list, byte);
                                                new_token_element = add_token_element (string_list, TOKEN_LEFT_PARENTHESIS, line_number);
                                                if (new_token_element != NULL)
                                                {
                                                  ok_to_advance_to_next_byte = TRUE;
                                                  state = 0;
                                                  if (last_token_element != NULL)
                                                  {
                                                    last_token_element->next = new_token_element;
                                                    last_token_element = last_token_element->next;
                                                  }
                                                  else
                                                  {
                                                    token_list = new_token_element;
                                                    last_token_element = new_token_element;
                                                  }
                                                }
                                                else
                                                { 
                                                  state = 9999;
                                                }
                                              }
                                              else
                                              {
                                                if (byte == ')')
                                                {
                                                  string_list = delete_string (string_list);
                                                  string_list = append_to_string (string_list, byte);
                                                  new_token_element = add_token_element (string_list, TOKEN_RIGHT_PARENTHESIS, line_number);
                                                  if (new_token_element != NULL)
                                                  {
                                                    ok_to_advance_to_next_byte = TRUE;
                                                    state = 0;
                                                    if (last_token_element != NULL)
                                                    {
                                                      last_token_element->next = new_token_element;
                                                      last_token_element = last_token_element->next;
                                                    }
                                                    else
                                                    {
                                                      token_list = new_token_element;
                                                      last_token_element = new_token_element;
                                                    }
                                                  }
                                                  else
                                                  { 
                                                    state = 9999;
                                                  }
                                                }
                                                else
                                                {
                                                  if (byte == '{')
                                                  {
                                                    string_list = delete_string (string_list);
                                                    string_list = append_to_string (string_list, byte);
                                                    new_token_element = add_token_element (string_list, TOKEN_LEFT_CURLY_BRACE, line_number);
                                                    if (new_token_element != NULL)
                                                    {
                                                      ok_to_advance_to_next_byte = TRUE;
                                                      state = 0;
                                                      if (last_token_element != NULL)
                                                      {
                                                        last_token_element->next = new_token_element;
                                                        last_token_element = last_token_element->next;
                                                      }
                                                      else
                                                      {
                                                        token_list = new_token_element;
                                                        last_token_element = new_token_element;
                                                      }
                                                    }
                                                    else
                                                    { 
                                                      state = 9999;
                                                    }
                                                  }
                                                  else
                                                  {
                                                    if (byte == '}')
                                                    {
                                                      string_list = delete_string (string_list);
                                                      string_list = append_to_string (string_list, byte);
                                                      new_token_element = add_token_element (string_list, TOKEN_RIGHT_CURLY_BRACE, line_number);
                                                      if (new_token_element != NULL)
                                                      {
                                                        ok_to_advance_to_next_byte = TRUE;
                                                        state = 0;
                                                        if (last_token_element != NULL)
                                                        {
                                                          last_token_element->next = new_token_element;
                                                          last_token_element = last_token_element->next;
                                                        }
                                                        else
                                                        {
                                                          token_list = new_token_element;
                                                          last_token_element = new_token_element;
                                                        }
                                                      }
                                                      else
                                                      { 
                                                        state = 9999;
                                                      }
                                                    }
                                                    else
                                                    {
                                                      if (byte == ';')
                                                      {
                                                        string_list = delete_string (string_list);
                                                        string_list = append_to_string (string_list, byte);
                                                        new_token_element = add_token_element (string_list, TOKEN_SEMICOLON, line_number);
                                                        if (new_token_element != NULL)
                                                        {
                                                          ok_to_advance_to_next_byte = TRUE;
                                                          state = 0;
                                                          if (last_token_element != NULL)
                                                          {
                                                            last_token_element->next = new_token_element;
                                                            last_token_element = last_token_element->next;
                                                          }
                                                          else
                                                          {
                                                            token_list = new_token_element;
                                                            last_token_element = new_token_element;
                                                          }
                                                        }
                                                        else
                                                        { 
                                                          state = 9999;
                                                        }
                                                      }
                                                      else
                                                      {
                                                        if (byte == ':')
                                                        {
                                                          string_list = delete_string (string_list);
                                                          string_list = append_to_string (string_list, byte);
                                                          new_token_element = add_token_element (string_list, TOKEN_COLON, line_number);
                                                          if (new_token_element != NULL)
                                                          {
                                                            ok_to_advance_to_next_byte = TRUE;
                                                            state = 0;
                                                            if (last_token_element != NULL)
                                                            {
                                                              last_token_element->next = new_token_element;
                                                              last_token_element = last_token_element->next;
                                                            }
                                                            else
                                                            {
                                                              token_list = new_token_element;
                                                              last_token_element = new_token_element;
                                                            }
                                                          }
                                                          else
                                                          { 
                                                            state = 9999;
                                                          }
                                                        }
                                                        else
                                                        {
                                                          if (byte == '.')
                                                          {
                                                            string_list = delete_string (string_list);
                                                            string_list = append_to_string (string_list, byte);
                                                            new_token_element = add_token_element (string_list, TOKEN_PERIOD, line_number);
                                                            if (new_token_element != NULL)
                                                            {
                                                              ok_to_advance_to_next_byte = TRUE;
                                                              state = 0;
                                                              if (last_token_element != NULL)
                                                              {
                                                                last_token_element->next = new_token_element;
                                                                last_token_element = last_token_element->next;
                                                              }
                                                              else
                                                              {
                                                                token_list = new_token_element;
                                                                last_token_element = new_token_element;
                                                              }
                                                            }
                                                            else
                                                            { 
                                                              state = 9999;
                                                            }
                                                          }
                                                          else
                                                          {
                                                            if ((byte == ' ') || (byte == '\t') || (byte == '\r') || (byte == '\n'))
                                                            {
                                                              if (byte == '\n')
                                                              {
                                                                line_number++;
                                                              }
                                                              ok_to_advance_to_next_byte = TRUE;
                                                              state = 0;
                                                            }
                                                            else
                                                            {
                                                              printf ("Syntax error on line %llu.\n", last_token_element->line_number);
                                                              state = 9999;
                                                            }
                                                          }
                                                        }
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                            }
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        break;
        case 100:
          if ((byte >= '0') && (byte <= '9'))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 2100;
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_MINUS, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          } 
        break;
        case 105:
          if ((byte >= '0') && (byte <= '9'))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 2100;
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_PLUS, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          } 
        break;
        case 110:
          if (byte == '\'')
          {
            new_token_element = add_token_element (string_list, TOKEN_STRING, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;           
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          } 
          else
          {
            if (byte == '"')
            {
              new_token_element = add_token_element (string_list, TOKEN_STRING, line_number);
              if (new_token_element != NULL)
              {
                ok_to_advance_to_next_byte = TRUE;
                state = 0;
                if (last_token_element != NULL)
                {
                  last_token_element->next = new_token_element;
                  last_token_element = last_token_element->next;
                }
                else
                {
                  token_list = new_token_element;
                  last_token_element = new_token_element;
                }
              }
              else
              { 
                state = 9999;
              }
            }
            else
            {
              string_list = delete_string (string_list);
// *****************************************************************************************************************
// TODO: What if the user enters \000 or \xFF. Both of those are valid cases too! Must add them as tokens as well. *  
// *****************************************************************************************************************
              if (byte == '\n')
              {
                string_list = append_to_string (string_list, '\\'); // replace all line-feeds with "\n". This makes strings one contiguous line in assembler output.
                string_list = append_to_string (string_list, 'n');
                line_number++;
              }
              else
              {  
                string_list = append_to_string (string_list, byte);
              }
              ok_to_advance_to_next_byte = TRUE;
              if (byte == '\\')
              {
                state = 115;
              }
              else
              {
                state = 120;
              }
            }
          }
        break;
        case 115:
          if ((byte == '\\') || (byte == 'a') || (byte == 'b') || (byte == 't') || (byte == 'n') || (byte == 'v') || (byte == 'f') || (byte == 'r') || (byte == '\'') || ((byte >= '0') && (byte <= '9')))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 120;
          }
          else
          {
            state = 9999;
          }
        break;
        case 120:
          if (byte == '\'')
          {
            new_token_element = add_token_element (string_list, TOKEN_STRING, line_number);
            if (new_token_element != NULL)
            {
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
            string_list = delete_string (string_list);
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_SINGLE_QUOTE, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          } 
          else
          {
            if (byte == '\n')
            {
              string_list = append_to_string (string_list, '\\'); // replace all line-feeds with "\n". This makes strings one contiguous line in assembler output.
              string_list = append_to_string (string_list, 'n');
              line_number++;
            }
            else
            {
              string_list = append_to_string (string_list, byte);
            }
            ok_to_advance_to_next_byte = TRUE;
            if (byte == '\\')
            {
              state = 115; 
            }
            else
            {
              state = 120;
            }
          }
        break;
        case 130:
          if (byte == '"')
          {
            new_token_element = add_token_element (string_list, TOKEN_DOUBLE_QUOTE, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          } 
          else
          {
            string_list = delete_string (string_list);
            if (byte == '\n')
            {
              string_list = append_to_string (string_list, '\\'); // replace all line-feeds with "\n". This makes strings one contiguous line in assembler output.
              string_list = append_to_string (string_list, 'n');
              line_number++;
            }
            else
            {  
              string_list = append_to_string (string_list, byte);
            }
            ok_to_advance_to_next_byte = TRUE;
            if (byte == '\\')
            {
              state = 135;
            }
            else
            {
              state = 140;
            }
          }
        break;
        case 135:
          if ((byte == '\\') || (byte == 'a') || (byte == 'b') || (byte == 't') || (byte == 'n') || (byte == 'v') || (byte == 'f') || (byte == 'r') || (byte == '"') || ((byte >= '0') && (byte <= '9')))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 140;
          }
          else
          {
            state = 9999;
          }
        break;
        case 140:
          if (byte == '"')
          {
            new_token_element = add_token_element (string_list, TOKEN_STRING, line_number);
            if (new_token_element != NULL)
            {
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
            string_list = delete_string (string_list);
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_DOUBLE_QUOTE, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          } 
          else
          {
            if (byte == '\n')
            {
              string_list = append_to_string (string_list, '\\'); // replace all line-feeds with "\n". This makes strings one contiguous line in assembler output.
              string_list = append_to_string (string_list, 'n');
              line_number++;
            }
            else
            {
              string_list = append_to_string (string_list, byte);
            }
            ok_to_advance_to_next_byte = TRUE;
            if (byte == '\\')
            {
              state = 135; 
            }
            else
            {
              state = 140;
            }
          }
        break;
        case 500:
          if (byte == '=')
          {
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_LESS_THAN_OR_EQUAL, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_LESS_THAN, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
        break;
        case 600:
          if (byte == '=')
          {
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_GREATER_THAN_OR_EQUAL, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_GREATER_THAN, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
        break;
        case 700:
          if (byte == '=')
          {
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_EQUAL, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_ASSIGNMENT, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
        break;
        case 800:
          if (byte == '=')
          {
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_NOT_EQUAL, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_UNARY_NOT, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
        break;
        case 900:
          if (byte == '|')
          {
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_OR, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            state = 9999;
          }
        break;
        case 1000:
          if (byte == '&')
          {
            string_list = append_to_string (string_list, byte);
            new_token_element = add_token_element (string_list, TOKEN_AND, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            new_token_element = add_token_element (string_list, TOKEN_AMPERSAND, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = FALSE;
              state = 0; 
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
        break;
// ***********************
// * Process identifiers *
// ***********************
        case 2000:
          if (((byte >= 'A') && (byte <= 'Z')) || ((byte >= 'a') && (byte <= 'z')) || ((byte >= '0') && (byte <= '9')) || (byte == '_'))
          {
            string_list = append_to_string (string_list, byte);
            state = 2000;
          }
          else
          {
// ****************************************************************************************************************
// * Before marking the token-string as an IDENTIFIER, make a temporary copy of the token-string. During the copy *
// * process, convert each byte in the copy to upper-case. This makes it easy to determine if the token-string is *
// * a BOOLEAN constant of "TRUE" or "FALSE" without having to deal with case sensitivity.                        *
// ****************************************************************************************************************
            token_is_boolean_true = FALSE;
            token_is_boolean_false = FALSE;
            token_string_length = 0;
            string_element = string_list;
            while (string_element != NULL)
            {
              token_string_length++;
              string_element = string_element->next;
            }
            if (token_string_length == 4)  // TRUE is four characters in length
            {
              string_element = string_list;
              if ((string_element->byte == 't') || (string_element->byte == 'T'))
              {
                string_element = string_element->next;
                if ((string_element->byte == 'r') || (string_element->byte == 'R'))
                {
                  string_element = string_element->next;
                  if ((string_element->byte == 'u') || (string_element->byte == 'U'))
                  {
                    string_element = string_element->next;
                    if ((string_element->byte == 'e') || (string_element->byte == 'E'))
                    {
                      token_is_boolean_true = TRUE;
// ***********************************************************************************************************************
// * Now normalize the input token to ALL UPPER CASE regardless of whether the user entered "True", "true", "TrUe", etc. *
// ***********************************************************************************************************************
                      string_element = string_list;
                      string_element->byte ='T';
                      string_element = string_element->next;
                      string_element->byte ='R';
                      string_element = string_element->next;
                      string_element->byte ='U';
                      string_element = string_element->next;
                      string_element->byte ='E';
                    }
                  }
                }
              }
            }
            else
            {
              if (token_string_length == 5) // FALSE is five characters in length
              {
                string_element = string_list;
                if ((string_element->byte == 'f') || (string_element->byte == 'F'))
                {
                  string_element=string_element->next;
                  if ((string_element->byte == 'a') || (string_element->byte == 'A'))
                  {
                    string_element=string_element->next;
                    if ((string_element->byte == 'l') || (string_element->byte == 'L'))
                    {
                      string_element=string_element->next;
                      if ((string_element->byte == 's') || (string_element->byte == 'S'))
                      {
                        string_element=string_element->next;
                        if ((string_element->byte == 'e') || (string_element->byte == 'E'))
                        {
                          token_is_boolean_false = TRUE;
// **************************************************************************************************************************
// * Now normalize the input token to ALL UPPER CASE regardless of whether the user entered "False", "false", "FaLsE", etc. *
// **************************************************************************************************************************
                          string_element = string_list;
                          string_element->byte ='F';
                          string_element = string_element->next;
                          string_element->byte ='A';
                          string_element = string_element->next;
                          string_element->byte ='L';
                          string_element = string_element->next;
                          string_element->byte ='S';
                          string_element = string_element->next;
                          string_element->byte ='E';
                        }
                      }
                    }
                  }
                }
              }
            }
            if (token_is_boolean_true == TRUE)
            {
              new_token_element = add_token_element (string_list, TOKEN_TRUE, line_number);
              if (new_token_element != NULL)
              {
                ok_to_advance_to_next_byte = FALSE;
                state = 0;
                if (last_token_element != NULL)
                {
                  last_token_element->next = new_token_element;
                  last_token_element = last_token_element->next;
                }
                else
                {
                  token_list = new_token_element;
                  last_token_element = new_token_element;
                }
              }
              else
              { 
                state = 9999;
              }
            }
            else
            {
              if (token_is_boolean_false == TRUE)
              {
                new_token_element = add_token_element (string_list, TOKEN_FALSE, line_number);
                if (new_token_element != NULL)
                {
                  ok_to_advance_to_next_byte = FALSE;
                  state = 0;
                  if (last_token_element != NULL)
                  {
                    last_token_element->next = new_token_element;
                    last_token_element = last_token_element->next;
                  }
                  else
                  {
                    token_list = new_token_element;
                    last_token_element = new_token_element;
                  }
                }
                else
                { 
                  state = 9999;
                }
              }
              else
              { 
                new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER, line_number);
                if (new_token_element != NULL)
                {
                  ok_to_advance_to_next_byte = FALSE;
                  state = 0;
                  if (last_token_element != NULL)
                  {
                    last_token_element->next = new_token_element;
                    last_token_element = last_token_element->next;
                  }
                  else
                  {
                    token_list = new_token_element;
                    last_token_element = new_token_element;
                  }
                }
                else
                { 
                  state = 9999;
                }
              }
            }
          }
        break;
// *******************
// * Process numbers *
// *******************
        case 2100:
          if ((byte >= '0') && (byte <= '9'))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 2100;
          }
          else
          {
            if (byte == '.')
            {
              string_list = append_to_string (string_list, byte);
              ok_to_advance_to_next_byte = TRUE;
              state = 2200;
            }
            else
            {
              if ((byte == 'f') || (byte == 'F') || (byte == 'l') || (byte == 'L'))
              {
                string_list = append_to_string (string_list, byte);
                ok_to_advance_to_next_byte = TRUE;
                state = 2300;
              }
              else
              {
                if ((byte == 'e') || (byte == 'E'))
                {
                  string_list = append_to_string (string_list, byte);
                  ok_to_advance_to_next_byte = TRUE;
                  state = 2400;
                }
                else
                {
                  new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_INTEGER_CONSTANT, line_number);
                  if (new_token_element != NULL)
                  {
                    ok_to_advance_to_next_byte = FALSE;
                    state = 0;
                    if (last_token_element != NULL)
                    {
                      last_token_element->next = new_token_element;
                      last_token_element = last_token_element->next;
                    }
                    else
                    {
                      token_list = new_token_element;
                      last_token_element = new_token_element;
                    }
                  }
                  else
                  { 
                    state = 9999;
                  }
                }
              }
            }
          }
        break;
        case 2200:
          if ((byte >= '0') && (byte <= '9'))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE;
            state = 2200;
          }
          else
          {
            if ((byte == ' ') || (byte == '\t'))
            {
              new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
              if (new_token_element != NULL)
              {
                ok_to_advance_to_next_byte = FALSE;
                state = 0;
                if (last_token_element != NULL)
                {
                  last_token_element->next = new_token_element;
                  last_token_element = last_token_element->next;
                }
                else
                {
                  token_list = new_token_element;
                  last_token_element = new_token_element;
                }
              }
              else
              { 
                state = 9999;
              }
            }
            else
            {
              if ((byte == 'f') || (byte == 'F') || (byte == 'l') || (byte == 'L'))
              {
                string_list = append_to_string (string_list, byte);
                new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                if (new_token_element != NULL)
                {
                  ok_to_advance_to_next_byte = TRUE;
                  state = 0;
                  if (last_token_element != NULL)
                  {
                    last_token_element->next = new_token_element;
                    last_token_element = last_token_element->next;
                  }
                  else
                  {
                    token_list = new_token_element;
                    last_token_element = new_token_element;
                  }
                }
                else
                { 
                  state = 9999;
                }
              }
              else
              {
                if ((byte == 'e') || (byte == 'E'))
                {
                  string_list = append_to_string (string_list, byte);
                  ok_to_advance_to_next_byte = TRUE;
                  state = 2400;
                }
                else
                {
                  new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                  if (new_token_element != NULL)
                  {
                    ok_to_advance_to_next_byte = FALSE;
                    state = 0;
                    if (last_token_element != NULL)
                    {
                      last_token_element->next = new_token_element;
                      last_token_element = last_token_element->next;
                    }
                    else
                    {
                      token_list = new_token_element;
                      last_token_element = new_token_element;
                    }
                  }
                  else
                  { 
                    state = 9999;
                  }
                }
              }
            }
          }
        break;
        case 2300:
          if ((byte == ' ') || (byte == '\t'))
          {
            new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
            if (new_token_element != NULL)
            {
              ok_to_advance_to_next_byte = TRUE;
              state = 0;
              if (last_token_element != NULL)
              {
                last_token_element->next = new_token_element;
                last_token_element = last_token_element->next;
              }
              else
              {
                token_list = new_token_element;
                last_token_element = new_token_element;
              }
            }
            else
            { 
              state = 9999;
            }
          }
          else
          {
            if (byte == '=') 
            {
              new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
              if (new_token_element != NULL)
              {
                ok_to_advance_to_next_byte = FALSE;
                state = 0;
                if (last_token_element != NULL)
                {
                  last_token_element->next = new_token_element;
                  last_token_element = last_token_element->next;
                }
                else
                {
                  token_list = new_token_element;
                  last_token_element = new_token_element;
                }
              }
              else
              { 
                state = 9999;
              }
            }
            else
            {
              if (byte == '<')
              {
                new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                if (new_token_element != NULL)
                {
                  ok_to_advance_to_next_byte = FALSE;
                  state = 0;
                  if (last_token_element != NULL)
                  {
                    last_token_element->next = new_token_element;
                    last_token_element = last_token_element->next;
                  }
                  else
                  {
                    token_list = new_token_element;
                    last_token_element = new_token_element;
                  }
                }
                else
                { 
                  state = 9999;
                }
              }
              else
              {
                state = 9999;
              }
            }
          }
        break;
        case 2400:
          if ((byte >= '0') && (byte <= '9'))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE; 
            state = 2500;
          }
          else
          {
            if ((byte == ' ') || (byte == '\t'))
            {
              new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
              if (new_token_element != NULL)
              {
                ok_to_advance_to_next_byte = TRUE;
                state = 0;
                if (last_token_element != NULL)
                {
                  last_token_element->next = new_token_element;
                  last_token_element = last_token_element->next;
                }
                else
                {
                  token_list = new_token_element;
                  last_token_element = new_token_element;
                }
              }
              else
              { 
                state = 9999;
              }
            }
            else
            {
              if ((byte == 'f') || (byte == 'F') || (byte == 'l') || (byte == 'L'))
              {
                string_list = append_to_string (string_list, byte);
                ok_to_advance_to_next_byte = TRUE; 
                state = 2300;
              }
              else
              {
                if ((byte == '+') || (byte == '-'))
                {
                  string_list = append_to_string (string_list, byte);
                  ok_to_advance_to_next_byte = TRUE; 
                  state = 2500;
                }
                else
                {
                  if (byte == '=') 
                  {
                    new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                    if (new_token_element != NULL)
                    {
                      ok_to_advance_to_next_byte = FALSE; 
                      state = 0;
                      if (last_token_element != NULL)
                      {
                        last_token_element->next = new_token_element;
                        last_token_element = last_token_element->next;
                      }
                      else
                      {
                        token_list = new_token_element;
                        last_token_element = new_token_element;
                      }
                    }
                    else
                    { 
                      state = 9999;
                    }
                  }
                  else
                  {
                    if (byte == '<')
                    {
                      new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                      if (new_token_element != NULL)
                      {
                        ok_to_advance_to_next_byte = FALSE; 
                        state = 0;
                        if (last_token_element != NULL)
                        {
                          last_token_element->next = new_token_element;
                          last_token_element = last_token_element->next;
                        }
                        else
                        {
                          token_list = new_token_element;
                          last_token_element = new_token_element;
                        }
                      }
                      else
                      { 
                        state = 9999;
                      }
                    }
                    else
                    {
                      if (byte == '>')
                      {
                        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                        if (new_token_element != NULL)
                        {
                          ok_to_advance_to_next_byte = FALSE; 
                          state = 0;
                          if (last_token_element != NULL)
                          {
                            last_token_element->next = new_token_element;
                            last_token_element = last_token_element->next;
                          }
                          else
                          {
                            token_list = new_token_element;
                            last_token_element = new_token_element;
                          }
                        }
                        else
                        { 
                          state = 9999;
                        }
                      }
                      else
                      {
                        state = 9999;
                      }
                    }
                  }
                }
              }
            }
          }
        break;
        case 2500:
          if ((byte >= '0') && (byte <= '9'))
          {
            string_list = append_to_string (string_list, byte);
            ok_to_advance_to_next_byte = TRUE; 
            state = 2500;
          }
          else
          {
            if ((byte == ' ') || (byte == '\t'))
            {
              new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
              if (new_token_element != NULL)
              {
                ok_to_advance_to_next_byte = TRUE; 
                state = 0;
                if (last_token_element != NULL)
                {
                  last_token_element->next = new_token_element;
                  last_token_element = last_token_element->next;
                }
                else
                {
                  token_list = new_token_element;
                  last_token_element = new_token_element;
                }
              }
              else
              { 
                state = 9999;
              }
            }
            else
            {
              if ((byte == 'f') || (byte == 'F') || (byte == 'l') || (byte == 'L'))
              {
                string_list = append_to_string (string_list, byte);
                ok_to_advance_to_next_byte = TRUE; 
                state = 2300;
              }
              else
              {
                if (byte == '=') 
                {
                  new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                  if (new_token_element != NULL)
                  {    
                    ok_to_advance_to_next_byte = FALSE; 
                    state = 0;
                    if (last_token_element != NULL)
                    {
                      last_token_element->next = new_token_element;
                      last_token_element = last_token_element->next;
                    }
                    else
                    {
                      token_list = new_token_element;
                      last_token_element = new_token_element;
                    }
                  }
                  else
                  { 
                    state = 9999;
                  }
                }
                else
                {
                  if (byte == '<')
                  {
                    new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                    if (new_token_element != NULL)
                    {
                      ok_to_advance_to_next_byte = FALSE; 
                      state = 0;
                      if (last_token_element != NULL)
                      {
                        last_token_element->next = new_token_element;
                        last_token_element = last_token_element->next;
                      }
                      else
                      {
                        token_list = new_token_element;
                        last_token_element = new_token_element;
                      }
                    }
                    else
                    { 
                      state = 9999;
                    }
                  }
                  else
                  {
                    if (byte == '>')
                    {
                      new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                      if (new_token_element != NULL)
                      {
                        ok_to_advance_to_next_byte = FALSE; 
                        state = 0;
                        if (last_token_element != NULL)
                        {
                          last_token_element->next = new_token_element;
                          last_token_element = last_token_element->next;
                        }
                        else
                        {
                          token_list = new_token_element;
                          last_token_element = new_token_element;
                        }
                      }
                      else
                      { 
                        state = 9999;
                      }
                    }
                    else
                    {
                      if (byte == '!')
                      {
                        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                        if (new_token_element != NULL)
                        {
                          ok_to_advance_to_next_byte = FALSE; 
                          state = 0;
                          if (last_token_element != NULL)
                          {
                            last_token_element->next = new_token_element;
                            last_token_element = last_token_element->next;
                          }
                          else
                          {
                            token_list = new_token_element;
                            last_token_element = new_token_element;
                          }
                        }
                        else
                        { 
                          state = 9999;
                        }
                      }
                      else
                      {
                        if (byte == ';')
                        {
                          new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
                          if (new_token_element != NULL)
                          {
                            ok_to_advance_to_next_byte = FALSE; 
                            state = 0;
                            if (last_token_element != NULL)
                            {
                              last_token_element->next = new_token_element;
                              last_token_element = last_token_element->next;
                            }
                            else
                            {
                              token_list = new_token_element;
                              last_token_element = new_token_element;
                            }
                          }
                          else
                          { 
                            state = 9999;
                          }
                        }
                        else
                        {
                          state = 9999;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        break;
        default:
        break;
      }
      if (ok_to_advance_to_next_byte)
      {
        i++;
      }
    }
    switch (state)
    {
      case 2000:
        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER, line_number);
        if (new_token_element != NULL)
        {
          if (last_token_element != NULL)
          {
            last_token_element->next = new_token_element;
            last_token_element = last_token_element->next;
          }
          else
          {
            token_list = new_token_element;
            last_token_element = new_token_element;
          }
        }
        else
        { 
          state = 9999;
        }
      break;
      case 2100:
        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_INTEGER_CONSTANT, line_number);
        if (new_token_element != NULL)
        {
          if (last_token_element != NULL)
          {
            last_token_element->next = new_token_element;
            last_token_element = last_token_element->next;
          }
          else
          {
            token_list = new_token_element;
            last_token_element = new_token_element;
          }
        }
        else
        { 
          state = 9999;
        }
      break;
      case 2200:
        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
        if (new_token_element != NULL)
        {
          if (last_token_element != NULL)
          {
            last_token_element->next = new_token_element;
            last_token_element = last_token_element->next;
          }
          else
          {
            token_list = new_token_element;
            last_token_element = new_token_element;
          }
        }
        else
        { 
          state = 9999;
        }
      break; 
      case 2300:
        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
        if (new_token_element != NULL)
        {
          if (last_token_element != NULL)
          {
            last_token_element->next = new_token_element;
            last_token_element = last_token_element->next;
          }
          else
          {
            token_list = new_token_element;
            last_token_element = new_token_element;
          }
        }
        else
        { 
          state = 9999;
        }
      break;
      case 2500:
        new_token_element = add_token_element (string_list, TOKEN_IDENTIFIER_FLOATING_POINT_CONSTANT, line_number);
        if (new_token_element != NULL)
        {
          if (last_token_element != NULL)
          {
            last_token_element->next = new_token_element;
            last_token_element = last_token_element->next;
          }
          else
          {
            token_list = new_token_element;
            last_token_element = new_token_element;
          }
        }
        else
        { 
          state = 9999;
        }
      break; 
      default:
      break;
    }
  }
  if ((state == 140) || (state == 120))
  {
    state = 9999;
    if (last_token_element != NULL)
    {
      printf ("Syntax error on line %llu: unterminated string quote.\n", last_token_element->line_number);
    }
  }
  if (state == 9999)
  {
    while (token_list != NULL)
    {
      token_element = token_list;
      token_list = token_list->next;
      if (token_element->token != NULL)
      {
        free (token_element->token);
      }
      free (token_element);
      token_element = NULL;
    }
  }
  return token_list;
}
