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-2024 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          int 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    A68 (max_simplout_size) = A68_REF_SIZE;       // For anonymous SKIP
  53    max_unitings_to_simplout (p, &A68 (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 (A68_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  int 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 (A68_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 (A68_REAL);
 102    } else if (p == M_LONG_INT) {
 103  #if (A68_LEVEL >= 3)
 104      return SIZE_ALIGNED (A68_LONG_INT);
 105  #else
 106      return (int) size_mp ();
 107  #endif
 108    } else if (p == M_LONG_REAL) {
 109  #if (A68_LEVEL >= 3)
 110      return SIZE_ALIGNED (A68_LONG_REAL);
 111  #else
 112      return (int) size_mp ();
 113  #endif
 114    } else if (p == M_LONG_BITS) {
 115  #if (A68_LEVEL >= 3)
 116      return SIZE_ALIGNED (A68_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 (A68_BOOL);
 124    } else if (p == M_CHAR) {
 125      return SIZE_ALIGNED (A68_CHAR);
 126    } else if (p == M_ROW_CHAR) {
 127      return A68_REF_SIZE;
 128    } else if (p == M_BITS) {
 129      return SIZE_ALIGNED (A68_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 (A68_BYTES);
 134    } else if (p == M_LONG_BYTES) {
 135      return SIZE_ALIGNED (A68_LONG_BYTES);
 136    } else if (p == M_FILE) {
 137      return SIZE_ALIGNED (A68_FILE);
 138    } else if (p == M_CHANNEL) {
 139      return SIZE_ALIGNED (A68_CHANNEL);
 140    } else if (p == M_FORMAT) {
 141      return SIZE_ALIGNED (A68_FORMAT);
 142    } else if (p == M_SEMA) {
 143      return A68_REF_SIZE;
 144    } else if (p == M_SOUND) {
 145      return SIZE_ALIGNED (A68_SOUND);
 146    } else if (p == M_COLLITEM) {
 147      return SIZE_ALIGNED (A68_COLLITEM);
 148    } else if (p == M_HEX_NUMBER) {
 149      int k = 0;
 150      MAXIMISE (k, SIZE_ALIGNED (A68_BOOL));
 151      MAXIMISE (k, SIZE_ALIGNED (A68_CHAR));
 152      MAXIMISE (k, SIZE_ALIGNED (A68_INT));
 153      MAXIMISE (k, SIZE_ALIGNED (A68_REAL));
 154      MAXIMISE (k, SIZE_ALIGNED (A68_BITS));
 155  #if (A68_LEVEL >= 3)
 156      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_INT));
 157      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_REAL));
 158      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_BITS));
 159  #endif
 160      return SIZE_ALIGNED (A68_UNION) + k;
 161    } else if (p == M_NUMBER) {
 162      int k = 0;
 163      MAXIMISE (k, A68_REF_SIZE);
 164      MAXIMISE (k, SIZE_ALIGNED (A68_INT));
 165      MAXIMISE (k, SIZE_ALIGNED (A68_REAL));
 166      MAXIMISE (k, (int) size_long_mp ());
 167  #if (A68_LEVEL >= 3)
 168      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_INT));
 169      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_REAL));
 170  #else
 171      MAXIMISE (k, (int) size_mp ());
 172  #endif
 173      return SIZE_ALIGNED (A68_UNION) + k;
 174    } else if (p == M_SIMPLIN) {
 175      int k = 0;
 176      MAXIMISE (k, A68_REF_SIZE);
 177      MAXIMISE (k, SIZE_ALIGNED (A68_FORMAT));
 178      MAXIMISE (k, SIZE_ALIGNED (A68_PROCEDURE));
 179      MAXIMISE (k, SIZE_ALIGNED (A68_SOUND));
 180      return SIZE_ALIGNED (A68_UNION) + k;
 181    } else if (p == M_SIMPLOUT) {
 182      return SIZE_ALIGNED (A68_UNION) + A68 (max_simplout_size);
 183    } else if (IS_REF (p)) {
 184      return A68_REF_SIZE;
 185    } else if (IS (p, PROC_SYMBOL)) {
 186      return SIZE_ALIGNED (A68_PROCEDURE);
 187    } else if (IS_ROW (p) && p != M_ROWS) {
 188      return A68_REF_SIZE;
 189    } else if (p == M_ROWS) {
 190      return SIZE_ALIGNED (A68_UNION) + A68_REF_SIZE;
 191    } else if (IS_FLEX (p)) {
 192      return moid_size (SUB (p));
 193    } else if (IS_STRUCT (p)) {
 194      int size = 0;
 195      for (PACK_T *z = PACK (p); z != NO_PACK; FORWARD (z)) {
 196        size += moid_size (MOID (z));
 197      }
 198      return size;
 199    } else if (IS_UNION (p)) {
 200      int size = 0;
 201      for (PACK_T *z = PACK (p); z != NO_PACK; FORWARD (z)) {
 202        if (moid_size (MOID (z)) > size) {
 203          size = moid_size (MOID (z));
 204        }
 205      }
 206      return SIZE_ALIGNED (A68_UNION) + size;
 207    } else if (PACK (p) != NO_PACK) {
 208      int size = 0;
 209      for (PACK_T *z = PACK (p); z != NO_PACK; FORWARD (z)) {
 210        size += moid_size (MOID (z));
 211      }
 212      return size;
 213    } else {
 214  // ?
 215      return 0;
 216    }
 217  }
 218  
 219  //! @brief Moid digits 2.
 220  
 221  int moid_digits_2 (MOID_T * p)
 222  {
 223    if (p == NO_MOID) {
 224      return 0;
 225    }
 226    if (EQUIVALENT (p) != NO_MOID) {
 227      return moid_digits_2 (EQUIVALENT (p));
 228    }
 229    if (p == M_LONG_INT) {
 230  #if (A68_LEVEL >= 3)
 231      return 0;
 232  #else
 233      return (int) mp_digits ();
 234  #endif
 235    }
 236    if (p == M_LONG_LONG_INT) {
 237      return (int) long_mp_digits ();
 238    }
 239    if (p == M_LONG_REAL) {
 240      return (int) mp_digits ();
 241    }
 242    if (p == M_LONG_LONG_REAL) {
 243      return (int) long_mp_digits ();
 244    }
 245    if (p == M_LONG_BITS) {
 246  #if (A68_LEVEL >= 3)
 247      return 0;
 248  #else
 249      return (int) mp_digits ();
 250  #endif
 251    }
 252    if (p == M_LONG_LONG_BITS) {
 253      return (int) long_mp_digits ();
 254    } else {
 255      return 0;
 256    }
 257  }
 258  
 259  //! @brief Moid size.
 260  
 261  int moid_size (MOID_T * p)
 262  {
 263    SIZE (p) = A68_ALIGN (moid_size_2 (p));
 264    return SIZE (p);
 265  }
 266  
 267  //! @brief Moid digits.
 268  
 269  int moid_digits (MOID_T * p)
 270  {
 271    DIGITS (p) = moid_digits_2 (p);
 272    return DIGITS (p);
 273  }