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


#include "libchaga-constants.h"




typedef enum chaga_operand_type
{
  _nothing,
  _int,
  _bool,
  _float,
  _constant_int,
  _constant_float,
  _constant_bool
} chaga_operand_type;




typedef enum chaga_operator_type
{
  _none,
  _greater_than_or_equal,
  _greater_than,
  _less_than_or_equal,
  _less_than,
  _equal,
  _not_equal,
  _and,
  _or,
  _xor,
  _not,
  _plus,
  _minus,
  _times,
  _divide,
  _modulo
} chaga_operator_type;




enum occupied_nibble
{
  lo, hi
}; 




enum string_number_sign
{
  negative, zero, positive, undefined
}; 



typedef struct psnc  // psnc: packed string number component (base-10)
{
  unsigned char          packed_number_block[MAX_PACKED_NUMBER_BLOCK_SIZE];
  long long int          highest_digit_position;
  enum occupied_nibble   highest_nibble_position;   // does the highest digit occupy the low or high nibble?
  struct psnc            *first_number_block;
  struct psnc            *last_number_block;
  struct psnc            *previous_number_block;
  struct psnc            *next_number_block; 
} psnc;



// *****************************************************************************************************************
// * IDEA: future versions of psint will store the left of decimal without trailing zeros followed by an exponent. *
// * Example: 100000 would be stored as 1 * 10^5 (left_of_decimal = 1 and exponent = 5)                            *
// *****************************************************************************************************************
typedef struct psint // psint: packed string integer (base-10)
{
  enum string_number_sign  sign;
  unsigned int             status_flag;
  psnc                     *left_of_decimal;
  long long int            scale; // this read/write attribute describes the number of digits right of the decimal to be retained.
} psint;  




typedef struct psflt // psflt: packed string float (base-10)
{
  enum string_number_sign  sign;
  unsigned int             status_flag;
  psnc                     *left_of_decimal;
  psnc                     *right_of_decimal;
  long long int            scale; // this read/write attribute describes the number of digits right of the decimal to be retained.
} psflt;  




typedef struct psimgy // psimgy: packed string imaginary (base-10)
{
  enum string_number_sign  sign;
  unsigned int             status_flag;
  psnc                     *left_of_decimal;
  psnc                     *right_of_decimal;
} psimgy;




typedef struct pscplx // pscplx: packed string complex (base-10)
{
  enum string_number_sign  sign;
  unsigned int             status_flag;
  psflt                    *float_component;
  psimgy                   *imaginary_component;
} pscplx;  



typedef struct psint_list_node
{
  psint                    *element;
  struct psint_list_node   *next_element;
} psint_list_node;




typedef struct digit_stack_node
{
  unsigned char            digit[MAX_DIGIT_STACK_BLOCK_SIZE];
  long long int            stack_top_position;
  enum occupied_nibble     stack_top_nibble_orientation; 
  struct digit_stack_node *next;
} digit_stack_node;




typedef struct digit_queue_node
{
  unsigned char digit;
  struct digit_queue_node *next;
} digit_queue_node;




typedef struct psflt_stack_node
{
  psflt                   *packed_string_float;
  struct psflt_stack_node *next;
} psflt_stack_node;




typedef struct runtime_expression_node
{
  chaga_operator_type              operator;
  chaga_operand_type               operand_type; 
  void                             *operand;
  unsigned char                    ok_to_free_memory_for_operand;
  struct runtime_expression_node   *next;
} runtime_expression_node;








