moids-size.c

     
   1  //! @file moids-size.c
   2  //! @author J. Marcel van der Veer
   3  
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2025 J. Marcel van der Veer [algol68g@xs4all.nl].
   8  
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Memory footprint (size) of a mode.
  25  
  26  #include "a68g.h"
  27  #include "a68g-mp.h"
  28  #include "a68g-parser.h"
  29  
  30  // Next are routines to calculate the size of a mode.
  31  
  32  //! @brief Max unitings to simplout.
  33  
  34  void max_unitings_to_simplout (NODE_T * p, int *max)
  35  {
  36    for (; p != NO_NODE; FORWARD (p)) {
  37      if (IS (p, UNITING) && MOID (p) == M_SIMPLOUT) {
  38        MOID_T *q = MOID (SUB (p));
  39        if (q != M_SIMPLOUT) {
  40          size_t size = moid_size (q);
  41          MAXIMISE (*max, size);
  42        }
  43      }
  44      max_unitings_to_simplout (SUB (p), max);
  45    }
  46  }
  47  
  48  //! @brief Get max simplout size.
  49  
  50  void get_max_simplout_size (NODE_T * p)
  51  {
  52    A68G (max_simplout_size) = A68G_REF_SIZE;       // For anonymous SKIP
  53    max_unitings_to_simplout (p, &A68G (max_simplout_size));
  54  }
  55  
  56  //! @brief Set moid sizes.
  57  
  58  void set_moid_sizes (MOID_T * z)
  59  {
  60    for (; z != NO_MOID; FORWARD (z)) {
  61      SIZE (z) = moid_size (z);
  62      DIGITS (z) = moid_digits (z);
  63    }
  64  // Next is guaranteed.
  65  #if (A68G_LEVEL >= 3)
  66    SIZE (M_LONG_REAL) = moid_size (M_LONG_REAL);
  67    DIGITS (M_LONG_REAL) = 0;
  68  #else
  69    SIZE (M_LONG_REAL) = moid_size (M_LONG_REAL);
  70    DIGITS (M_LONG_REAL) = moid_digits (M_LONG_REAL);
  71  #endif
  72    SIZE (M_LONG_LONG_REAL) = moid_size (M_LONG_LONG_REAL);
  73    DIGITS (M_LONG_LONG_REAL) = moid_digits (M_LONG_LONG_REAL);
  74    SIZE_COMPL (M_LONG_COMPLEX) = SIZE (M_LONG_REAL);
  75    SIZE_COMPL (M_REF_LONG_COMPLEX) = SIZE (M_LONG_REAL);
  76    DIGITS_COMPL (M_LONG_COMPLEX) = DIGITS (M_LONG_REAL);
  77    DIGITS_COMPL (M_REF_LONG_COMPLEX) = DIGITS (M_LONG_REAL);
  78    SIZE_COMPL (M_LONG_LONG_COMPLEX) = SIZE (M_LONG_LONG_REAL);
  79    SIZE_COMPL (M_REF_LONG_LONG_COMPLEX) = SIZE (M_LONG_LONG_REAL);
  80    DIGITS_COMPL (M_LONG_LONG_COMPLEX) = DIGITS (M_LONG_LONG_REAL);
  81    DIGITS_COMPL (M_REF_LONG_LONG_COMPLEX) = DIGITS (M_LONG_LONG_REAL);
  82  }
  83  
  84  //! @brief Moid size 2.
  85  
  86  size_t moid_size_2 (MOID_T * p)
  87  {
  88    if (p == NO_MOID) {
  89      return 0;
  90    } else if (EQUIVALENT (p) != NO_MOID) {
  91      return moid_size_2 (EQUIVALENT (p));
  92    } else if (p == M_HIP) {
  93      return 0;
  94    } else if (p == M_VOID) {
  95      return 0;
  96    } else if (p == M_INT) {
  97      return SIZE_ALIGNED (A68G_INT);
  98    } else if (p == M_LONG_LONG_INT) {
  99      return (int) size_long_mp ();
 100    } else if (p == M_REAL) {
 101      return SIZE_ALIGNED (A68G_REAL);
 102    } else if (p == M_LONG_INT) {
 103  #if (A68G_LEVEL >= 3)
 104      return SIZE_ALIGNED (A68G_LONG_INT);
 105  #else
 106      return size_mp ();
 107  #endif
 108    } else if (p == M_LONG_REAL) {
 109  #if (A68G_LEVEL >= 3)
 110      return SIZE_ALIGNED (A68G_LONG_REAL);
 111  #else
 112      return (int) size_mp ();
 113  #endif
 114    } else if (p == M_LONG_BITS) {
 115  #if (A68G_LEVEL >= 3)
 116      return SIZE_ALIGNED (A68G_LONG_BITS);
 117  #else
 118      return (int) size_mp ();
 119  #endif
 120    } else if (p == M_LONG_LONG_REAL) {
 121      return (int) size_long_mp ();
 122    } else if (p == M_BOOL) {
 123      return SIZE_ALIGNED (A68G_BOOL);
 124    } else if (p == M_CHAR) {
 125      return SIZE_ALIGNED (A68G_CHAR);
 126    } else if (p == M_ROW_CHAR) {
 127      return A68G_REF_SIZE;
 128    } else if (p == M_BITS) {
 129      return SIZE_ALIGNED (A68G_BITS);
 130    } else if (p == M_LONG_LONG_BITS) {
 131      return (int) size_long_mp ();
 132    } else if (p == M_BYTES) {
 133      return SIZE_ALIGNED (A68G_BYTES);
 134    } else if (p == M_LONG_BYTES) {
 135      return SIZE_ALIGNED (A68G_LONG_BYTES);
 136    } else if (p == M_FILE) {
 137      return SIZE_ALIGNED (A68G_FILE);
 138    } else if (p == M_CHANNEL) {
 139      return SIZE_ALIGNED (A68G_CHANNEL);
 140    } else if (p == M_FORMAT) {
 141      return SIZE_ALIGNED (A68G_FORMAT);
 142    } else if (p == M_SEMA) {
 143      return A68G_REF_SIZE;
 144    } else if (p == M_SOUND) {
 145      return SIZE_ALIGNED (A68G_SOUND);
 146    } else if (p == M_COLLITEM) {
 147      return SIZE_ALIGNED (A68G_COLLITEM);
 148    } else if (p == M_HEX_NUMBER) {
 149      int k = 0;
 150      MAXIMISE (k, SIZE_ALIGNED (A68G_BOOL));
 151      MAXIMISE (k, SIZE_ALIGNED (A68G_CHAR));
 152      MAXIMISE (k, SIZE_ALIGNED (A68G_INT));
 153      MAXIMISE (k, SIZE_ALIGNED (A68G_REAL));
 154      MAXIMISE (k, SIZE_ALIGNED (A68G_BITS));
 155  #if (A68G_LEVEL >= 3)
 156      MAXIMISE (k, SIZE_ALIGNED (A68G_LONG_INT));
 157      MAXIMISE (k, SIZE_ALIGNED (A68G_LONG_REAL));
 158      MAXIMISE (k, SIZE_ALIGNED (A68G_LONG_BITS));
 159  #endif
 160      return SIZE_ALIGNED (A68G_UNION) + k;
 161    } else if (p == M_NUMBER) {
 162      int k = 0;
 163      MAXIMISE (k, A68G_REF_SIZE);
 164      MAXIMISE (k, SIZE_ALIGNED (A68G_INT));
 165      MAXIMISE (k, SIZE_ALIGNED (A68G_REAL));
 166      MAXIMISE (k, size_mp ());
 167      MAXIMISE (k, size_long_mp ());
 168  #if (A68G_LEVEL >= 3)
 169      MAXIMISE (k, SIZE_ALIGNED (A68G_LONG_INT));
 170      MAXIMISE (k, SIZE_ALIGNED (A68G_LONG_REAL));
 171  #endif
 172      return SIZE_ALIGNED (A68G_UNION) + k;
 173    } else if (p == M_SIMPLIN) {
 174      int k = 0;
 175      MAXIMISE (k, A68G_REF_SIZE);
 176      MAXIMISE (k, SIZE_ALIGNED (A68G_FORMAT));
 177      MAXIMISE (k, SIZE_ALIGNED (A68G_PROCEDURE));
 178      MAXIMISE (k, SIZE_ALIGNED (A68G_SOUND));
 179      return SIZE_ALIGNED (A68G_UNION) + k;
 180    } else if (p == M_SIMPLOUT) {
 181      return SIZE_ALIGNED (A68G_UNION) + A68G (max_simplout_size);
 182    } else if (IS_REF (p)) {
 183      return A68G_REF_SIZE;
 184    } else if (IS (p, PROC_SYMBOL)) {
 185      return SIZE_ALIGNED (A68G_PROCEDURE);
 186    } else if (IS_ROW (p) && p != M_ROWS) {
 187      return A68G_REF_SIZE;
 188    } else if (p == M_ROWS) {
 189      return SIZE_ALIGNED (A68G_UNION) + A68G_REF_SIZE;
 190    } else if (IS_FLEX (p)) {
 191      return moid_size (SUB (p));
 192    } else if (IS_STRUCT (p)) {
 193      size_t size = 0;
 194      for (PACK_T *z = PACK (p); z != NO_PACK; FORWARD (z)) {
 195        size += moid_size (MOID (z));
 196      }
 197      return size;
 198    } else if (IS_UNION (p)) {
 199      size_t size = 0;
 200      for (PACK_T *z = PACK (p); z != NO_PACK; FORWARD (z)) {
 201        if (moid_size (MOID (z)) > size) {
 202          size = moid_size (MOID (z));
 203        }
 204      }
 205      return SIZE_ALIGNED (A68G_UNION) + size;
 206    } else if (PACK (p) != NO_PACK) {
 207      size_t size = 0;
 208      for (PACK_T *z = PACK (p); z != NO_PACK; FORWARD (z)) {
 209        size += moid_size (MOID (z));
 210      }
 211      return size;
 212    } else {
 213  // ?
 214      return 0;
 215    }
 216  }
 217  
 218  //! @brief Moid digits 2.
 219  
 220  int moid_digits_2 (MOID_T * p)
 221  {
 222    if (p == NO_MOID) {
 223      return 0;
 224    }
 225    if (EQUIVALENT (p) != NO_MOID) {
 226      return moid_digits_2 (EQUIVALENT (p));
 227    }
 228    if (p == M_LONG_INT) {
 229  #if (A68G_LEVEL >= 3)
 230      return 0;
 231  #else
 232      return (int) mp_digits ();
 233  #endif
 234    }
 235    if (p == M_LONG_LONG_INT) {
 236      return (int) long_mp_digits ();
 237    }
 238    if (p == M_LONG_REAL) {
 239      return (int) mp_digits ();
 240    }
 241    if (p == M_LONG_LONG_REAL) {
 242      return (int) long_mp_digits ();
 243    }
 244    if (p == M_LONG_BITS) {
 245  #if (A68G_LEVEL >= 3)
 246      return 0;
 247  #else
 248      return (int) mp_digits ();
 249  #endif
 250    }
 251    if (p == M_LONG_LONG_BITS) {
 252      return (int) long_mp_digits ();
 253    } else {
 254      return 0;
 255    }
 256  }
 257  
 258  //! @brief Moid size.
 259  
 260  size_t moid_size (MOID_T * p)
 261  {
 262    SIZE (p) = A68G_ALIGN (moid_size_2 (p));
 263    return SIZE (p);
 264  }
 265  
 266  //! @brief Moid digits.
 267  
 268  int moid_digits (MOID_T * p)
 269  {
 270    DIGITS (p) = moid_digits_2 (p);
 271    return DIGITS (p);
 272  }
     


© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)